From 7e2074a95de21f8151cd138ee434a2f35dd6ca37 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Thu, 12 Jun 2025 19:49:10 +0200 Subject: [PATCH 1/5] sysdb: add sysdb_search_user_by_upn_with_view_res() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new call will apply overrides to a user object which was searched by UPN or email address before returning it. Reviewed-by: Alexey Tikhonov Reviewed-by: Pavel Březina (cherry picked from commit 794e80f4f155cd5d97e70ee015909cd9f3b918b3) --- src/db/sysdb.h | 7 +++++++ src/db/sysdb_ops.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index a049460f0e..19e141b6a7 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -1070,6 +1070,13 @@ int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx, const char **attrs, struct ldb_result **out_res); +int sysdb_search_user_by_upn_with_view_res(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + bool domain_scope, + const char *upn, + const char **attrs, + struct ldb_result **out_res); + int sysdb_search_user_by_upn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, bool domain_scope, diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index cfc3b9e54a..c32c33120f 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -712,6 +712,43 @@ int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx, return ret; } +int sysdb_search_user_by_upn_with_view_res(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + bool domain_scope, + const char *upn, + const char **attrs, + struct ldb_result **out_res) +{ + int ret; + struct ldb_result *orig_obj = NULL; + + /* The UPN or the email address cannot be overwritten and we can search + * directly the original object. */ + ret = sysdb_search_user_by_upn_res(mem_ctx, domain, domain_scope, upn, + attrs, &orig_obj); + if (ret != EOK) { + DEBUG(ret == ENOENT ? SSSDBG_MINOR_FAILURE : SSSDBG_OP_FAILURE, + "Failed to find UPN [%s] in cache [%d][%s].\n", + upn, ret, sss_strerror(ret)); + return ret; + } + + /* If there are views we have to check if override values must be added to + * the original object. */ + if (DOM_HAS_VIEWS(domain)) { + ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0], NULL, + attrs); + if (ret != EOK && ret != ENOENT) { + talloc_free(orig_obj); + DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); + return ret; + } + } + + *out_res = orig_obj; + return ret; +} + int sysdb_search_user_by_upn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, bool domain_scope, From 4401a30593c05cdb788dbacd074dd57f86bba78c Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Thu, 12 Jun 2025 19:49:42 +0200 Subject: [PATCH 2/5] cache_req: use sysdb_search_user_by_upn_with_view_res() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To make sure any overrides are applied to the user even when searched by UPN or email address sysdb_search_user_by_upn_with_view_res() is now used in the cache request code. Reviewed-by: Alexey Tikhonov Reviewed-by: Pavel Březina (cherry picked from commit 43f22b968a48c4e1f1e7cb885e68428baa7cc7be) --- .../cache_req/plugins/cache_req_user_by_upn.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c b/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c index 037994c8c2..cfcaf49160 100644 --- a/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c +++ b/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c @@ -84,13 +84,14 @@ cache_req_user_by_upn_lookup(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_result) { - if (data->attrs == NULL) { - return sysdb_getpwupn(mem_ctx, domain, true, data->name.lookup, _result); - } - - return sysdb_search_user_by_upn_res(mem_ctx, domain, true, - data->name.lookup, data->attrs, - _result); + static const char *def_attrs[] = SYSDB_PW_ATTRS; + + return sysdb_search_user_by_upn_with_view_res(mem_ctx, domain, true, + data->name.lookup, + data->attrs == NULL + ? def_attrs + : data->attrs, + _result); } static struct tevent_req * From d5af78b6deb4b1b17ebfdaebafd031a330c23b79 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Thu, 12 Jun 2025 19:52:10 +0200 Subject: [PATCH 3/5] sysdb:: remove sysdb_getpwupn() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Alexey Tikhonov Reviewed-by: Pavel Březina (cherry picked from commit fe61b85b440380bd88d5859819a1111878ca36ea) --- src/db/sysdb.h | 6 ------ src/db/sysdb_search.c | 30 -------------------------- src/tests/cmocka/test_sysdb_ts_cache.c | 6 ------ 3 files changed, 42 deletions(-) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 19e141b6a7..427495181b 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -875,12 +875,6 @@ int sysdb_getpwuid(TALLOC_CTX *mem_ctx, uid_t uid, struct ldb_result **res); -int sysdb_getpwupn(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - bool domain_scope, - const char *upn, - struct ldb_result **res); - int sysdb_enumpwent(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **res); diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c index 513e721ca4..645871354f 100644 --- a/src/db/sysdb_search.c +++ b/src/db/sysdb_search.c @@ -598,36 +598,6 @@ static char *enum_filter(TALLOC_CTX *mem_ctx, return filter; } -int sysdb_getpwupn(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - bool domain_scope, - const char *upn, - struct ldb_result **_res) -{ - TALLOC_CTX *tmp_ctx; - struct ldb_result *res; - static const char *attrs[] = SYSDB_PW_ATTRS; - errno_t ret; - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); - return ENOMEM; - } - - ret = sysdb_search_user_by_upn_res(tmp_ctx, domain, domain_scope, upn, attrs, &res); - if (ret != EOK && ret != ENOENT) { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_upn_res() failed.\n"); - goto done; - } - - *_res = talloc_steal(mem_ctx, res); - -done: - talloc_free(tmp_ctx); - return ret; -} - errno_t sysdb_search_ts_matches(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, const char *attrs[], diff --git a/src/tests/cmocka/test_sysdb_ts_cache.c b/src/tests/cmocka/test_sysdb_ts_cache.c index f349b70619..531de72abe 100644 --- a/src/tests/cmocka/test_sysdb_ts_cache.c +++ b/src/tests/cmocka/test_sysdb_ts_cache.c @@ -1303,12 +1303,6 @@ static void test_user_byupn(void **state) TEST_NOW_2); assert_int_equal(ret, EOK); - ret = sysdb_getpwupn(test_ctx, test_ctx->tctx->dom, false, TEST_USER_UPN, &res); - assert_int_equal(ret, EOK); - assert_int_equal(res->count, 1); - assert_ts_attrs_res(res, TEST_NOW_2 + TEST_CACHE_TIMEOUT, TEST_NOW_2); - talloc_free(res); - ret = sysdb_search_user_by_upn_res(test_ctx, test_ctx->tctx->dom, false, TEST_USER_UPN, pw_fetch_attrs, &res); From 10e3fc7dde291a37cb71bef64c1f84293bcd9874 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 13 Jun 2025 09:43:22 +0200 Subject: [PATCH 4/5] tests: lookup user with overrides with email MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Alexey Tikhonov Reviewed-by: Pavel Březina (cherry picked from commit 6d8f9d7e9c8858fc108bf0e5e4fc40fcdec7ed71) --- src/tests/system/tests/test_sss_override.py | 57 +++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/tests/system/tests/test_sss_override.py b/src/tests/system/tests/test_sss_override.py index 9e5389fd82..ea61ad6bb1 100644 --- a/src/tests/system/tests/test_sss_override.py +++ b/src/tests/system/tests/test_sss_override.py @@ -116,6 +116,63 @@ def test_sss_override__user_attributes(client: Client, provider: GenericProvider assert result.home == "/home/o-user1", "User's override name homedir does not match override value!" +@pytest.mark.importance("high") +@pytest.mark.topology([KnownTopology.LDAP, KnownTopology.AD, KnownTopology.Samba]) +def test_sss_overrides__overriding_username_and_attributes_lookup_by_email(client: Client, provider: GenericProvider): + """ + :title: Locally overriding the name and POSIX attributes of a user and lookup with the email address + :setup: + 1. Create POSIX user "user1" with email "email@example.com", email is + used because the UPN is not supported in all roles of the framework + 2. Configure SSSD with "ldap_id_mapping = false" and start SSSD + 3. Create local override for "user1" + 4. Restart SSSD, this is necessary to enable local overrides + :steps: + 1. Lookup user by the original name, check the uid and gid + 2. Lookup user by the overridden name, check the uid and gid + 3. Lookup user by email, check the uid and gid + :expectedresults: + 1. User is found and uid and gid match new values + 2. User is found and uid and gid match new values + 3. User is found and uid and gid match new values + :customerscenario: True + """ + provider.user("user1").add( + uid=999011, + gid=999011, + home="/home/user1", + gecos="user", + shell="/bin/bash", + password="Secret123", + email="email@example.com", + ) + + client.sssd.domain["ldap_id_mapping"] = "False" + client.sssd.start() + + client.sss_override.user("user1").add(name="o-user1", uid=999999, gid=888888, home="/home/o-user1") + + client.sssd.restart() + + result = client.tools.getent.passwd("user1") + assert result is not None, "User not found!" + assert result.uid == 999999, "User's uid does not match override value!" + assert result.gid == 888888, "User's gid does not match override value!" + assert result.home == "/home/o-user1", "User's homedir does not match override value!" + + result = client.tools.getent.passwd("o-user1") + assert result is not None, "User not found by override name!" + assert result.uid == 999999, "Local override uid does not match override value!" + assert result.gid == 888888, "Local override gid does not match override value!" + assert result.home == "/home/o-user1", "User's override name homedir does not match override value!" + + result = client.tools.getent.passwd("email@example.com") + assert result is not None, "User not found by email!" + assert result.uid == 999999, "Local override uid does not match override value!" + assert result.gid == 888888, "Local override gid does not match override value!" + assert result.home == "/home/o-user1", "User's override name homedir does not match override value!" + + @pytest.mark.importance("high") @pytest.mark.topology([KnownTopology.LDAP, KnownTopology.AD, KnownTopology.Samba]) @pytest.mark.preferred_topology(KnownTopology.LDAP) From 16cd1d2ebee149134e4bf9c5722b4021e5102c5b Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Mon, 5 Jan 2026 10:17:27 +0100 Subject: [PATCH 5/5] sysdb: do not treat missing id-override as an error In sysdb_search_user_by_upn_with_view_res() sysdb_add_overrides_to_object() can return ENOENT if there is no id-override for the given user. This is expected and should not be treated as an error. Reviewed-by: Alexey Tikhonov (cherry picked from commit 72a42d5cbb969f61698f7403fe6e7cf6a8abf957) --- src/db/sysdb_ops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index c32c33120f..5090ae52f2 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -743,6 +743,7 @@ int sysdb_search_user_by_upn_with_view_res(TALLOC_CTX *mem_ctx, DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); return ret; } + ret = EOK; } *out_res = orig_obj;