File 0011-SYSDB-Use-SYSDB_NAME-from-cached-entry-when-updating.patch of Package sssd.37243
From 03a5698dd50575fbcd700a69fe852224a8e6b465 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 4df921c8d..627cddf64 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -337,7 +337,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;
}
@@ -771,6 +781,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);
+ fail_if(data == NULL, "Failed to allocate memory");
+
+ /* Add a name alias, like if the domain was case insensitive */
+ data->attrs = sysdb_new_attrs(test_ctx);
+ fail_if(data->attrs == NULL, "Failed to allocate memory");
+ ret = sysdb_attrs_add_lc_name_alias(data->attrs, data->username);
+ fail_if(ret != EOK, "sysdb_attrs_add_lc_name_alias failed with error: %d", ret);
+ ret = test_store_user(data);
+ fail_if(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);
+ fail_if(ret != EOK, "Could not add attributes: %s", sss_strerror(ret));
+ ret = test_store_user(data);
+ fail_if(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;
@@ -6211,6 +6265,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
@@ -7839,6 +7898,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 9fcd38b67034b7a44aca0f31b1f1c966c4e456a2 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 0785bf801..469f4dff7 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -2800,6 +2800,22 @@ int sysdb_store_user(struct sss_domain_info *domain,
shell, orig_dn, attrs, cache_timeout, now);
} 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);
@@ -3032,6 +3048,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