URL: https://github.com/SSSD/sssd/pull/13
Author: celestian
 Title: #13: MEMBEROF: Don't resolve members if they are removed
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/13/head:pr13
git checkout pr13
From 10b3a126e098a061212fcebde4f2506e6198d889 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20=C4=8Cech?= <pc...@redhat.com>
Date: Wed, 31 Aug 2016 12:28:48 +0200
Subject: [PATCH 1/3] MEMBEROF: Don't resolve members if they are removed

If we need remove ghost (SYSDB_GHOST, DB_GHOST) attribute
from group we use empty structure.

This doesn't mean that there is pointer to NULL but
it means that there is zero elements.
Ghost attribute is array not string.

Resolves:
https://fedorahosted.org/sssd/ticket/2940
---
 src/ldb_modules/memberof.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/ldb_modules/memberof.c b/src/ldb_modules/memberof.c
index af7147e..af42c72 100644
--- a/src/ldb_modules/memberof.c
+++ b/src/ldb_modules/memberof.c
@@ -2920,7 +2920,9 @@ static int memberof_mod(struct ldb_module *module, struct ldb_request *req)
     mod_ctx->ghel = ldb_msg_find_element(mod_ctx->msg, DB_GHOST);
 
     /* continue with normal ops if there are no members and no ghosts */
-    if (mod_ctx->membel == NULL && mod_ctx->ghel == NULL) {
+    if ((mod_ctx->membel == NULL && mod_ctx->ghel == NULL) ||
+        (mod_ctx->membel == NULL && mod_ctx->ghel != NULL &&
+         mod_ctx->ghel->num_values == 0)) {
         mod_ctx->terminate = true;
         return mbof_orig_mod(mod_ctx);
     }

From 2cccc16bf7c1556ee5c12a3f263a817f33674610 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20=C4=8Cech?= <pc...@redhat.com>
Date: Mon, 12 Sep 2016 15:18:07 +0200
Subject: [PATCH 2/3] LDAP: Removing of member link from group

Co-author: Sumit Bose

Resolves:
https://fedorahosted.org/sssd/ticket/2940
---
 src/providers/ldap/sdap_async_groups.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index 72760b7..08dfa01 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -878,6 +878,8 @@ static int sdap_save_grpmem(TALLOC_CTX *memctx,
     size_t nuserdns = 0;
     struct sss_domain_info *group_dom = NULL;
     int ret;
+    const char *remove_attrs[] = {SYSDB_MEMBER, SYSDB_ORIG_MEMBER, SYSDB_GHOST,
+                                  NULL};
 
     if (dom->ignore_group_members) {
         DEBUG(SSSDBG_CRIT_FAILURE,
@@ -962,6 +964,13 @@ static int sdap_save_grpmem(TALLOC_CTX *memctx,
     if (el->num_values == 0 && nuserdns == 0) {
         DEBUG(SSSDBG_TRACE_FUNC,
               "No members for group [%s]\n", group_name);
+
+        ret = sysdb_remove_attrs(group_dom, group_name, SYSDB_MEMBER_GROUP,
+                                 discard_const(remove_attrs));
+        if (ret != EOK) {
+            DEBUG(SSSDBG_OP_FAILURE, "sysdb_remove_attrs failed.\n");
+            goto fail;
+        }
     } else {
         DEBUG(SSSDBG_TRACE_FUNC,
               "Adding member users to group [%s]\n", group_name);

From ea685ea0bf71c3a350fb709d41b01068e948839a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20=C4=8Cech?= <pc...@redhat.com>
Date: Fri, 9 Sep 2016 06:28:01 +0200
Subject: [PATCH 3/3] TESTS: Adding intg. tests on nested groups

Resolves:
https://fedorahosted.org/sssd/ticket/2940
---
 src/tests/intg/test_ldap.py | 157 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 157 insertions(+)

diff --git a/src/tests/intg/test_ldap.py b/src/tests/intg/test_ldap.py
index 11792f5..7f0b8ff 100644
--- a/src/tests/intg/test_ldap.py
+++ b/src/tests/intg/test_ldap.py
@@ -794,3 +794,160 @@ def test_extra_attribute_already_exists(ldap_conn, extra_attributes):
                                   user, domain, extra_attribute)
 
     assert val == given_name
+
+
+@pytest.fixture
+def add_user_to_group(request, ldap_conn):
+    """
+    Adding user to group
+    """
+    ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn)
+    ent_list.add_user("user1", 1001, 2001)
+    ent_list.add_group_bis("group1", 20001, member_uids=["user1"])
+    create_ldap_fixture(request, ldap_conn, ent_list)
+    create_conf_fixture(request,
+                        format_rfc2307bis_deref_conf(
+                            ldap_conn,
+                            SCHEMA_RFC2307_BIS))
+    create_sssd_fixture(request)
+    return None
+
+
+def test_add_user_to_group(ldap_conn, add_user_to_group):
+    ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001, gid=2001))
+    ent.assert_group_by_name("group1", dict(mem=ent.contains_only("user1")))
+
+
+@pytest.fixture
+def remove_user_from_group(request, ldap_conn):
+    """
+    Adding user to group
+    """
+    ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn)
+    ent_list.add_user("user1", 1001, 2001)
+    ent_list.add_user("user2", 1002, 2002)
+    ent_list.add_group_bis("group1", 20001, member_uids=["user1", "user2"])
+    create_ldap_fixture(request, ldap_conn, ent_list)
+    create_conf_fixture(request,
+                        format_rfc2307bis_deref_conf(
+                            ldap_conn,
+                            SCHEMA_RFC2307_BIS))
+    create_sssd_fixture(request)
+    return None
+
+
+def test_remove_user_from_group(ldap_conn, remove_user_from_group):
+    """
+    Removing two users from group, step by step
+    """
+    group1_dn = 'cn=group1,ou=Groups,' + ldap_conn.ds_inst.base_dn
+
+    ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001, gid=2001))
+    ent.assert_passwd_by_name("user2", dict(name="user2", uid=1002, gid=2002))
+    ent.assert_group_by_name("group1",
+                             dict(mem=ent.contains_only("user1", "user2")))
+
+    # removing of user2 from group1
+    old = {'member': ["uid=user1,ou=Users,dc=example,dc=com",
+                      "uid=user2,ou=Users,dc=example,dc=com"]}
+    new = {'member': ["uid=user1,ou=Users,dc=example,dc=com"]}
+
+    ldif = ldap.modlist.modifyModlist(old, new)
+    ldap_conn.modify_s(group1_dn, ldif)
+
+    if subprocess.call(["sss_cache", "-GU"]) != 0:
+        raise Exception("sssd_cache failed")
+
+    ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001, gid=2001))
+    ent.assert_passwd_by_name("user2", dict(name="user2", uid=1002, gid=2002))
+    ent.assert_group_by_name("group1", dict(mem=ent.contains_only("user1")))
+
+    # removing of user1 from group1
+    old = {'member': ["uid=user1,ou=Users,dc=example,dc=com"]}
+    new = {'member': []}
+
+    ldif = ldap.modlist.modifyModlist(old, new)
+    ldap_conn.modify_s(group1_dn, ldif)
+
+    if subprocess.call(["sss_cache", "-GU"]) != 0:
+        raise Exception("sssd_cache failed")
+
+    ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001, gid=2001))
+    ent.assert_passwd_by_name("user2", dict(name="user2", uid=1002, gid=2002))
+    ent.assert_group_by_name("group1", dict(mem=ent.contains_only()))
+
+
+@pytest.fixture
+def remove_user_from_nested_group(request, ldap_conn):
+    ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn)
+    ent_list.add_user("user1", 1001, 2001)
+    ent_list.add_user("user2", 1002, 2002)
+    ent_list.add_group_bis("group1", 20001, member_uids=["user1"])
+    ent_list.add_group_bis("group2", 20002, member_uids=["user2"])
+    ent_list.add_group_bis("group3", 20003, member_gids=["group1", "group2"])
+    create_ldap_fixture(request, ldap_conn, ent_list)
+    create_conf_fixture(request,
+                        format_rfc2307bis_deref_conf(
+                            ldap_conn,
+                            SCHEMA_RFC2307_BIS))
+    create_sssd_fixture(request)
+    return None
+
+
+def test_remove_user_from_nested_group(ldap_conn,
+                                       remove_user_from_nested_group):
+
+    group3_dn = 'cn=group3,ou=Groups,' + ldap_conn.ds_inst.base_dn
+
+    ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001, gid=2001))
+    ent.assert_passwd_by_name("user2", dict(name="user2", uid=1002, gid=2002))
+
+    ent.assert_group_by_name("group1",
+                             dict(mem=ent.contains_only("user1")))
+    ent.assert_group_by_name("group2",
+                             dict(mem=ent.contains_only("user2")))
+
+    ent.assert_group_by_name("group3",
+                             dict(mem=ent.contains_only("user1",
+                                                        "user2")))
+
+    # removing of group2 from group3
+    old = {'member': ["cn=group1,ou=Groups,dc=example,dc=com",
+                      "cn=group2,ou=Groups,dc=example,dc=com"]}
+    new = {'member': ["cn=group1,ou=Groups,dc=example,dc=com"]}
+
+    ldif = ldap.modlist.modifyModlist(old, new)
+    ldap_conn.modify_s(group3_dn, ldif)
+
+    if subprocess.call(["sss_cache", "-GU"]) != 0:
+        raise Exception("sssd_cache failed")
+
+    ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001, gid=2001))
+    ent.assert_passwd_by_name("user2", dict(name="user2", uid=1002, gid=2002))
+
+    ent.assert_group_by_name("group1",
+                             dict(mem=ent.contains_only("user1")))
+    ent.assert_group_by_name("group2",
+                             dict(mem=ent.contains_only("user2")))
+    ent.assert_group_by_name("group3",
+                             dict(mem=ent.contains_only("user1")))
+
+    # removing of group1 from group3
+    old = {'member': ["cn=group1,ou=Groups,dc=example,dc=com"]}
+    new = {'member': []}
+
+    ldif = ldap.modlist.modifyModlist(old, new)
+    ldap_conn.modify_s(group3_dn, ldif)
+
+    if subprocess.call(["sss_cache", "-GU"]) != 0:
+        raise Exception("sssd_cache failed")
+
+    ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001, gid=2001))
+    ent.assert_passwd_by_name("user2", dict(name="user2", uid=1002, gid=2002))
+
+    ent.assert_group_by_name("group1",
+                             dict(mem=ent.contains_only("user1")))
+    ent.assert_group_by_name("group2",
+                             dict(mem=ent.contains_only("user2")))
+    ent.assert_group_by_name("group3",
+                             dict(mem=ent.contains_only()))
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org

Reply via email to