Fabiano Fidêncio f3d06df
From 68b14b6f94cf23fe2f66ee592e2e1fa5abfe3b9c Mon Sep 17 00:00:00 2001
Fabiano Fidêncio f3d06df
From: Jakub Hrozek <jhrozek@redhat.com>
Fabiano Fidêncio f3d06df
Date: Fri, 23 Mar 2018 13:40:34 +0100
Fabiano Fidêncio f3d06df
Subject: [PATCH] SYSDB: When marking an entry as expired, also set the
Fabiano Fidêncio f3d06df
 originalModifyTimestamp to 1
Fabiano Fidêncio f3d06df
MIME-Version: 1.0
Fabiano Fidêncio f3d06df
Content-Type: text/plain; charset=UTF-8
Fabiano Fidêncio f3d06df
Content-Transfer-Encoding: 8bit
Fabiano Fidêncio f3d06df
Fabiano Fidêncio f3d06df
Resolves:
Fabiano Fidêncio f3d06df
https://pagure.io/SSSD/sssd/issue/3684
Fabiano Fidêncio f3d06df
Fabiano Fidêncio f3d06df
If the cleanup task removes a user who was a fully resolved member (not a
Fabiano Fidêncio f3d06df
ghost), but then the group the user was a member of is requested, unless
Fabiano Fidêncio f3d06df
the group had changed, the user doesn't appear as a member of the group
Fabiano Fidêncio f3d06df
again. This is because the modify timestamp would prevent the group from
Fabiano Fidêncio f3d06df
updating and therefore the ghost attribute is not readded.
Fabiano Fidêncio f3d06df
Fabiano Fidêncio f3d06df
To mitigate this, let's also set the originalModifyTimestamp attribute
Fabiano Fidêncio f3d06df
to 1, so that we never take the optimized path while updating the group.
Fabiano Fidêncio f3d06df
Fabiano Fidêncio f3d06df
Reviewed-by: Fabiano FidĂȘncio <fidencio@redhat.com>
Fabiano Fidêncio f3d06df
(cherry picked from commit 250751bf8b0532d6175e762b7f2f008cc1c39a78)
Fabiano Fidêncio f3d06df
---
Fabiano Fidêncio f3d06df
 src/db/sysdb_ops.c          | 13 +++++++++++
Fabiano Fidêncio f3d06df
 src/tests/intg/test_ldap.py | 54 +++++++++++++++++++++++++++++++++++++++++++++
Fabiano Fidêncio f3d06df
 2 files changed, 67 insertions(+)
Fabiano Fidêncio f3d06df
Fabiano Fidêncio f3d06df
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
Fabiano Fidêncio f3d06df
index cc86a114e..09aa04a29 100644
Fabiano Fidêncio f3d06df
--- a/src/db/sysdb_ops.c
Fabiano Fidêncio f3d06df
+++ b/src/db/sysdb_ops.c
Fabiano Fidêncio f3d06df
@@ -5410,6 +5410,19 @@ errno_t sysdb_mark_entry_as_expired_ldb_dn(struct sss_domain_info *dom,
Fabiano Fidêncio f3d06df
         goto done;
Fabiano Fidêncio f3d06df
     }
Fabiano Fidêncio f3d06df
 
Fabiano Fidêncio f3d06df
+    ret = ldb_msg_add_empty(msg, SYSDB_ORIG_MODSTAMP,
Fabiano Fidêncio f3d06df
+                            LDB_FLAG_MOD_REPLACE, NULL);
Fabiano Fidêncio f3d06df
+    if (ret != LDB_SUCCESS) {
Fabiano Fidêncio f3d06df
+        ret = sysdb_error_to_errno(ret);
Fabiano Fidêncio f3d06df
+        goto done;
Fabiano Fidêncio f3d06df
+    }
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
+    ret = ldb_msg_add_string(msg, SYSDB_ORIG_MODSTAMP, "1");
Fabiano Fidêncio f3d06df
+    if (ret != LDB_SUCCESS) {
Fabiano Fidêncio f3d06df
+        ret = sysdb_error_to_errno(ret);
Fabiano Fidêncio f3d06df
+        goto done;
Fabiano Fidêncio f3d06df
+    }
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
     ret = ldb_modify(dom->sysdb->ldb, msg);
Fabiano Fidêncio f3d06df
     if (ret != LDB_SUCCESS) {
Fabiano Fidêncio f3d06df
         ret = sysdb_error_to_errno(ret);
Fabiano Fidêncio f3d06df
diff --git a/src/tests/intg/test_ldap.py b/src/tests/intg/test_ldap.py
Fabiano Fidêncio f3d06df
index a6659b1b7..db3253858 100644
Fabiano Fidêncio f3d06df
--- a/src/tests/intg/test_ldap.py
Fabiano Fidêncio f3d06df
+++ b/src/tests/intg/test_ldap.py
Fabiano Fidêncio f3d06df
@@ -434,6 +434,60 @@ def test_refresh_after_cleanup_task(ldap_conn, refresh_after_cleanup_task):
Fabiano Fidêncio f3d06df
         dict(mem=ent.contains_only("user1")))
Fabiano Fidêncio f3d06df
 
Fabiano Fidêncio f3d06df
 
Fabiano Fidêncio f3d06df
+@pytest.fixture
Fabiano Fidêncio f3d06df
+def update_ts_after_cleanup_task(request, ldap_conn):
Fabiano Fidêncio f3d06df
+    ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn)
Fabiano Fidêncio f3d06df
+    ent_list.add_user("user1", 1001, 2001)
Fabiano Fidêncio f3d06df
+    ent_list.add_user("user2", 1002, 2001)
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
+    ent_list.add_group_bis("group1", 2001, ["user1", "user2"])
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
+    create_ldap_fixture(request, ldap_conn, ent_list)
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
+    conf = \
Fabiano Fidêncio f3d06df
+        format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) + \
Fabiano Fidêncio f3d06df
+        unindent("""
Fabiano Fidêncio f3d06df
+            [domain/LDAP]
Fabiano Fidêncio f3d06df
+            ldap_purge_cache_timeout = 3
Fabiano Fidêncio f3d06df
+        """).format(**locals())
Fabiano Fidêncio f3d06df
+    create_conf_fixture(request, conf)
Fabiano Fidêncio f3d06df
+    create_sssd_fixture(request)
Fabiano Fidêncio f3d06df
+    return None
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
+def test_update_ts_cache_after_cleanup_task(ldap_conn,
Fabiano Fidêncio f3d06df
+                                            update_ts_after_cleanup_task):
Fabiano Fidêncio f3d06df
+    """
Fabiano Fidêncio f3d06df
+    Regression test for ticket:
Fabiano Fidêncio f3d06df
+    https://fedorahosted.org/sssd/ticket/2676
Fabiano Fidêncio f3d06df
+    """
Fabiano Fidêncio f3d06df
+    ent.assert_group_by_name(
Fabiano Fidêncio f3d06df
+        "group1",
Fabiano Fidêncio f3d06df
+        dict(mem=ent.contains_only("user1", "user2")))
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
+    ent.assert_passwd_by_name(
Fabiano Fidêncio f3d06df
+        'user1',
Fabiano Fidêncio f3d06df
+        dict(name='user1', passwd='*', uid=1001, gid=2001,
Fabiano Fidêncio f3d06df
+             gecos='1001', shell='/bin/bash'))
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
+    ent.assert_passwd_by_name(
Fabiano Fidêncio f3d06df
+        'user2',
Fabiano Fidêncio f3d06df
+        dict(name='user2', passwd='*', uid=1002, gid=2001,
Fabiano Fidêncio f3d06df
+             gecos='1002', shell='/bin/bash'))
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
+    if subprocess.call(["sss_cache", "-u", "user1"]) != 0:
Fabiano Fidêncio f3d06df
+        raise Exception("sssd_cache failed")
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
+    # The cleanup task runs every 3 seconds, so sleep for 6
Fabiano Fidêncio f3d06df
+    # so that we know the cleanup task ran at least once
Fabiano Fidêncio f3d06df
+    # even if we start sleeping during the first one
Fabiano Fidêncio f3d06df
+    time.sleep(6)
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
+    ent.assert_group_by_name(
Fabiano Fidêncio f3d06df
+        "group1",
Fabiano Fidêncio f3d06df
+        dict(mem=ent.contains_only("user1", "user2")))
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
+
Fabiano Fidêncio f3d06df
 @pytest.fixture
Fabiano Fidêncio f3d06df
 def blank_rfc2307(request, ldap_conn):
Fabiano Fidêncio f3d06df
     """Create blank RFC2307 directory fixture with interactive SSSD conf"""
Fabiano Fidêncio f3d06df
-- 
Fabiano Fidêncio f3d06df
2.14.3
Fabiano Fidêncio f3d06df