URL: https://github.com/SSSD/sssd/pull/5663
Author: ikerexxe
 Title: #5663: [WIP] cache_req: replace FQNs by shortnames
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/5663/head:pr5663
git checkout pr5663
From 2c83e6226790eac55460c58f7faeee33a67ddd6a Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedr...@redhat.com>
Date: Thu, 13 May 2021 12:24:09 +0200
Subject: [PATCH] cache_req: replace FQNs by shortnames

Replace FQNs by shortnames in cache_req_XYZ_by_name_send() when the FQN
already contains the domain name. This is done to avoid appending again
the domain name to the FQN.

Includes a unit test to check that the FQN to shortname replacement
works correctly.

It also includes an integration test to check that UpdateMemberList()
and GetAll() return the correct users that are members of a group. This
is done by first adding a member to a group and checking that it is
returned correctly. Then, the member is deleted and the interface returns
no members.

Resolves: https://github.com/SSSD/sssd/issues/4255
---
 src/responder/common/cache_req/cache_req.c  | 12 ++++-
 src/tests/cmocka/test_responder_cache_req.c | 24 +++++++++
 src/tests/intg/test_infopipe.py             | 54 +++++++++++++++++++++
 3 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c
index 3a575cf51a..04f42cfd33 100644
--- a/src/responder/common/cache_req/cache_req.c
+++ b/src/responder/common/cache_req/cache_req.c
@@ -1170,7 +1170,7 @@ static errno_t cache_req_process_input(TALLOC_CTX *mem_ctx,
         return cache_req_update_domains(mem_ctx, req, cr, domain);
     }
 
-    if (cr->plugin->parse_name == false || domain != NULL) {
+    if (cr->plugin->parse_name == false) {
         /* Call cache_req_update_domains() in order to get a up to date list
          * of domains and subdomains, if needed. Otherwise, just use the input
          * name as it is. */
@@ -1275,6 +1275,16 @@ static void cache_req_input_parsed(struct tevent_req *subreq)
     state = tevent_req_data(req, struct cache_req_state);
 
     ret = sss_parse_inp_recv(subreq, state, &name, &domain);
+
+    if (state->domain_name && domain && strcmp(state->domain_name, domain)){
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "Mismatch between input domain name [%s] and parsed domain name [%s]\n",
+              state->domain_name, domain);
+        tevent_req_error(req, EIO); //TODO: change error code?
+        DEBUG(SSSDBG_CRIT_FAILURE, "%s: return 1, ret %d\n", __FUNCTION__, ret); //TODO: delete
+        return;
+    }
+
     switch (ret) {
     case EOK:
         ret = cache_req_set_name(state->cr, name);
diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c
index 258bc78943..8a47e2e6b8 100644
--- a/src/tests/cmocka/test_responder_cache_req.c
+++ b/src/tests/cmocka/test_responder_cache_req.c
@@ -877,6 +877,9 @@ void test_user_by_name_cache_valid(void **state)
     /* Setup user. */
     prepare_user(test_ctx->tctx->dom, &users[0], 1000, time(NULL));
 
+    /* Mock values */
+    mock_parse_inp(users[0].short_name, NULL, ERR_OK);
+
     /* Test. */
     run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
     check_user(test_ctx, &users[0], test_ctx->tctx->dom);
@@ -891,6 +894,9 @@ void test_user_by_name_cache_expired(void **state)
     /* Setup user. */
     prepare_user(test_ctx->tctx->dom, &users[0], -1000, time(NULL));
 
+    /* Mock values */
+    mock_parse_inp(users[0].short_name, NULL, ERR_OK);
+
     /* Mock values. */
     /* DP should be contacted */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
@@ -914,6 +920,7 @@ void test_user_by_name_cache_midpoint(void **state)
     /* Mock values. */
     /* DP should be contacted without callback */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
+    mock_parse_inp(users[0].short_name, NULL, ERR_OK);
 
     /* Test. */
     run_user_by_name(test_ctx, test_ctx->tctx->dom, 50, ERR_OK);
@@ -939,6 +946,9 @@ void test_user_by_name_ncache(void **state)
     talloc_free(fqname);
     assert_int_equal(ret, EOK);
 
+    /* Mock values */
+    mock_parse_inp(users[0].short_name, NULL, ERR_OK);
+
     /* Test. */
     run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
     assert_false(test_ctx->dp_called);
@@ -953,6 +963,7 @@ void test_user_by_name_missing_found(void **state)
     /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
+    mock_parse_inp(users[0].short_name, NULL, ERR_OK);
 
     test_ctx->create_user1 = true;
     test_ctx->create_user2 = false;
@@ -972,6 +983,7 @@ void test_user_by_name_missing_notfound(void **state)
     /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
+    mock_parse_inp(users[0].short_name, NULL, ERR_OK);
 
     /* Test. */
     run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
@@ -1780,6 +1792,9 @@ void test_group_by_name_cache_valid(void **state)
     /* Setup group. */
     prepare_group(test_ctx->tctx->dom, &groups[0], 1000, time(NULL));
 
+    /* Mock values */
+    mock_parse_inp(groups[0].short_name, NULL, ERR_OK);
+
     /* Test. */
     run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
     check_group(test_ctx, &groups[0], test_ctx->tctx->dom);
@@ -1798,6 +1813,7 @@ void test_group_by_name_cache_expired(void **state)
     /* DP should be contacted */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
+    mock_parse_inp(groups[0].short_name, NULL, ERR_OK);
 
     /* Test. */
     run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK);
@@ -1817,6 +1833,7 @@ void test_group_by_name_cache_midpoint(void **state)
     /* Mock values. */
     /* DP should be contacted without callback */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
+    mock_parse_inp(groups[0].short_name, NULL, ERR_OK);
 
     /* Test. */
     run_group_by_name(test_ctx, test_ctx->tctx->dom, 50, ERR_OK);
@@ -1842,6 +1859,9 @@ void test_group_by_name_ncache(void **state)
     talloc_free(fqname);
     assert_int_equal(ret, EOK);
 
+    /* Mock values */
+    mock_parse_inp(groups[0].short_name, NULL, ERR_OK);
+
     /* Test. */
     run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
     assert_false(test_ctx->dp_called);
@@ -1856,6 +1876,7 @@ void test_group_by_name_missing_found(void **state)
     /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
+    mock_parse_inp(groups[0].short_name, NULL, ERR_OK);
 
     test_ctx->create_group1 = true;
     test_ctx->create_group2 = false;
@@ -1875,6 +1896,7 @@ void test_group_by_name_missing_notfound(void **state)
     /* Mock values. */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
+    mock_parse_inp(groups[0].short_name, NULL, ERR_OK);
 
     /* Test. */
     run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT);
@@ -2387,9 +2409,11 @@ void test_user_by_recent_filter_valid(void **state)
     req_mem_ctx = talloc_new(test_ctx->tctx);
     check_leaks_push(req_mem_ctx);
 
+    /* Mock values */
     /* Filters always go to DP */
     will_return(__wrap_sss_dp_get_account_send, test_ctx);
     mock_account_recv_simple();
+    //mock_parse_inp(users[0].short_name, NULL, ERR_OK);
 
     /* User TEST_USER is created with a DP callback. */
     req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev,
diff --git a/src/tests/intg/test_infopipe.py b/src/tests/intg/test_infopipe.py
index 6cd7c49a8d..5aefcac9e9 100644
--- a/src/tests/intg/test_infopipe.py
+++ b/src/tests/intg/test_infopipe.py
@@ -615,3 +615,57 @@ def test_sssctl_domain_list_app_domain(dbus_system_bus,
     assert "Error" not in output
     assert output.find("LDAP") != -1
     assert output.find("app") != -1
+
+
+def test_update_member_list_and_get_all(dbus_system_bus,
+                                        ldap_conn,
+                                        sanity_rfc2307):
+    '''
+    Test that UpdateMemberList() and GetAll() return the correct users that are
+    members of a group
+    '''
+    sssd_obj = dbus_system_bus.get_object(
+        'org.freedesktop.sssd.infopipe',
+        '/org/freedesktop/sssd/infopipe/Groups')
+    groups_iface = dbus.Interface(sssd_obj,
+                                  'org.freedesktop.sssd.infopipe.Groups')
+    group_id = 2011
+    expected_user_result = "/org/freedesktop/sssd/infopipe/Users/LDAP/1001"
+
+    group_path = groups_iface.FindByName('single_user_group')
+
+    group_object = dbus_system_bus.get_object('org.freedesktop.sssd.infopipe',
+                                              group_path)
+    group_iface = dbus.Interface(group_object,
+                                 'org.freedesktop.sssd.infopipe.Groups.Group')
+
+    # update local cache for group
+    try:
+        group_iface.UpdateMemberList(group_id)
+    except dbus.exceptions.DBusException as ex:
+        assert False, "Unexpected DBusException raised"
+
+    # check members of group
+    prop_iface = dbus.Interface(group_object,
+                                'org.freedesktop.DBus.Properties')
+    res = prop_iface.GetAll('org.freedesktop.sssd.infopipe.Groups.Group')
+    assert str(res.get("users")[0]) == expected_user_result
+
+    # delete group (there's no other way of removing a user from a group) and
+    # wait change to propagate
+    ldap_conn.delete("cn=single_user_group,ou=Groups,dc=example,dc=com")
+    time.sleep(INTERACTIVE_TIMEOUT)
+
+    # add group back but this time without any member
+    ldap_group = ldap_ent.group("dc=example,dc=com", "single_user_group", 2011)
+    ldap_conn.add_s(ldap_group[0], ldap_group[1])
+
+    # invalidate cache
+    subprocess.call(["sss_cache", "-E"])
+
+    # check that group has no members
+    group_iface.UpdateMemberList(group_id)
+    prop_interface = dbus.Interface(group_object,
+                                    'org.freedesktop.DBus.Properties')
+    res = prop_interface.GetAll('org.freedesktop.sssd.infopipe.Groups.Group')
+    assert not res.get("users")
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/sssd-devel@lists.fedorahosted.org
Do not reply to spam on the list, report it: 
https://pagure.io/fedora-infrastructure

Reply via email to