File 0007-SYSDB-Use-SYSDB_NAME-from-cached-entry-when-updating.patch of Package sssd.36868
From 9a8873e680962563326a130cd7b3ed3f63dfc740 Mon Sep 17 00:00:00 2001
From: Samuel Cabrero <scabrero@suse.de>
Date: Tue, 7 May 2024 16:51:55 +0200
Subject: [PATCH 1/2] TESTS: Extend sysdb-tests to check case-insensitive store
operations
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If the domain is case insensitive then users and groups must be
correctly stored regardless name capitalization.
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/tests/sysdb-tests.c | 62 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 61 insertions(+), 1 deletion(-)
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
index bf8668094..f9f347da7 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -336,7 +336,17 @@ static int test_store_user(struct test_data *data)
data->username, "x",
data->uid, 0, gecos, homedir,
data->shell ? data->shell : "/bin/bash",
- NULL, NULL, NULL, -1, 0);
+ NULL, data->attrs, NULL, -1, 0);
+ if (data->attrs != NULL) {
+ /*
+ * After storing user data->attrs contains at least lastUpdate,
+ * dataExpireTimestamp and initgrExpireTimestamp. If the same test_data
+ * structure is reused add operation will fail because
+ * sysdb_store_user code path adds again these attributes to
+ * data->attrs, ending with two equal values per attribute
+ */
+ talloc_zfree(data->attrs);
+ }
return ret;
}
@@ -770,6 +780,50 @@ START_TEST (test_sysdb_store_user_existing)
}
END_TEST
+START_TEST (test_sysdb_store_user_existing_case_insensitive)
+{
+ struct sysdb_test_ctx *test_ctx;
+ struct test_data *data;
+ int ret;
+ char *uc_username;
+
+ /* Setup */
+ ret = setup_sysdb_tests(&test_ctx);
+ if (ret != EOK) {
+ ck_abort_msg("Could not set up the test");
+ return;
+ }
+
+ test_ctx->domain->case_sensitive = false;
+
+ data = test_data_new_user(test_ctx, _i);
+ sss_ck_fail_if_msg(data == NULL, "Failed to allocate memory");
+
+ /* Add a name alias, like if the domain was case insensitive */
+ data->attrs = sysdb_new_attrs(test_ctx);
+ sss_ck_fail_if_msg(data->attrs == NULL, "Failed to allocate memory");
+ ret = sysdb_attrs_add_lc_name_alias(data->attrs, data->username);
+ sss_ck_fail_if_msg(ret != EOK, "sysdb_attrs_add_lc_name_alias failed with error: %d", ret);
+ ret = test_store_user(data);
+ sss_ck_fail_if_msg(ret != EOK, "Could not store user %s: %s", data->username, sss_strerror(ret));
+
+ /* Modification with different capitalization */
+ uc_username = talloc_strdup(data, data->username);
+ for (char *p=uc_username; *p != '\0'; p++) {
+ *p = toupper(*p);
+ }
+ data->username = uc_username;
+ data->attrs = sysdb_new_attrs(test_ctx);
+ ret = sysdb_attrs_add_string(data->attrs, TEST_ATTR_NAME, TEST_ATTR_VALUE);
+ sss_ck_fail_if_msg(ret != EOK, "Could not add attributes: %s", sss_strerror(ret));
+ ret = test_store_user(data);
+ sss_ck_fail_if_msg(ret != EOK,
+ "Store with different name capitalization must succeed in "
+ "case-insensitive domains");
+ talloc_free(test_ctx);
+}
+END_TEST
+
START_TEST (test_sysdb_store_group)
{
struct sysdb_test_ctx *test_ctx;
@@ -6193,6 +6247,11 @@ START_TEST(test_sysdb_search_object_by_name)
talloc_free(res);
+ data->groupname = lc_group_name;
+
+ ret = test_store_group(data);
+ ck_assert_msg(ret == EOK, "Store with different name capitalization must succeed in case-insensitive domains");
+
talloc_free(test_ctx);
}
END_TEST
@@ -7831,6 +7890,7 @@ Suite *create_sysdb_suite(void)
tcase_add_loop_test(tc_sysdb, test_sysdb_group_dn_name, 28000, 28010);
/* sysdb_store_user allows setting attributes for existing users */
+ tcase_add_loop_test(tc_sysdb, test_sysdb_store_user_existing_case_insensitive, 27000, 27010);
tcase_add_loop_test(tc_sysdb, test_sysdb_store_user_existing, 27000, 27010);
/* test the change */
--
2.45.1
From eed81f3dfaff4b3e924e0648a489ff61b8c34c06 Mon Sep 17 00:00:00 2001
From: Samuel Cabrero <scabrero@suse.de>
Date: Wed, 22 May 2024 13:31:06 +0200
Subject: [PATCH 2/2] SYSDB: Use SYSDB_NAME from cached entry when updating
users and groups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The sysdb_store_user() and sysdb_store_group() functinos search for the
entry by name to check if it is already cached. This search considers
SYSDB_ALIAS, added when the domain is case insensitive. If a matching
entry is found use its SYSDB_NAME instead of the passed name.
It may happen the group is stored in uppercase, but later some server
returns a memberOf attribute in lowercase. When updating the group to
add the memberships the first search will find the entry, but the modify
operation will fail as the group name in the built DN will differ in case.
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/db/sysdb_ops.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 7a3c00213..d2aeb5cf5 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -2613,6 +2613,22 @@ int sysdb_store_user(struct sss_domain_info *domain,
}
} else {
/* the user exists, let's just replace attributes when set */
+ /*
+ * The sysdb_search_user_by_name() function also matches lowercased
+ * aliases, saved when the domain is case-insensitive. This means that
+ * the stored entry name can differ in capitalization from the search
+ * name. Use the cached entry name to perform the modification because
+ * if name capitalization in entry's DN differs the modify operation
+ * will fail.
+ */
+ const char *entry_name =
+ ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
+ if (entry_name != NULL) {
+ name = entry_name;
+ } else {
+ DEBUG(SSSDBG_MINOR_FAILURE, "User '%s' without a name?\n", name);
+ }
+
ret = sysdb_store_user_attrs(domain, name, uid, gid, gecos, homedir,
shell, orig_dn, attrs, remove_attrs,
cache_timeout, now);
@@ -2847,6 +2863,22 @@ int sysdb_store_group(struct sss_domain_info *domain,
ret = sysdb_store_new_group(domain, name, gid, attrs,
cache_timeout, now);
} else {
+ /*
+ * The sysdb_search_group_by_name() function also matches lowercased
+ * aliases, saved when the domain is case-insensitive. This means that
+ * the stored entry name can differ in capitalization from the search
+ * name. Use the cached entry name to perform the modification because
+ * if name capitalization in entry's DN differs the modify operation
+ * will fail.
+ */
+ const char *entry_name =
+ ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
+ if (entry_name != NULL) {
+ name = entry_name;
+ } else {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Group '%s' without a name?\n", name);
+ }
+
ret = sysdb_store_group_attrs(domain, name, gid, attrs,
cache_timeout, now);
}
--
2.45.1