import CS sssd-2.9.6-4.el9

This commit is contained in:
eabdullin 2025-03-11 08:13:33 +00:00
parent a964670b11
commit e9b714e709
14 changed files with 263 additions and 833 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/sssd-2.9.5.tar.gz
SOURCES/sssd-2.9.6.tar.gz

View File

@ -1 +1 @@
f6704a9df1303e154ef8526f9f21e2b72879c046 SOURCES/sssd-2.9.5.tar.gz
da2490cf07d91fd340ce87ffc209fc2420ccf60c SOURCES/sssd-2.9.6.tar.gz

View File

@ -0,0 +1,83 @@
From 4f9fb5fd301d635ad54bf6d0ef93d6811445c7f9 Mon Sep 17 00:00:00 2001
From: Samuel Cabrero <scabrero@suse.de>
Date: Wed, 22 May 2024 13:31:06 +0200
Subject: [PATCH] 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>
(cherry picked from commit d2b734b926e1f23370c9cabd8ba6f07bf6b29a86)
Reviewed-by: Justin Stephenson <jstephen@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 76f4580aa..32e49d759 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -2615,6 +2615,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);
@@ -2849,6 +2865,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.47.0

View File

@ -1,34 +0,0 @@
From ee8de7e404ba65062e0b373f2badc0475835bbde Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Tue, 11 Jun 2024 15:57:23 +0200
Subject: [PATCH] spec: change passkey_child owner
passkey_child owner was incorrectly set to $sssd_user:$sssd_user, when
it should be root:root. Correcting it.
Fixes: 30daa0ccdae5 ("spec: update to include passkey")
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
(cherry picked from commit bb72b53d3a222f016d882853a619bd74c237edf9)
---
contrib/sssd.spec.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index 03171a872..3735d4f06 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -998,7 +998,7 @@ done
%if %{build_passkey}
%files passkey
-%attr(755,%{sssd_user},%{sssd_user}) %{_libexecdir}/%{servicename}/passkey_child
+%{_libexecdir}/%{servicename}/passkey_child
%{_libdir}/%{name}/modules/sssd_krb5_passkey_plugin.so
%{_datadir}/sssd/krb5-snippets/sssd_enable_passkey
%config(noreplace) %{_sysconfdir}/krb5.conf.d/sssd_enable_passkey
--
2.44.0

View File

@ -0,0 +1,93 @@
From 6aba9a7dd2261c19f053d5fbd5358fdaf335b807 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Wed, 5 Feb 2025 08:59:49 +0100
Subject: [PATCH] KCM: fix memory leak
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The copy of 'secret' argument - `secret_val.data` - was left hanging
on `sss_sec_ctx`, effectively resulting in a memory leak.
But this copy isn't actually required as this data isn't modified in
below operations.
This is a backport of https://github.com/SSSD/sssd/pull/7823
:fixes:'sssd_kcm' memory leak was fixed.
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
---
src/responder/kcm/secrets/secrets.c | 28 ++++++++++++----------------
1 file changed, 12 insertions(+), 16 deletions(-)
diff --git a/src/responder/kcm/secrets/secrets.c b/src/responder/kcm/secrets/secrets.c
index 730fa68b6..d1a9672d5 100644
--- a/src/responder/kcm/secrets/secrets.c
+++ b/src/responder/kcm/secrets/secrets.c
@@ -953,7 +953,7 @@ errno_t sss_sec_put(struct sss_sec_req *req,
size_t secret_len)
{
struct ldb_message *msg;
- struct ldb_val secret_val;
+ const struct ldb_val secret_val = { .length = secret_len, .data = secret };
int ret;
if (req == NULL || secret == NULL) {
@@ -1002,13 +1002,11 @@ errno_t sss_sec_put(struct sss_sec_req *req,
goto done;
}
- secret_val.length = secret_len;
- secret_val.data = talloc_memdup(req->sctx, secret, secret_len);
- if (!secret_val.data) {
- ret = ENOMEM;
- goto done;
- }
-
+ /* `ldb_msg_add_value()` does NOT make a copy of secret_val::*data
+ * but rather copies a pointer under the hood.
+ * This is fine since no operations modifying this data are performed
+ * below and 'msg' is freed before function returns.
+ */
ret = ldb_msg_add_value(msg, SEC_ATTR_SECRET, &secret_val, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
@@ -1050,7 +1048,7 @@ errno_t sss_sec_update(struct sss_sec_req *req,
size_t secret_len)
{
struct ldb_message *msg;
- struct ldb_val secret_val;
+ const struct ldb_val secret_val = { .length = secret_len, .data = secret };
int ret;
if (req == NULL || secret == NULL) {
@@ -1099,13 +1097,6 @@ errno_t sss_sec_update(struct sss_sec_req *req,
goto done;
}
- secret_val.length = secret_len;
- secret_val.data = talloc_memdup(req->sctx, secret, secret_len);
- if (!secret_val.data) {
- ret = ENOMEM;
- goto done;
- }
-
/* FIXME - should we have a lastUpdate timestamp? */
ret = ldb_msg_add_empty(msg, SEC_ATTR_SECRET, LDB_FLAG_MOD_REPLACE, NULL);
if (ret != LDB_SUCCESS) {
@@ -1115,6 +1106,11 @@ errno_t sss_sec_update(struct sss_sec_req *req,
goto done;
}
+ /* `ldb_msg_add_value()` does NOT make a copy of secret_val::*data
+ * but rather copies a pointer under the hood.
+ * This is fine since no operations modifying this data are performed
+ * below and 'msg' is freed before function returns.
+ */
ret = ldb_msg_add_value(msg, SEC_ATTR_SECRET, &secret_val, NULL);
if (ret != LDB_SUCCESS) {
DEBUG(SSSDBG_MINOR_FAILURE,
--
2.47.0

View File

@ -1,58 +0,0 @@
From d234cf5d6e793daf2c96856887acb641c4dff407 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 14 Jun 2024 16:10:34 +0200
Subject: [PATCH] sysdb: do not fail to add non-posix user to MPG domain
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
SSSD does not handle the root user (UID==0) and treats all accounts with
UID 0 as non-Posix accounts. The primary GID of those accounts is 0 as
well and as a result for those accounts in MPG domains the check for a
collisions of the primary GID should be skipped. The current code might
e.g. cause issues during GPO evaluation when adding a host account into
the cache which does not have any UID or GID set in AD and SSSD is
configured to read UID and GID from AD.
Resolves: https://github.com/SSSD/sssd/issues/7451
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
(cherry picked from commit 986bb726202e69b05f861c14c3a220379baf9bd1)
---
src/db/sysdb_ops.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 0f62e3b1a..76f4580aa 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -1914,15 +1914,17 @@ int sysdb_add_user(struct sss_domain_info *domain,
goto done;
}
- ret = sysdb_search_group_by_gid(tmp_ctx, domain, uid, NULL, &msg);
- if (ret != ENOENT) {
- if (ret == EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Group with GID [%"SPRIgid"] already exists in an "
- "MPG domain\n", gid);
- ret = EEXIST;
+ if (uid != 0) { /* uid == 0 means non-POSIX object */
+ ret = sysdb_search_group_by_gid(tmp_ctx, domain, uid, NULL, &msg);
+ if (ret != ENOENT) {
+ if (ret == EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Group with GID [%"SPRIgid"] already exists in an "
+ "MPG domain\n", uid);
+ ret = EEXIST;
+ }
+ goto done;
}
- goto done;
}
}
--
2.44.0

View File

@ -0,0 +1,59 @@
From e7c76df8c0fa4a361c433684553ba1384166a564 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Wed, 12 Feb 2025 11:30:22 +0100
Subject: [PATCH] KCM: another memory leak fixed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
```
...
talloc_new: src/responder/kcm/kcmsrv_ccache.c:405 contains 0 bytes in 1 blocks (ref 0) 0x563feaabc0a0
talloc_new: src/responder/kcm/kcmsrv_ccache.c:405 contains 0 bytes in 1 blocks (ref 0) 0x563feaa84f90
talloc_new: src/responder/kcm/kcmsrv_ccache.c:405 contains 0 bytes in 1 blocks (ref 0) 0x563feaabf520
...
```
Reviewed-by: Alejandro López <allopez@redhat.com>
(cherry picked from commit 9e72bc242b600158d7920b2b98644efa42fd1ffa)
---
src/responder/kcm/kcmsrv_ccache.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c
index 6e4ea64e0..4f4f8b46a 100644
--- a/src/responder/kcm/kcmsrv_ccache.c
+++ b/src/responder/kcm/kcmsrv_ccache.c
@@ -404,7 +404,7 @@ krb5_creds **kcm_cc_unmarshal(TALLOC_CTX *mem_ctx,
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
- goto done;
+ goto fail;
}
for (cred = kcm_cc_get_cred(cc); cred != NULL; cred = kcm_cc_next_cred(cred)) {
@@ -417,7 +417,7 @@ krb5_creds **kcm_cc_unmarshal(TALLOC_CTX *mem_ctx,
cred_list[i] = kcm_cred_to_krb5(krb_context, cred);
if (cred_list[i] == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to convert kcm cred to krb5\n");
- goto done;
+ goto fail;
}
}
@@ -426,8 +426,10 @@ krb5_creds **kcm_cc_unmarshal(TALLOC_CTX *mem_ctx,
talloc_steal(mem_ctx, cred_list);
+ talloc_free(tmp_ctx);
return cred_list;
-done:
+
+fail:
talloc_free(tmp_ctx);
return NULL;
#endif
--
2.47.0

View File

@ -1,37 +0,0 @@
From 723a30b45ba4cbd9a4913fd37d68e392dcfc16ba Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 7 Jun 2024 18:04:00 +0200
Subject: [PATCH] ad: use right memory context in GPO code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The original primary SID is allocated on a temporary context and must be
move to be longer living one to still be available when the SID is
evaluated later in the code.
Resolves: https://github.com/SSSD/sssd/issues/7411
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
(cherry picked from commit b25e510ad60f6ce0b57063cce648c3aa48b21241)
---
src/providers/ad/ad_gpo.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index b879b0a08..ed664ec83 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -711,7 +711,7 @@ ad_gpo_get_sids(TALLOC_CTX *mem_ctx,
}
group_sids[i++] = talloc_strdup(group_sids, AD_AUTHENTICATED_USERS_SID);
if (orig_gid_sid != NULL) {
- group_sids[i++] = orig_gid_sid;
+ group_sids[i++] = talloc_steal(group_sids, orig_gid_sid);
}
group_sids[i] = NULL;
--
2.44.0

View File

@ -1,208 +0,0 @@
From 09b23e78806d8930c3f1b9e411dc8cf464c18998 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Tue, 16 Jul 2024 13:08:02 +0200
Subject: [PATCH 4/5] TS_CACHE: never try to upgrade timestamps cache
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It's easier and more consistent to recreate it instead.
This is a natural extension of 3b67fc6488ac10ca13561d9032f59951f82203e6
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
(cherry picked from commit fc2a26c306e51b66680aef85aa0d2c41d8049a7f)
---
src/db/sysdb_init.c | 103 +----------------------------------------
src/db/sysdb_upgrade.c | 45 ------------------
2 files changed, 1 insertion(+), 147 deletions(-)
diff --git a/src/db/sysdb_init.c b/src/db/sysdb_init.c
index 38a9cd64a..a1d02d49c 100644
--- a/src/db/sysdb_init.c
+++ b/src/db/sysdb_init.c
@@ -376,57 +376,6 @@ static errno_t sysdb_cache_create_empty(struct ldb_context *ldb,
return EOK;
}
-static errno_t sysdb_ts_cache_upgrade(TALLOC_CTX *mem_ctx,
- struct sysdb_ctx *sysdb,
- struct ldb_context *ldb,
- struct sss_domain_info *domain,
- const char *cur_version,
- const char **_new_version)
-{
- errno_t ret;
- TALLOC_CTX *tmp_ctx;
- const char *version;
- struct ldb_context *save_ldb;
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- return ENOMEM;
- }
-
- /* The upgrade process depends on having ldb around, yet the upgrade
- * function shouldn't set the ldb pointer, only the connect function
- * should after it's successful. To avoid hard refactoring, save the
- * ldb pointer here and restore in the 'done' handler
- */
- save_ldb = sysdb->ldb;
- sysdb->ldb = ldb;
-
- version = talloc_strdup(tmp_ctx, cur_version);
- if (version == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- DEBUG(SSSDBG_CONF_SETTINGS,
- "Upgrading timstamp cache of DB [%s] from version: %s\n",
- domain->name, version);
-
- if (strcmp(version, SYSDB_TS_VERSION_0_1) == 0) {
- ret = sysdb_ts_upgrade_01(sysdb, &version);
- if (ret != EOK) {
- goto done;
- }
- }
-
- ret = EOK;
-
-done:
- sysdb->ldb = save_ldb;
- *_new_version = version;
- talloc_free(tmp_ctx);
- return ret;
-}
-
static errno_t sysdb_domain_cache_upgrade(TALLOC_CTX *mem_ctx,
struct sysdb_ctx *sysdb,
struct sysdb_dom_upgrade_ctx *upgrade_ctx,
@@ -884,56 +833,6 @@ static int sysdb_timestamp_cache_connect(struct sysdb_ctx *sysdb,
}
ret = sysdb_ts_cache_connect(tmp_ctx, sysdb, domain, &ldb, &version);
- switch (ret) {
- case ERR_SYSDB_VERSION_TOO_OLD:
- if (upgrade_ctx == NULL) {
- DEBUG(SSSDBG_FATAL_FAILURE,
- "DB version too old [%s], expected [%s] for domain %s!\n",
- version, SYSDB_VERSION, domain->name);
- break;
- }
-
- ret = sysdb_ts_cache_upgrade(tmp_ctx, sysdb, ldb, domain, version,
- &version);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- "Could not upgrade the timestamp ldb file (%d) (%s)\n",
- ret, sss_strerror(ret));
- break;
- }
-
- /* The version should now match SYSDB_VERSION.
- * If not, it means we didn't match any of the
- * known older versions. The DB might be
- * corrupt or generated by a newer version of
- * SSSD.
- */
- ret = sysdb_version_check(SYSDB_TS_VERSION, version);
- if (ret == EOK) {
- /* The cache has been upgraded.
- * We need to reopen the LDB to ensure that
- * any changes made above take effect.
- */
- ret = sysdb_ldb_reconnect(tmp_ctx,
- sysdb->ldb_ts_file,
- LDB_FLG_NOSYNC,
- &ldb);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- "Could not reopen the timestamp ldb file (%d) (%s)\n",
- ret, sss_strerror(ret));
- }
- }
- break;
- case ERR_SYSDB_VERSION_TOO_NEW:
- DEBUG(SSSDBG_MINOR_FAILURE,
- "DB version too new [%s], expected [%s] for domain %s!\n",
- version, SYSDB_TS_VERSION, domain->name);
- break;
- default:
- break;
- }
-
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE,
"The timestamps cache could not be opened. "
@@ -953,7 +852,7 @@ static int sysdb_timestamp_cache_connect(struct sysdb_ctx *sysdb,
ret = sysdb_ts_cache_connect(tmp_ctx, sysdb, domain, &ldb, &version);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE,
- "Could not delete the timestamp ldb file (%d) (%s)\n",
+ "sysdb_ts_cache_connect() failed after cache deletion [%d]: %s\n",
ret, sss_strerror(ret));
}
}
diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c
index 328bd2962..37c0007cb 100644
--- a/src/db/sysdb_upgrade.c
+++ b/src/db/sysdb_upgrade.c
@@ -2774,51 +2774,6 @@ done:
return ret;
}
-int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver)
-{
- struct upgrade_ctx *ctx;
- errno_t ret;
- struct ldb_message *msg = NULL;
-
- ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_TS_VERSION_0_2, &ctx);
- if (ret) {
- return ret;
- }
-
- /* Remove @IDXONE from index */
- talloc_free(msg);
- msg = ldb_msg_new(ctx);
- if (msg == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- msg->dn = ldb_dn_new(msg, sysdb->ldb, "@INDEXLIST");
- if (msg->dn == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = ldb_msg_add_empty(msg, "@IDXONE", LDB_FLAG_MOD_DELETE, NULL);
- if (ret != LDB_SUCCESS) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = ldb_modify(sysdb->ldb, msg);
- if (ret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(ret);
- goto done;
- }
-
- /* conversion done, update version number */
- ret = update_version(ctx);
-
-done:
- ret = finish_upgrade(ret, &ctx, ver);
- return ret;
-}
-
/*
* Example template for future upgrades.
* Copy and change version numbers as appropriate.
--
2.45.2

View File

@ -1,147 +0,0 @@
From 13e3d0390b9aaf72a855b857857c3cdd6eb6252a Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Fri, 21 Jun 2024 19:09:29 +0200
Subject: [PATCH 5/5] SYSDB: remove index on `dataExpireTimestamp`
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This index was only used in cleanup tasks that don't run often.
On the other hand, this index is huge and degrades performance of libldb
in general.
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
(cherry picked from commit f0d45464cee1d2a6a2719dbffe5bbf6189d0554a)
---
src/db/sysdb_init.c | 8 ++++++++
src/db/sysdb_private.h | 9 +++++----
src/db/sysdb_upgrade.c | 27 +++++++++++++++++++++++++++
3 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/src/db/sysdb_init.c b/src/db/sysdb_init.c
index a1d02d49c..68b9744dd 100644
--- a/src/db/sysdb_init.c
+++ b/src/db/sysdb_init.c
@@ -559,6 +559,13 @@ static errno_t sysdb_domain_cache_upgrade(TALLOC_CTX *mem_ctx,
}
}
+ if (strcmp(version, SYSDB_VERSION_0_24) == 0) {
+ ret = sysdb_upgrade_24(sysdb, &version);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
ret = EOK;
done:
sysdb->ldb = save_ldb;
@@ -765,6 +772,7 @@ static int sysdb_domain_cache_connect(struct sysdb_ctx *sysdb,
ret = sysdb_domain_cache_upgrade(tmp_ctx, sysdb, upgrade_ctx,
ldb, domain, version, &version);
if (ret != EOK) {
+ DEBUG(SSSDBG_TRACE_FUNC, "sysdb_domain_cache_upgrade() failed\n");
goto done;
}
diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h
index 63f7b5601..b814f97a5 100644
--- a/src/db/sysdb_private.h
+++ b/src/db/sysdb_private.h
@@ -23,6 +23,7 @@
#ifndef __INT_SYS_DB_H__
#define __INT_SYS_DB_H__
+#define SYSDB_VERSION_0_25 "0.25"
#define SYSDB_VERSION_0_24 "0.24"
#define SYSDB_VERSION_0_23 "0.23"
#define SYSDB_VERSION_0_22 "0.22"
@@ -48,7 +49,7 @@
#define SYSDB_VERSION_0_2 "0.2"
#define SYSDB_VERSION_0_1 "0.1"
-#define SYSDB_VERSION SYSDB_VERSION_0_24
+#define SYSDB_VERSION SYSDB_VERSION_0_25
#define SYSDB_BASE_LDIF \
"dn: @ATTRIBUTES\n" \
@@ -72,7 +73,6 @@
"@IDXATTR: uidNumber\n" \
"@IDXATTR: gidNumber\n" \
"@IDXATTR: lastUpdate\n" \
- "@IDXATTR: dataExpireTimestamp\n" \
"@IDXATTR: originalDN\n" \
"@IDXATTR: nameAlias\n" \
"@IDXATTR: servicePort\n" \
@@ -104,10 +104,11 @@
"\n"
/* The timestamp cache has its own versioning */
+#define SYSDB_TS_VERSION_0_3 "0.3"
#define SYSDB_TS_VERSION_0_2 "0.2"
#define SYSDB_TS_VERSION_0_1 "0.1"
-#define SYSDB_TS_VERSION SYSDB_TS_VERSION_0_2
+#define SYSDB_TS_VERSION SYSDB_TS_VERSION_0_3
#define SYSDB_TS_BASE_LDIF \
"dn: @ATTRIBUTES\n" \
@@ -115,7 +116,6 @@
"\n" \
"dn: @INDEXLIST\n" \
"@IDXATTR: lastUpdate\n" \
- "@IDXATTR: dataExpireTimestamp\n" \
"\n" \
"dn: cn=sysdb\n" \
"cn: sysdb\n" \
@@ -194,6 +194,7 @@ int sysdb_upgrade_20(struct sysdb_ctx *sysdb, const char **ver);
int sysdb_upgrade_21(struct sysdb_ctx *sysdb, const char **ver);
int sysdb_upgrade_22(struct sysdb_ctx *sysdb, const char **ver);
int sysdb_upgrade_23(struct sysdb_ctx *sysdb, const char **ver);
+int sysdb_upgrade_24(struct sysdb_ctx *sysdb, const char **ver);
int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver);
diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c
index 37c0007cb..b010488ca 100644
--- a/src/db/sysdb_upgrade.c
+++ b/src/db/sysdb_upgrade.c
@@ -2774,6 +2774,33 @@ done:
return ret;
}
+int sysdb_upgrade_24(struct sysdb_ctx *sysdb, const char **ver)
+{
+ struct upgrade_ctx *ctx;
+ errno_t ret;
+
+ ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_25, &ctx);
+ if (ret) {
+ return ret;
+ }
+
+ ret = sysdb_ldb_mod_index(sysdb, SYSDB_IDX_DELETE, sysdb->ldb, "dataExpireTimestamp");
+ if (ret == ENOENT) { /*nothing to delete */
+ ret = EOK;
+ }
+ if (ret != EOK) {
+ DEBUG(SSSDBG_TRACE_FUNC, "sysdb_ldb_mod_index() failed [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = update_version(ctx);
+
+done:
+ ret = finish_upgrade(ret, &ctx, ver);
+ return ret;
+}
+
/*
* Example template for future upgrades.
* Copy and change version numbers as appropriate.
--
2.45.2

View File

@ -1,115 +0,0 @@
From 39cbb8df402f59b4df2442eb291600773e7062cc Mon Sep 17 00:00:00 2001
From: Petr Mikhalicin <pmikhalicin@rutoken.ru>
Date: Fri, 10 Nov 2023 15:24:48 +0600
Subject: [PATCH 6/8] pam_sss: fix passthrow of old authtok from another pam
modules at PAM_PRELIM_CHECK
pam_sss ignored old authtoks passed from another pam modules
Resolves: https://github.com/SSSD/sssd/issues/7007
Resolves: https://github.com/SSSD/sssd/issues/5418
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit ae6b9163be0a5a8846e8dbf2e0da2c29221781b9)
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/sss_client/pam_sss.c | 75 ++++++++++++++++++++++++----------------
1 file changed, 45 insertions(+), 30 deletions(-)
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index 41a528dda..5171e58ec 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -2728,42 +2728,57 @@ static int get_authtok_for_password_change(pam_handle_t *pamh,
exp_data = NULL;
}
- /* we query for the old password during PAM_PRELIM_CHECK to make
- * pam_sss work e.g. with pam_cracklib */
if (pam_flags & PAM_PRELIM_CHECK) {
- if ( (getuid() != 0 || exp_data ) && !(flags & PAM_CLI_FLAGS_USE_FIRST_PASS)) {
- if (flags & PAM_CLI_FLAGS_USE_2FA
- || (pi->otp_vendor != NULL && pi->otp_token_id != NULL
- && pi->otp_challenge != NULL)) {
- if (pi->password_prompting) {
- ret = prompt_2fa(pamh, pi, _("First Factor (Current Password): "),
- _("Second Factor (optional): "));
- } else {
- ret = prompt_2fa(pamh, pi, _("First Factor (Current Password): "),
- _("Second Factor: "));
- }
+ if (getuid() == 0 && !exp_data )
+ return PAM_SUCCESS;
+
+ if (flags & PAM_CLI_FLAGS_USE_2FA
+ || (pi->otp_vendor != NULL && pi->otp_token_id != NULL
+ && pi->otp_challenge != NULL)) {
+ if (pi->password_prompting) {
+ ret = prompt_2fa(pamh, pi, _("First Factor (Current Password): "),
+ _("Second Factor (optional): "));
} else {
- ret = prompt_password(pamh, pi, _("Current Password: "));
+ ret = prompt_2fa(pamh, pi, _("First Factor (Current Password): "),
+ _("Second Factor: "));
}
- if (ret != PAM_SUCCESS) {
- D(("failed to get credentials from user"));
- return ret;
+ } else if ((flags & PAM_CLI_FLAGS_USE_FIRST_PASS)
+ && check_authtok_data(pamh, pi) != 0) {
+ if (pi->pamstack_oldauthtok == NULL) {
+ pi->pam_authtok_type = SSS_AUTHTOK_TYPE_EMPTY;
+ pi->pam_authtok = NULL;
+ pi->pam_authtok_size = 0;
+ } else {
+ pi->pam_authtok = strdup(pi->pamstack_oldauthtok);
+ if (pi->pam_authtok == NULL) {
+ D(("strdup failed"));
+ return PAM_BUF_ERR;
+ }
+ pi->pam_authtok_type = SSS_AUTHTOK_TYPE_PASSWORD;
+ pi->pam_authtok_size = strlen(pi->pam_authtok);
}
+ ret = PAM_SUCCESS;
+ } else {
+ ret = prompt_password(pamh, pi, _("Current Password: "));
+ }
+ if (ret != PAM_SUCCESS) {
+ D(("failed to get credentials from user"));
+ return ret;
+ }
- ret = pam_set_item(pamh, PAM_OLDAUTHTOK, pi->pam_authtok);
- if (ret != PAM_SUCCESS) {
- D(("Failed to set PAM_OLDAUTHTOK [%s], "
- "oldauthtok may not be available",
- pam_strerror(pamh,ret)));
- return ret;
- }
+ ret = pam_set_item(pamh, PAM_OLDAUTHTOK, pi->pam_authtok);
+ if (ret != PAM_SUCCESS) {
+ D(("Failed to set PAM_OLDAUTHTOK [%s], "
+ "oldauthtok may not be available",
+ pam_strerror(pamh,ret)));
+ return ret;
+ }
- if (pi->pam_authtok_type == SSS_AUTHTOK_TYPE_2FA) {
- ret = keep_authtok_data(pamh, pi);
- if (ret != 0) {
- D(("Failed to store authtok data to pam handle. Password "
- "change might fail."));
- }
+ if (pi->pam_authtok_type == SSS_AUTHTOK_TYPE_2FA) {
+ ret = keep_authtok_data(pamh, pi);
+ if (ret != 0) {
+ D(("Failed to store authtok data to pam handle. Password "
+ "change might fail."));
}
}
--
2.45.2

View File

@ -1,178 +0,0 @@
From ef375cdd67b51d8fb63cae4d3cd40f3a5c2bc173 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 1 Jul 2024 20:40:30 +0200
Subject: [PATCH 7/8] krb5_child: do not try passwords with OTP
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
During two-factor authentication (OTP) krb5_child should use use the
dedicated OTP auth types SSS_AUTHTOK_TYPE_2FA and
SSS_AUTHTOK_TYPE_2FA_SINGLE exclusively and should not try password or
other types.
The special handling needed of ssh under certain conditions are
documented in the code and the man page.
Resolves: https://github.com/SSSD/sssd/issues/7456
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
(cherry picked from commit af799964e5fa1264467b49988021c054586eff27)
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/man/sssd.conf.5.xml | 11 +++++++++
src/providers/krb5/krb5_child.c | 11 +--------
src/sss_client/pam_sss.c | 44 ++++++++++++++++++++++++---------
3 files changed, 44 insertions(+), 22 deletions(-)
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index fb86a4e41..8ac1a4418 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -4559,6 +4559,17 @@ ldap_user_extra_attrs = phone:telephoneNumber
to log in either only with the password or with both factors
two-step prompting has to be used.
</para>
+ <para>
+ Some clients, such as SSH with
+ 'PasswordAuthentication yes', generate their own prompts
+ and do not use prompts provided by SSSD or other PAM
+ modules. Additionally, for SSH with
+ PasswordAuthentication, if two-factor authentication is
+ available, SSSD expects that the
+ credentials entered by the user at the SSH password prompt
+ will always be the two factors in a single string, even if
+ two-factor authentication is optional.
+ </para>
</listitem>
</varlistentry>
</variablelist>
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 494711de9..cb9a9ce73 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -536,15 +536,6 @@ static krb5_error_code tokeninfo_matches(TALLOC_CTX *mem_ctx,
size_t fa2_len;
switch (sss_authtok_get_type(auth_tok)) {
- case SSS_AUTHTOK_TYPE_PASSWORD:
- ret = sss_authtok_get_password(auth_tok, &pwd, &len);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_password failed.\n");
- return ret;
- }
-
- return tokeninfo_matches_pwd(mem_ctx, ti, pwd, len, out_token, out_pin);
- break;
case SSS_AUTHTOK_TYPE_2FA_SINGLE:
ret = sss_authtok_get_2fa_single(auth_tok, &pwd, &len);
if (ret != EOK) {
@@ -569,7 +560,7 @@ static krb5_error_code tokeninfo_matches(TALLOC_CTX *mem_ctx,
"Unsupported authtok type %d\n", sss_authtok_get_type(auth_tok));
}
- return EINVAL;
+ return EAGAIN;
}
static krb5_error_code answer_otp(krb5_context ctx,
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index 5171e58ec..d43bd0f55 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -1656,6 +1656,7 @@ static int prompt_password(pam_handle_t *pamh, struct pam_items *pi,
}
static int prompt_2fa(pam_handle_t *pamh, struct pam_items *pi,
+ bool second_factor_optional,
const char *prompt_fa1, const char *prompt_fa2)
{
int ret;
@@ -1706,13 +1707,30 @@ static int prompt_2fa(pam_handle_t *pamh, struct pam_items *pi,
goto done;
}
- if (resp[1].resp == NULL || *(resp[1].resp) == '\0'
- || (pi->pam_service != NULL && strcmp(pi->pam_service, "sshd") == 0
- && strcmp(resp[0].resp, resp[1].resp) == 0)) {
+ if (resp[1].resp == NULL || *(resp[1].resp) == '\0') {
/* Missing second factor, assume first factor contains combined 2FA
- * credentials.
- * Special handling for SSH with password authentication. Combined
- * 2FA credentials are used but SSH puts them in both responses. */
+ * credentials if the second factor is not optional. If it is optional
+ * then it is assumed that the first factor contain the password. */
+ pi->pam_authtok = strndup(resp[0].resp, MAX_AUTHTOK_SIZE);
+ if (pi->pam_authtok == NULL) {
+ D(("strndup failed."));
+ ret = PAM_BUF_ERR;
+ goto done;
+ }
+ pi->pam_authtok_size = strlen(pi->pam_authtok) + 1;
+ pi->pam_authtok_type = second_factor_optional
+ ? SSS_AUTHTOK_TYPE_PASSWORD
+ : SSS_AUTHTOK_TYPE_2FA_SINGLE;
+ } else if (pi->pam_service != NULL && strcmp(pi->pam_service, "sshd") == 0
+ && strcmp(resp[0].resp, resp[1].resp) == 0) {
+ /* Special handling for SSH with password authentication (ssh's
+ * 'PasswordAuthentication' option. In this mode the ssh client
+ * directly prompts the user for a password and the prompts we are
+ * sending are ignored. Since we send two prompts ssh * will create two
+ * response as well with the same content. We assume that the combined
+ * 2FA credentials are used even if the second factor is optional
+ * because there is no indication about the intention of the user. As a
+ * result we prefer the more secure variant. */
pi->pam_authtok = strndup(resp[0].resp, MAX_AUTHTOK_SIZE);
if (pi->pam_authtok == NULL) {
@@ -1721,7 +1739,7 @@ static int prompt_2fa(pam_handle_t *pamh, struct pam_items *pi,
goto done;
}
pi->pam_authtok_size = strlen(pi->pam_authtok) + 1;
- pi->pam_authtok_type = SSS_AUTHTOK_TYPE_PASSWORD;
+ pi->pam_authtok_type = SSS_AUTHTOK_TYPE_2FA_SINGLE;
} else {
ret = sss_auth_pack_2fa_blob(resp[0].resp, 0, resp[1].resp, 0, NULL, 0,
@@ -2487,7 +2505,7 @@ static int prompt_by_config(pam_handle_t *pamh, struct pam_items *pi)
ret = prompt_password(pamh, pi, pc_get_password_prompt(pi->pc[c]));
break;
case PC_TYPE_2FA:
- ret = prompt_2fa(pamh, pi, pc_get_2fa_1st_prompt(pi->pc[c]),
+ ret = prompt_2fa(pamh, pi, false, pc_get_2fa_1st_prompt(pi->pc[c]),
pc_get_2fa_2nd_prompt(pi->pc[c]));
break;
case PC_TYPE_2FA_SINGLE:
@@ -2564,10 +2582,10 @@ static int get_authtok_for_authentication(pam_handle_t *pamh,
|| (pi->otp_vendor != NULL && pi->otp_token_id != NULL
&& pi->otp_challenge != NULL)) {
if (pi->password_prompting) {
- ret = prompt_2fa(pamh, pi, _("First Factor: "),
+ ret = prompt_2fa(pamh, pi, true, _("First Factor: "),
_("Second Factor (optional): "));
} else {
- ret = prompt_2fa(pamh, pi, _("First Factor: "),
+ ret = prompt_2fa(pamh, pi, false, _("First Factor: "),
_("Second Factor: "));
}
} else if (pi->passkey_prompt_pin) {
@@ -2736,10 +2754,12 @@ static int get_authtok_for_password_change(pam_handle_t *pamh,
|| (pi->otp_vendor != NULL && pi->otp_token_id != NULL
&& pi->otp_challenge != NULL)) {
if (pi->password_prompting) {
- ret = prompt_2fa(pamh, pi, _("First Factor (Current Password): "),
+ ret = prompt_2fa(pamh, pi, true,
+ _("First Factor (Current Password): "),
_("Second Factor (optional): "));
} else {
- ret = prompt_2fa(pamh, pi, _("First Factor (Current Password): "),
+ ret = prompt_2fa(pamh, pi, false,
+ _("First Factor (Current Password): "),
_("Second Factor: "));
}
} else if ((flags & PAM_CLI_FLAGS_USE_FIRST_PASS)
--
2.45.2

View File

@ -1,45 +0,0 @@
From 7e76396a891b4c704f1db8c71a217f869bef0ec3 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 12 Jul 2024 13:46:00 +0200
Subject: [PATCH 8/8] pam_sss: add missing optional 2nd factor handling
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is a follow up to pull-request #7462 and adds the proper handling of
an optional second factor in case the prompting is configured.
Resolves: https://github.com/SSSD/sssd/issues/7456
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
(cherry picked from commit 077d2993a1b306e7cfe61618cbd5d03c602572f8)
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/sss_client/pam_sss.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index d43bd0f55..d1101e16c 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -2505,8 +2505,13 @@ static int prompt_by_config(pam_handle_t *pamh, struct pam_items *pi)
ret = prompt_password(pamh, pi, pc_get_password_prompt(pi->pc[c]));
break;
case PC_TYPE_2FA:
- ret = prompt_2fa(pamh, pi, false, pc_get_2fa_1st_prompt(pi->pc[c]),
- pc_get_2fa_2nd_prompt(pi->pc[c]));
+ if (pi->password_prompting) {
+ ret = prompt_2fa(pamh, pi, true, pc_get_2fa_1st_prompt(pi->pc[c]),
+ pc_get_2fa_2nd_prompt(pi->pc[c]));
+ } else {
+ ret = prompt_2fa(pamh, pi, false, pc_get_2fa_1st_prompt(pi->pc[c]),
+ pc_get_2fa_2nd_prompt(pi->pc[c]));
+ }
break;
case PC_TYPE_2FA_SINGLE:
ret = prompt_2fa_single(pamh, pi,
--
2.45.2

View File

@ -26,7 +26,7 @@
%global samba_package_version %(rpm -q samba-devel --queryformat %{version}-%{release})
Name: sssd
Version: 2.9.5
Version: 2.9.6
Release: 4%{?dist}
Summary: System Security Services Daemon
License: GPLv3+
@ -34,14 +34,9 @@ URL: https://github.com/SSSD/sssd/
Source0: https://github.com/SSSD/sssd/releases/download/%{version}/sssd-%{version}.tar.gz
### Patches ###
Patch0001: 0001-spec-change-passkey_child-owner.patch
Patch0002: 0002-sysdb-do-not-fail-to-add-non-posix-user-to-MPG-domai.patch
Patch0003: 0003-ad-use-right-memory-context-in-GPO-code.patch
Patch0004: 0004-TS_CACHE-never-try-to-upgrade-timestamps-cache.patch
Patch0005: 0005-SYSDB-remove-index-on-dataExpireTimestamp.patch
Patch0006: 0006-pam_sss-fix-passthrow-of-old-authtok-from-another-pa.patch
Patch0007: 0007-krb5_child-do-not-try-passwords-with-OTP.patch
Patch0008: 0008-pam_sss-add-missing-optional-2nd-factor-handling.patch
Patch0001: 0001-SYSDB-Use-SYSDB_NAME-from-cached-entry-when-updating.patch
Patch0002: 0002-KCM-fix-memory-leak.patch
Patch0003: 0003-KCM-another-memory-leak-fixed.patch
### Dependencies ###
@ -1091,6 +1086,28 @@ fi
%systemd_postun_with_restart sssd.service
%changelog
* Wed Feb 12 2025 Alexey Tikhonov <atikhono@redhat.com> - 2.9.6-4
- Resolves: RHEL-78253 - 'sssd_kcm' leaks memory [rhel-9]
* Mon Feb 10 2025 Alexey Tikhonov <atikhono@redhat.com> - 2.9.6-3
- Resolves: RHEL-78253 - 'sssd_kcm' leaks memory [rhel-9]
* Tue Jan 14 2025 Alexey Tikhonov <atikhono@redhat.com> - 2.9.6-2
- Resolves: RHEL-73400 - Use the DN from existing entry when updating a cached group [rhel-9]
* Thu Dec 5 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.6-1
- Resolves: RHEL-70189 - Rebase SSSD for RHEL 9.6
- Resolves: RHEL-67670 - Label DP_OPT_DYNDNS_REFRESH_OFFSET has no corresponding option [rhel-9]
- Resolves: RHEL-68369 - sssd backend process segfaults when krb5.conf is invalid
- Resolves: RHEL-66266 - SSSD needs an option to indicate if the LDAP server can run the exop with an anonymous bind or not [rhel-9]
* Mon Oct 21 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.5-5
- Related: RHEL-59788 - Rebase Samba to the latest 4.21.x release
* Tue Sep 24 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.5-4.1
- Resolves: RHEL-59876 - EL9/CentOS Stream 9 lost offline smart card authentication
- Resolves: RHEL-50912 - possible regression of rhbz#2196521
* Thu Jul 18 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.5-4
- Resolves: RHEL-49711 - SYSDB: remove index on dataExpireTimestamp
- Resolves: RHEL-49811 - 2FA is being enforced after upgrading 2.9.1->2.9.4