Resolves: RHEL-49711 - SYSDB: remove index on dataExpireTimestamp
Resolves: RHEL-49811 - 2FA is being enforced after upgrading 2.9.1->2.9.4
This commit is contained in:
parent
510ddf8166
commit
9fd0c37b6b
208
0004-TS_CACHE-never-try-to-upgrade-timestamps-cache.patch
Normal file
208
0004-TS_CACHE-never-try-to-upgrade-timestamps-cache.patch
Normal file
@ -0,0 +1,208 @@
|
||||
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
|
||||
|
147
0005-SYSDB-remove-index-on-dataExpireTimestamp.patch
Normal file
147
0005-SYSDB-remove-index-on-dataExpireTimestamp.patch
Normal file
@ -0,0 +1,147 @@
|
||||
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
|
||||
|
115
0006-pam_sss-fix-passthrow-of-old-authtok-from-another-pa.patch
Normal file
115
0006-pam_sss-fix-passthrow-of-old-authtok-from-another-pa.patch
Normal file
@ -0,0 +1,115 @@
|
||||
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
|
||||
|
178
0007-krb5_child-do-not-try-passwords-with-OTP.patch
Normal file
178
0007-krb5_child-do-not-try-passwords-with-OTP.patch
Normal file
@ -0,0 +1,178 @@
|
||||
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
|
||||
|
45
0008-pam_sss-add-missing-optional-2nd-factor-handling.patch
Normal file
45
0008-pam_sss-add-missing-optional-2nd-factor-handling.patch
Normal file
@ -0,0 +1,45 @@
|
||||
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
|
||||
|
11
sssd.spec
11
sssd.spec
@ -27,7 +27,7 @@
|
||||
|
||||
Name: sssd
|
||||
Version: 2.9.5
|
||||
Release: 3%{?dist}
|
||||
Release: 4%{?dist}
|
||||
Summary: System Security Services Daemon
|
||||
License: GPLv3+
|
||||
URL: https://github.com/SSSD/sssd/
|
||||
@ -37,6 +37,11 @@ Source0: https://github.com/SSSD/sssd/releases/download/%{version}/sssd-%{versio
|
||||
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
|
||||
|
||||
### Dependencies ###
|
||||
|
||||
@ -1086,6 +1091,10 @@ fi
|
||||
%systemd_postun_with_restart sssd.service
|
||||
|
||||
%changelog
|
||||
* 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
|
||||
|
||||
* Mon Jul 8 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.5-3
|
||||
- Resolves: RHEL-40742 - passkey_child with wrong owner
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user