Merge branch 'c9' into a9

This commit is contained in:
eabdullin 2024-07-24 13:36:32 +03:00
commit 51402632cc
36 changed files with 1966 additions and 4126 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/sssd-2.9.1.tar.gz SOURCES/sssd-2.9.4.tar.gz

View File

@ -1 +1 @@
5eb0d3e600aed685a7e3ea49154dadef52361f84 SOURCES/sssd-2.9.1.tar.gz 574f6cec9ee12dd943e4305286845343ab7bb891 SOURCES/sssd-2.9.4.tar.gz

View File

@ -0,0 +1,144 @@
From dd0f63246aa75d5f53b44cbc185e88833e79976e Mon Sep 17 00:00:00 2001
From: Andre Boscatto <andreboscatto@gmail.com>
Date: Wed, 7 Feb 2024 12:28:28 +0100
Subject: [PATCH] sssd: adding mail as case insensitive
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves: https://github.com/SSSD/sssd/issues/7173
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
(cherry picked from commit 945cebcf72ef53ea0368f19c09e710f7fff11b51)
---
src/db/sysdb_init.c | 7 ++++++
src/db/sysdb_private.h | 5 +++-
src/db/sysdb_upgrade.c | 56 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/src/db/sysdb_init.c b/src/db/sysdb_init.c
index c2ea6c369..38a9cd64a 100644
--- a/src/db/sysdb_init.c
+++ b/src/db/sysdb_init.c
@@ -603,6 +603,13 @@ static errno_t sysdb_domain_cache_upgrade(TALLOC_CTX *mem_ctx,
}
}
+ if (strcmp(version, SYSDB_VERSION_0_23) == 0) {
+ ret = sysdb_upgrade_23(sysdb, &version);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
ret = EOK;
done:
sysdb->ldb = save_ldb;
diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h
index 1f55007bc..63f7b5601 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_24 "0.24"
#define SYSDB_VERSION_0_23 "0.23"
#define SYSDB_VERSION_0_22 "0.22"
#define SYSDB_VERSION_0_21 "0.21"
@@ -47,7 +48,7 @@
#define SYSDB_VERSION_0_2 "0.2"
#define SYSDB_VERSION_0_1 "0.1"
-#define SYSDB_VERSION SYSDB_VERSION_0_23
+#define SYSDB_VERSION SYSDB_VERSION_0_24
#define SYSDB_BASE_LDIF \
"dn: @ATTRIBUTES\n" \
@@ -60,6 +61,7 @@
"objectclass: CASE_INSENSITIVE\n" \
"ipHostNumber: CASE_INSENSITIVE\n" \
"ipNetworkNumber: CASE_INSENSITIVE\n" \
+ "mail: CASE_INSENSITIVE\n" \
"\n" \
"dn: @INDEXLIST\n" \
"@IDXATTR: cn\n" \
@@ -191,6 +193,7 @@ int sysdb_upgrade_19(struct sysdb_ctx *sysdb, const char **ver);
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_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 346a1cb0b..56083e6be 100644
--- a/src/db/sysdb_upgrade.c
+++ b/src/db/sysdb_upgrade.c
@@ -2718,6 +2718,62 @@ done:
return ret;
}
+int sysdb_upgrade_23(struct sysdb_ctx *sysdb, const char **ver)
+{
+ TALLOC_CTX *tmp_ctx;
+ int ret;
+ struct ldb_message *msg;
+ struct upgrade_ctx *ctx;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_24, &ctx);
+ if (ret) {
+ return ret;
+ }
+
+ /* Add new indexes */
+ msg = ldb_msg_new(tmp_ctx);
+ if (!msg) {
+ ret = ENOMEM;
+ goto done;
+ }
+ msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES");
+ if (!msg->dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ /* Case insensitive search for mail */
+ ret = ldb_msg_add_empty(msg, SYSDB_USER_EMAIL, LDB_FLAG_MOD_ADD, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = ENOMEM;
+ goto done;
+ }
+ ret = ldb_msg_add_string(msg, SYSDB_USER_EMAIL, "CASE_INSENSITIVE");
+ 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);
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver)
{
struct upgrade_ctx *ctx;
--
2.41.0

View File

@ -1,106 +0,0 @@
From 2cd5a6a2c8fd1826177d6bb51e7d4f4ad368bcfb Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 9 Jun 2023 12:31:39 +0200
Subject: [PATCH 1/2] watchdog: add arm_watchdog() and disarm_watchdog() calls
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Those two new calls can be used if there are requests stuck by e.g.
waiting on replies where there is no other way to handle the timeout and
get the system back into a stable state. They should be only used as a
last resort.
Resolves: https://github.com/SSSD/sssd/issues/6803
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 75f2b35ad3b9256de905d05c5108400d35688554)
---
src/util/util.h | 12 ++++++++++++
src/util/util_watchdog.c | 28 ++++++++++++++++++++++++++--
2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/src/util/util.h b/src/util/util.h
index a8356e0cd..9dbcf3301 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -756,6 +756,18 @@ int setup_watchdog(struct tevent_context *ev, int interval);
void teardown_watchdog(void);
int get_watchdog_ticks(void);
+/* The arm_watchdog() and disarm_watchdog() calls will disable and re-enable
+ * the watchdog reset, respectively. This means that after arm_watchdog() is
+ * called the watchdog will not be resetted anymore and it will kill the
+ * process if disarm_watchdog() wasn't called before.
+ * Those calls should only be used when there is no other way to handle
+ * waiting request and recover into a stable state.
+ * Those calls cannot be nested, i.e. after calling arm_watchdog() it should
+ * not be called a second time in a different request because then
+ * disarm_watchdog() will disable the watchdog coverage for both. */
+void arm_watchdog(void);
+void disarm_watchdog(void);
+
/* from files.c */
int sss_remove_tree(const char *root);
int sss_remove_subtree(const char *root);
diff --git a/src/util/util_watchdog.c b/src/util/util_watchdog.c
index b1534e499..abafd94b9 100644
--- a/src/util/util_watchdog.c
+++ b/src/util/util_watchdog.c
@@ -40,6 +40,7 @@ struct watchdog_ctx {
time_t timestamp;
struct tevent_fd *tfd;
int pipefd[2];
+ bool armed; /* if 'true' ticks counter will not be reset */
} watchdog_ctx;
static void watchdog_detect_timeshift(void)
@@ -89,8 +90,13 @@ static void watchdog_event_handler(struct tevent_context *ev,
struct timeval current_time,
void *private_data)
{
- /* first thing reset the watchdog ticks */
- watchdog_reset();
+ if (!watchdog_ctx.armed) {
+ /* first thing reset the watchdog ticks */
+ watchdog_reset();
+ } else {
+ DEBUG(SSSDBG_IMPORTANT_INFO,
+ "Watchdog armed, process might be terminated soon.\n");
+ }
/* then set a new watchodg event */
watchdog_ctx.te = tevent_add_timer(ev, ev,
@@ -197,6 +203,7 @@ int setup_watchdog(struct tevent_context *ev, int interval)
watchdog_ctx.ev = ev;
watchdog_ctx.input_interval = interval;
watchdog_ctx.timestamp = time(NULL);
+ watchdog_ctx.armed = false;
ret = pipe(watchdog_ctx.pipefd);
if (ret == -1) {
@@ -264,3 +271,20 @@ int get_watchdog_ticks(void)
{
return __sync_add_and_fetch(&watchdog_ctx.ticks, 0);
}
+
+void arm_watchdog(void)
+{
+ if (watchdog_ctx.armed) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "arm_watchdog() is called although the watchdog is already armed. "
+ "This indicates a programming error and should be avoided because "
+ "it will most probably not work as expected.\n");
+ }
+
+ watchdog_ctx.armed = true;
+}
+
+void disarm_watchdog(void)
+{
+ watchdog_ctx.armed = false;
+}
--
2.38.1

View File

@ -1,53 +0,0 @@
From 55564defec8fdbb4d9df6b0124a8b18b31743230 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 9 Jun 2023 13:01:47 +0200
Subject: [PATCH 2/2] sbus: arm watchdog for sbus_connect_init_send()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There seem to be conditions where the reply in the
sbus_call_DBus_Hello_send() request gets lost and the backend cannot
properly initialize its sbus/DBus server. Since the backend cannot be
connected by the frontends in this state the best way to recover would
be a restart. Since the event-loop is active in this state, e.g. waiting
for the reply, the watchdog will not consider the process as hung and
will not restart the process.
To make the watchdog handle this case arm_watchdog() and
disarm_watchdog() are called before and after the request, respectively.
Resolves: https://github.com/SSSD/sssd/issues/6803
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit cca9361d92501e0be34d264d370fe897a0c970af)
---
src/sbus/connection/sbus_connection_connect.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/sbus/connection/sbus_connection_connect.c b/src/sbus/connection/sbus_connection_connect.c
index 45a0fa491..edc090e15 100644
--- a/src/sbus/connection/sbus_connection_connect.c
+++ b/src/sbus/connection/sbus_connection_connect.c
@@ -67,6 +67,8 @@ sbus_connect_init_send(TALLOC_CTX *mem_ctx,
tevent_req_set_callback(subreq, sbus_connect_init_hello_done, req);
+ arm_watchdog();
+
return req;
}
@@ -111,6 +113,8 @@ static void sbus_connect_init_done(struct tevent_req *subreq)
uint32_t res;
errno_t ret;
+ disarm_watchdog();
+
req = tevent_req_callback_data(subreq, struct tevent_req);
ret = sbus_call_DBus_RequestName_recv(subreq, &res);
--
2.38.1

View File

@ -0,0 +1,154 @@
From a7621a5b464af7a3c8409dcbde038b35fee2c895 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 23 Jan 2024 13:47:53 +0100
Subject: [PATCH 2/3] sdap: add search_bases option to groups_by_user_send()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
AD handles users and computer objects very similar and so does SSSD's
GPO code when lookup up the host's group-memberships. But users and
computers might be stored in different sub-tree of the AD LDAP tree and
if a dedicated user search base is given with the ldap_user_search_base
option in sssd.conf the host object might be in a different sub-tree. To
make sure the host can still be found this patch uses the base DN of
the LDAP tree when searching for hosts in the GPO code.
Resolves: https://github.com/SSSD/sssd/issues/5708
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
(cherry picked from commit 29a77c6e79020d7e8cb474b4d3b394d390eba196)
---
src/providers/ad/ad_gpo.c | 10 ++++++++++
src/providers/ldap/ldap_common.h | 1 +
src/providers/ldap/ldap_id.c | 6 +++++-
src/providers/ldap/sdap_async.h | 1 +
src/providers/ldap/sdap_async_initgroups.c | 4 +++-
5 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index 94959c36b..b0ee3e616 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -2091,6 +2091,7 @@ ad_gpo_connect_done(struct tevent_req *subreq)
char *server_uri;
LDAPURLDesc *lud;
struct sdap_domain *sdom;
+ struct sdap_search_base **search_bases;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct ad_gpo_access_state);
@@ -2184,9 +2185,18 @@ ad_gpo_connect_done(struct tevent_req *subreq)
goto done;
}
+ ret = common_parse_search_base(state, sdom->basedn, state->ldb_ctx,
+ "AD_HOSTS", NULL, &search_bases);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failed to create dedicated search base for host lookups, "
+ "trying with user search base.");
+ }
+
subreq = groups_by_user_send(state, state->ev,
state->access_ctx->ad_id_ctx->sdap_id_ctx,
sdom, state->conn,
+ search_bases,
state->host_fqdn,
BE_FILTER_NAME,
NULL,
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 7159d6356..2c984ef50 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -304,6 +304,7 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
struct sdap_id_ctx *ctx,
struct sdap_domain *sdom,
struct sdap_id_conn_ctx *conn,
+ struct sdap_search_base **search_bases,
const char *filter_value,
int filter_type,
const char *extra_value,
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index da54816bd..b3ea2333f 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -1139,6 +1139,7 @@ struct groups_by_user_state {
struct sdap_id_op *op;
struct sysdb_ctx *sysdb;
struct sss_domain_info *domain;
+ struct sdap_search_base **search_bases;
const char *filter_value;
int filter_type;
@@ -1160,6 +1161,7 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
struct sdap_id_ctx *ctx,
struct sdap_domain *sdom,
struct sdap_id_conn_ctx *conn,
+ struct sdap_search_base **search_bases,
const char *filter_value,
int filter_type,
const char *extra_value,
@@ -1192,6 +1194,7 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
state->extra_value = extra_value;
state->domain = sdom->dom;
state->sysdb = sdom->dom->sysdb;
+ state->search_bases = search_bases;
if (state->domain->type == DOM_TYPE_APPLICATION || set_non_posix) {
state->non_posix = true;
@@ -1254,6 +1257,7 @@ static void groups_by_user_connect_done(struct tevent_req *subreq)
sdap_id_op_handle(state->op),
state->ctx,
state->conn,
+ state->search_bases,
state->filter_value,
state->filter_type,
state->extra_value,
@@ -1449,7 +1453,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
}
subreq = groups_by_user_send(state, be_ctx->ev, id_ctx,
- sdom, conn,
+ sdom, conn, NULL,
ar->filter_value,
ar->filter_type,
ar->extra_value,
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index 5458d21f1..89245f41f 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -158,6 +158,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
struct sdap_handle *sh,
struct sdap_id_ctx *id_ctx,
struct sdap_id_conn_ctx *conn,
+ struct sdap_search_base **search_bases,
const char *name,
int filter_type,
const char *extra_value,
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 97be594a3..fb3d8fe24 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2732,6 +2732,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
struct sdap_handle *sh,
struct sdap_id_ctx *id_ctx,
struct sdap_id_conn_ctx *conn,
+ struct sdap_search_base **search_bases,
const char *filter_value,
int filter_type,
const char *extra_value,
@@ -2764,7 +2765,8 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
state->orig_user = NULL;
state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT);
state->user_base_iter = 0;
- state->user_search_bases = sdom->user_search_bases;
+ state->user_search_bases = (search_bases == NULL) ? sdom->user_search_bases
+ : search_bases;
if (!state->user_search_bases) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Initgroups lookup request without a user search base\n");
--
2.41.0

View File

@ -1,220 +0,0 @@
From 641e5f73d3bd5b3d32cafd551013d3bfd2a52732 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 4 Aug 2023 12:19:49 +0200
Subject: [PATCH] mc: recover from invalid memory cache size
If we access the mmap file outside its boundaries a SIGBUS is raised.
We can now safely recover if the file has unexpected size.
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/responder/nss/nsssrv_mmap_cache.c | 86 +++++++++++++++++----
src/sss_client/nss_mc_common.c | 42 +++++++---
src/tests/system/tests/test_memory_cache.py | 36 ++++++++-
3 files changed, 135 insertions(+), 29 deletions(-)
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index 12c2996596..bd814f3bc7 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -722,6 +722,57 @@ static errno_t sss_mmap_cache_invalidate(struct sss_mc_ctx *mcc,
return EOK;
}
+static errno_t sss_mmap_cache_validate_or_reinit(struct sss_mc_ctx **_mcc)
+{
+ struct sss_mc_ctx *mcc = *_mcc;
+ struct stat fdstat;
+ bool reinit = false;
+ errno_t ret;
+
+ /* No mcc initialized? Memory cache may be disabled. */
+ if (mcc == NULL || mcc->fd < 0) {
+ ret = EINVAL;
+ reinit = false;
+ goto done;
+ }
+
+ if (fstat(mcc->fd, &fdstat) == -1) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Unable to stat memory cache [file=%s, fd=%d] [%d]: %s\n",
+ mcc->file, mcc->fd, ret, sss_strerror(ret));
+ reinit = true;
+ goto done;
+ }
+
+ if (fdstat.st_nlink == 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Memory cache file was removed\n");
+ ret = ENOENT;
+ reinit = true;
+ goto done;
+ }
+
+ if (fdstat.st_size != mcc->mmap_size) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Memory cache is corrupted, invalid size [file=%s, fd=%d, "
+ "expected_size=%zu, real_size=%zu]\n",
+ mcc->file, mcc->fd, mcc->mmap_size, fdstat.st_size);
+ ret = EINVAL;
+ reinit = true;
+ goto done;
+ }
+
+ ret = EOK;
+ reinit = false;
+
+done:
+ if (reinit) {
+ return sss_mmap_cache_reinit(talloc_parent(mcc), -1, -1, -1, -1, _mcc);
+ }
+
+ return ret;
+}
+
/***************************************************************************
* passwd map
***************************************************************************/
@@ -744,9 +795,9 @@ errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc,
size_t pos;
int ret;
- if (mcc == NULL) {
- /* cache not initialized? */
- return EINVAL;
+ ret = sss_mmap_cache_validate_or_reinit(&mcc);
+ if (ret != EOK) {
+ return ret;
}
ret = snprintf(uidstr, 11, "%ld", (long)uid);
@@ -815,9 +866,9 @@ errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid)
char *uidstr;
errno_t ret;
- if (mcc == NULL) {
- /* cache not initialized? */
- return EINVAL;
+ ret = sss_mmap_cache_validate_or_reinit(&mcc);
+ if (ret != EOK) {
+ return ret;
}
uidstr = talloc_asprintf(NULL, "%ld", (long)uid);
@@ -886,9 +937,9 @@ int sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc,
size_t pos;
int ret;
- if (mcc == NULL) {
- /* cache not initialized? */
- return EINVAL;
+ ret = sss_mmap_cache_validate_or_reinit(&mcc);
+ if (ret != EOK) {
+ return ret;
}
ret = snprintf(gidstr, 11, "%ld", (long)gid);
@@ -953,9 +1004,9 @@ errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid)
char *gidstr;
errno_t ret;
- if (mcc == NULL) {
- /* cache not initialized? */
- return EINVAL;
+ ret = sss_mmap_cache_validate_or_reinit(&mcc);
+ if (ret != EOK) {
+ return ret;
}
gidstr = talloc_asprintf(NULL, "%ld", (long)gid);
@@ -1018,9 +1069,9 @@ errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc,
size_t pos;
int ret;
- if (mcc == NULL) {
- /* cache not initialized? */
- return EINVAL;
+ ret = sss_mmap_cache_validate_or_reinit(&mcc);
+ if (ret != EOK) {
+ return ret;
}
/* array of gids + name + unique_name */
@@ -1087,8 +1138,9 @@ errno_t sss_mmap_cache_sid_store(struct sss_mc_ctx **_mcc,
size_t rec_len;
int ret;
- if (mcc == NULL) {
- return EINVAL;
+ ret = sss_mmap_cache_validate_or_reinit(&mcc);
+ if (ret != EOK) {
+ return ret;
}
ret = snprintf(idkey, sizeof(idkey), "%d-%ld",
diff --git a/src/sss_client/nss_mc_common.c b/src/sss_client/nss_mc_common.c
index 3128861bf3..e227c0bae3 100644
--- a/src/sss_client/nss_mc_common.c
+++ b/src/sss_client/nss_mc_common.c
@@ -69,13 +69,43 @@ static void sss_mt_unlock(struct sss_cli_mc_ctx *ctx)
#endif
}
+static errno_t sss_nss_mc_validate(struct sss_cli_mc_ctx *ctx)
+{
+ struct stat fdstat;
+
+ /* No mc ctx initialized?*/
+ if (ctx == NULL || ctx->fd < 0) {
+ return EINVAL;
+ }
+
+ if (fstat(ctx->fd, &fdstat) == -1) {
+ return errno;
+ }
+
+ /* Memcache was removed. */
+ if (fdstat.st_nlink == 0) {
+ return ENOENT;
+ }
+
+ /* Invalid size. */
+ if (fdstat.st_size != ctx->mmap_size) {
+ return ERANGE;
+ }
+
+ return EOK;
+}
+
errno_t sss_nss_check_header(struct sss_cli_mc_ctx *ctx)
{
struct sss_mc_header h;
bool copy_ok;
int count;
int ret;
- struct stat fdstat;
+
+ ret = sss_nss_mc_validate(ctx);
+ if (ret != EOK) {
+ return ret;
+ }
/* retry barrier protected reading max 5 times then give up */
for (count = 5; count > 0; count--) {
@@ -115,16 +145,6 @@ errno_t sss_nss_check_header(struct sss_cli_mc_ctx *ctx)
}
}
- ret = fstat(ctx->fd, &fdstat);
- if (ret == -1) {
- return EIO;
- }
-
- if (fdstat.st_nlink == 0) {
- /* memory cache was removed; we need to reinitialize it. */
- return EINVAL;
- }
-
return 0;
}

View File

@ -0,0 +1,194 @@
From 6a8e60df84d5d2565bec36be19c2def25a6ece1f Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 24 Jan 2024 14:21:12 +0100
Subject: [PATCH 3/3] sdap: add naming_context as new member of struct
sdap_domain
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The naming_context could be a more reliable source than basedn for the
actual base DN because basedn is set very early from the domain name
given in sssd.conf. Although it is recommended to use the fully
qualified DNS domain name here it is not required. As a result basedn
might not reflect the actual based DN of the LDAP server. Also pure LDAP
server (i.e. not AD or FreeIPA) might use different schemes to set the
base DN which will not be based on the DNS domain of the LDAP server.
Resolves: https://github.com/SSSD/sssd/issues/5708
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
(cherry picked from commit a153f13f296401247a862df2b99048bb1bbb8e2e)
---
src/providers/ad/ad_gpo.c | 6 ++++--
src/providers/ldap/sdap.c | 36 +++++++++++++-----------------------
src/providers/ldap/sdap.h | 11 +++++++++++
3 files changed, 28 insertions(+), 25 deletions(-)
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index b0ee3e616..3d1ad39c7 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -2185,8 +2185,10 @@ ad_gpo_connect_done(struct tevent_req *subreq)
goto done;
}
- ret = common_parse_search_base(state, sdom->basedn, state->ldb_ctx,
- "AD_HOSTS", NULL, &search_bases);
+ ret = common_parse_search_base(state,
+ sdom->naming_context == NULL ? sdom->basedn
+ : sdom->naming_context,
+ state->ldb_ctx, "AD_HOSTS", NULL, &search_bases);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"Failed to create dedicated search base for host lookups, "
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index f5637c5fb..956eba93a 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -1252,19 +1252,10 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse,
struct sdap_domain *sdom)
{
int ret;
- char *naming_context = NULL;
- if (!sdom->search_bases
- || !sdom->user_search_bases
- || !sdom->group_search_bases
- || !sdom->netgroup_search_bases
- || !sdom->host_search_bases
- || !sdom->sudo_search_bases
- || !sdom->iphost_search_bases
- || !sdom->ipnetwork_search_bases
- || !sdom->autofs_search_bases) {
- naming_context = get_naming_context(opts->basic, rootdse);
- if (naming_context == NULL) {
+ if (!sdom->naming_context) {
+ sdom->naming_context = get_naming_context(sdom, rootdse);
+ if (sdom->naming_context == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "get_naming_context failed.\n");
/* This has to be non-fatal, since some servers offer
@@ -1280,7 +1271,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse,
if (!sdom->search_bases) {
ret = sdap_set_search_base(opts, sdom,
SDAP_SEARCH_BASE,
- naming_context);
+ sdom->naming_context);
if (ret != EOK) goto done;
}
@@ -1288,7 +1279,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse,
if (!sdom->user_search_bases) {
ret = sdap_set_search_base(opts, sdom,
SDAP_USER_SEARCH_BASE,
- naming_context);
+ sdom->naming_context);
if (ret != EOK) goto done;
}
@@ -1296,7 +1287,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse,
if (!sdom->group_search_bases) {
ret = sdap_set_search_base(opts, sdom,
SDAP_GROUP_SEARCH_BASE,
- naming_context);
+ sdom->naming_context);
if (ret != EOK) goto done;
}
@@ -1304,7 +1295,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse,
if (!sdom->netgroup_search_bases) {
ret = sdap_set_search_base(opts, sdom,
SDAP_NETGROUP_SEARCH_BASE,
- naming_context);
+ sdom->naming_context);
if (ret != EOK) goto done;
}
@@ -1312,7 +1303,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse,
if (!sdom->host_search_bases) {
ret = sdap_set_search_base(opts, sdom,
SDAP_HOST_SEARCH_BASE,
- naming_context);
+ sdom->naming_context);
if (ret != EOK) goto done;
}
@@ -1320,7 +1311,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse,
if (!sdom->sudo_search_bases) {
ret = sdap_set_search_base(opts, sdom,
SDAP_SUDO_SEARCH_BASE,
- naming_context);
+ sdom->naming_context);
if (ret != EOK) goto done;
}
@@ -1328,7 +1319,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse,
if (!sdom->service_search_bases) {
ret = sdap_set_search_base(opts, sdom,
SDAP_SERVICE_SEARCH_BASE,
- naming_context);
+ sdom->naming_context);
if (ret != EOK) goto done;
}
@@ -1336,7 +1327,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse,
if (!sdom->autofs_search_bases) {
ret = sdap_set_search_base(opts, sdom,
SDAP_AUTOFS_SEARCH_BASE,
- naming_context);
+ sdom->naming_context);
if (ret != EOK) goto done;
}
@@ -1344,7 +1335,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse,
if (!sdom->iphost_search_bases) {
ret = sdap_set_search_base(opts, sdom,
SDAP_IPHOST_SEARCH_BASE,
- naming_context);
+ sdom->naming_context);
if (ret != EOK) goto done;
}
@@ -1352,14 +1343,13 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse,
if (!sdom->ipnetwork_search_bases) {
ret = sdap_set_search_base(opts, sdom,
SDAP_IPNETWORK_SEARCH_BASE,
- naming_context);
+ sdom->naming_context);
if (ret != EOK) goto done;
}
ret = EOK;
done:
- talloc_free(naming_context);
return ret;
}
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 161bc5c26..103d50ed4 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -454,6 +454,17 @@ struct sdap_domain {
char *basedn;
+ /* The naming_context could be a more reliable source than basedn for the
+ * actual base DN because basedn is set very early from the domain name
+ * given in sssd.conf. Although it is recommended to use the fully
+ * qualified DNS domain name here it is not required. As a result basedn
+ * might not reflect the actual based DN of the LDAP server. Also pure
+ * LDAP server (i.e. not AD or FreeIPA) might use different schemes to set
+ * the base DN which will not be based on the DNS domain of the LDAP
+ * server. naming_context might be NULL even after connection to an LDAP
+ * server. */
+ char *naming_context;
+
struct sdap_search_base **search_bases;
struct sdap_search_base **user_search_bases;
struct sdap_search_base **group_search_bases;
--
2.41.0

View File

@ -0,0 +1,233 @@
From 50077c3255177fe1b01837fbe31a7f8fd47dee74 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 18 Jan 2024 13:08:17 +0100
Subject: [PATCH] pam: fix SC auth with multiple certs and missing login name
While introducing the local_auth_policy option a quite specific use-case
was not covered correctly. If there are multiple matching certificates
on the Smartcard, 'local_auth_policy = only' is set and GDM's Smartcard
mode was used for login, i.e. there is no user name given and the user
has to be derived from the certificate used for login, authentication
failed. The main reason for the failure is that in this case the
Smartcard interaction and the user mapping has to be done first to
determine the user before local_auth_policy is evaluated. As a result
when checking if the authentication can be finished the request was in
an unexpected state because the indicator for local Smartcard
authentication was not enabled.
Resolves: https://github.com/SSSD/sssd/issues/7109
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
Reviewed-by: Scott Poore <spoore@redhat.com>
(cherry picked from commit 44ec3e4638b0c6f7f45a3390a28c2e8745d52bc3)
---
src/responder/pam/pamsrv.h | 10 ++++
src/responder/pam/pamsrv_cmd.c | 17 +++++--
src/tests/intg/Makefile.am | 2 +
src/tests/intg/test_pam_responder.py | 74 +++++++++++++++++++++++++++-
4 files changed, 96 insertions(+), 7 deletions(-)
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
index 7013a8edd..618836189 100644
--- a/src/responder/pam/pamsrv.h
+++ b/src/responder/pam/pamsrv.h
@@ -93,7 +93,17 @@ struct pam_auth_req {
struct ldb_message *user_obj;
struct cert_auth_info *cert_list;
struct cert_auth_info *current_cert;
+ /* Switched to 'true' if the backend indicates that it cannot handle
+ * Smartcard authentication, but Smartcard authentication is
+ * possible and local Smartcard authentication is allowed. */
bool cert_auth_local;
+ /* Switched to 'true' if authentication (not pre-authentication) was
+ * started without a login name and the name had to be lookup up with the
+ * certificate used for authentication. Since reading the certificate from
+ * the Smartcard already involves the PIN validation in this case there
+ * would be no need for an additional Smartcard interaction if only local
+ * Smartcard authentication is possible. */
+ bool initial_cert_auth_successful;
bool passkey_data_exists;
uint32_t client_id_num;
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index c23ea7ba4..a7c181733 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -2200,8 +2200,8 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req)
ret = ENOENT;
goto done;
}
-
- if (cert_count > 1) {
+ /* Multiple certificates are only expected during pre-auth */
+ if (cert_count > 1 && preq->pd->cmd == SSS_PAM_PREAUTH) {
for (preq->current_cert = preq->cert_list;
preq->current_cert != NULL;
preq->current_cert = sss_cai_get_next(preq->current_cert)) {
@@ -2285,7 +2285,9 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req)
}
/* If logon_name was not given during authentication add a
- * SSS_PAM_CERT_INFO message to send the name to the caller. */
+ * SSS_PAM_CERT_INFO message to send the name to the caller.
+ * Additionally initial_cert_auth_successful is set to
+ * indicate that the user is already authenticated. */
if (preq->pd->cmd == SSS_PAM_AUTHENTICATE
&& preq->pd->logon_name == NULL) {
ret = add_pam_cert_response(preq->pd,
@@ -2297,6 +2299,8 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req)
preq->pd->pam_status = PAM_AUTHINFO_UNAVAIL;
goto done;
}
+
+ preq->initial_cert_auth_successful = true;
}
/* cert_user will be returned to the PAM client as user name, so
@@ -2851,12 +2855,15 @@ static void pam_dom_forwarder(struct pam_auth_req *preq)
if (found) {
if (local_policy != NULL && strcasecmp(local_policy, "only") == 0) {
talloc_free(tmp_ctx);
- DEBUG(SSSDBG_IMPORTANT_INFO, "Local auth only set, skipping online auth\n");
+ DEBUG(SSSDBG_IMPORTANT_INFO,
+ "Local auth only set and matching certificate was found, "
+ "skipping online auth\n");
if (preq->pd->cmd == SSS_PAM_PREAUTH) {
preq->pd->pam_status = PAM_SUCCESS;
} else if (preq->pd->cmd == SSS_PAM_AUTHENTICATE
&& IS_SC_AUTHTOK(preq->pd->authtok)
- && preq->cert_auth_local) {
+ && (preq->cert_auth_local
+ || preq->initial_cert_auth_successful)) {
preq->pd->pam_status = PAM_SUCCESS;
preq->callback = pam_reply;
}
diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am
index 3866d3ca6..0cfd268dc 100644
--- a/src/tests/intg/Makefile.am
+++ b/src/tests/intg/Makefile.am
@@ -199,6 +199,7 @@ clean-local:
PAM_CERT_DB_PATH="$(abs_builddir)/../test_CA/SSSD_test_CA.pem"
SOFTHSM2_CONF="$(abs_builddir)/../test_CA/softhsm2_one.conf"
+SOFTHSM2_TWO_CONF="$(abs_builddir)/../test_CA/softhsm2_two.conf"
intgcheck-installed: config.py passwd group pam_sss_service pam_sss_alt_service pam_sss_sc_required pam_sss_try_sc pam_sss_allow_missing_name pam_sss_domains sss_netgroup_thread_test
pipepath="$(DESTDIR)$(pipepath)"; \
@@ -233,6 +234,7 @@ intgcheck-installed: config.py passwd group pam_sss_service pam_sss_alt_service
PAM_CERT_DB_PATH=$(PAM_CERT_DB_PATH) \
ABS_SRCDIR=$(abs_srcdir) \
SOFTHSM2_CONF=$(SOFTHSM2_CONF) \
+ SOFTHSM2_TWO_CONF=$(SOFTHSM2_TWO_CONF) \
KCM_RENEW=$(KCM_RENEW) \
FILES_PROVIDER=$(FILES_PROVIDER) \
DBUS_SOCK_DIR="$(DESTDIR)$(runstatedir)/dbus/" \
diff --git a/src/tests/intg/test_pam_responder.py b/src/tests/intg/test_pam_responder.py
index 1fc3937e6..0fbf8065e 100644
--- a/src/tests/intg/test_pam_responder.py
+++ b/src/tests/intg/test_pam_responder.py
@@ -168,7 +168,7 @@ def format_pam_cert_auth_conf(config, provider):
{provider.p}
[certmap/auth_only/user1]
- matchrule = <SUBJECT>.*CN=SSSD test cert 0001.*
+ matchrule = <SUBJECT>.*CN=SSSD test cert 000[12].*
""").format(**locals())
@@ -201,7 +201,7 @@ def format_pam_cert_auth_conf_name_format(config, provider):
{provider.p}
[certmap/auth_only/user1]
- matchrule = <SUBJECT>.*CN=SSSD test cert 0001.*
+ matchrule = <SUBJECT>.*CN=SSSD test cert 000[12].*
""").format(**locals())
@@ -380,6 +380,28 @@ def simple_pam_cert_auth_no_cert(request, passwd_ops_setup):
return None
+@pytest.fixture
+def simple_pam_cert_auth_two_certs(request, passwd_ops_setup):
+ """Setup SSSD with pam_cert_auth=True"""
+ config.PAM_CERT_DB_PATH = os.environ['PAM_CERT_DB_PATH']
+
+ old_softhsm2_conf = os.environ['SOFTHSM2_CONF']
+ softhsm2_two_conf = os.environ['SOFTHSM2_TWO_CONF']
+ os.environ['SOFTHSM2_CONF'] = softhsm2_two_conf
+
+ conf = format_pam_cert_auth_conf(config, provider_switch(request.param))
+ create_conf_fixture(request, conf)
+ create_sssd_fixture(request)
+
+ os.environ['SOFTHSM2_CONF'] = old_softhsm2_conf
+
+ passwd_ops_setup.useradd(**USER1)
+ passwd_ops_setup.useradd(**USER2)
+ sync_files_provider(USER2['name'])
+
+ return None
+
+
@pytest.fixture
def simple_pam_cert_auth_name_format(request, passwd_ops_setup):
"""Setup SSSD with pam_cert_auth=True and full_name_format"""
@@ -522,6 +544,54 @@ def test_sc_auth(simple_pam_cert_auth, env_for_sssctl):
assert err.find("pam_authenticate for user [user1]: Success") != -1
+@pytest.mark.parametrize('simple_pam_cert_auth_two_certs', provider_list(), indirect=True)
+def test_sc_auth_two(simple_pam_cert_auth_two_certs, env_for_sssctl):
+
+ sssctl = subprocess.Popen(["sssctl", "user-checks", "user1",
+ "--action=auth", "--service=pam_sss_service"],
+ universal_newlines=True,
+ env=env_for_sssctl, stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ try:
+ out, err = sssctl.communicate(input="2\n123456")
+ except Exception:
+ sssctl.kill()
+ out, err = sssctl.communicate()
+
+ sssctl.stdin.close()
+ sssctl.stdout.close()
+
+ if sssctl.wait() != 0:
+ raise Exception("sssctl failed")
+
+ assert err.find("pam_authenticate for user [user1]: Success") != -1
+
+
+@pytest.mark.parametrize('simple_pam_cert_auth_two_certs', provider_list(), indirect=True)
+def test_sc_auth_two_missing_name(simple_pam_cert_auth_two_certs, env_for_sssctl):
+
+ sssctl = subprocess.Popen(["sssctl", "user-checks", "",
+ "--action=auth", "--service=pam_sss_allow_missing_name"],
+ universal_newlines=True,
+ env=env_for_sssctl, stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ try:
+ out, err = sssctl.communicate(input="2\n123456")
+ except Exception:
+ sssctl.kill()
+ out, err = sssctl.communicate()
+
+ sssctl.stdin.close()
+ sssctl.stdout.close()
+
+ if sssctl.wait() != 0:
+ raise Exception("sssctl failed")
+
+ assert err.find("pam_authenticate for user [user1]: Success") != -1
+
+
@pytest.mark.parametrize('simple_pam_cert_auth', ['proxy_password'], indirect=True)
def test_sc_proxy_password_fallback(simple_pam_cert_auth, env_for_sssctl):
"""
--
2.41.0

View File

@ -1,400 +0,0 @@
From 1e5dfc187c7659cca567d2f7d5592e72794ef13c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Mon, 4 Sep 2023 14:12:58 +0200
Subject: [PATCH] sss_iface: do not add cli_id to chain key
Otherwise we only chain identical requests from the same client
which effectively renders chaining not functional.
Resolves: https://github.com/SSSD/sssd/issues/6911
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
---
src/sss_iface/sbus_sss_client_async.c | 12 +++----
src/sss_iface/sbus_sss_interface.h | 24 ++++++-------
src/sss_iface/sbus_sss_keygens.c | 50 +++++++++++++--------------
src/sss_iface/sbus_sss_keygens.h | 10 +++---
src/sss_iface/sss_iface.xml | 12 +++----
5 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/src/sss_iface/sbus_sss_client_async.c b/src/sss_iface/sbus_sss_client_async.c
index 042d1b7b34..5ca925283a 100644
--- a/src/sss_iface/sbus_sss_client_async.c
+++ b/src/sss_iface/sbus_sss_client_async.c
@@ -1861,7 +1861,7 @@ sbus_call_dp_autofs_Enumerate_send
const char * arg_mapname,
uint32_t arg_cli_id)
{
- return sbus_method_in_usu_out__send(mem_ctx, conn, _sbus_sss_key_usu_0_1_2,
+ return sbus_method_in_usu_out__send(mem_ctx, conn, _sbus_sss_key_usu_0_1,
busname, object_path, "sssd.DataProvider.Autofs", "Enumerate", arg_dp_flags, arg_mapname, arg_cli_id);
}
@@ -1883,7 +1883,7 @@ sbus_call_dp_autofs_GetEntry_send
const char * arg_entryname,
uint32_t arg_cli_id)
{
- return sbus_method_in_ussu_out__send(mem_ctx, conn, _sbus_sss_key_ussu_0_1_2_3,
+ return sbus_method_in_ussu_out__send(mem_ctx, conn, _sbus_sss_key_ussu_0_1_2,
busname, object_path, "sssd.DataProvider.Autofs", "GetEntry", arg_dp_flags, arg_mapname, arg_entryname, arg_cli_id);
}
@@ -1904,7 +1904,7 @@ sbus_call_dp_autofs_GetMap_send
const char * arg_mapname,
uint32_t arg_cli_id)
{
- return sbus_method_in_usu_out__send(mem_ctx, conn, _sbus_sss_key_usu_0_1_2,
+ return sbus_method_in_usu_out__send(mem_ctx, conn, _sbus_sss_key_usu_0_1,
busname, object_path, "sssd.DataProvider.Autofs", "GetMap", arg_dp_flags, arg_mapname, arg_cli_id);
}
@@ -2142,7 +2142,7 @@ sbus_call_dp_dp_getAccountDomain_send
const char * arg_filter,
uint32_t arg_cli_id)
{
- return sbus_method_in_uusu_out_qus_send(mem_ctx, conn, _sbus_sss_key_uusu_0_1_2_3,
+ return sbus_method_in_uusu_out_qus_send(mem_ctx, conn, _sbus_sss_key_uusu_0_1_2,
busname, object_path, "sssd.dataprovider", "getAccountDomain", arg_dp_flags, arg_entry_type, arg_filter, arg_cli_id);
}
@@ -2170,7 +2170,7 @@ sbus_call_dp_dp_getAccountInfo_send
const char * arg_extra,
uint32_t arg_cli_id)
{
- return sbus_method_in_uusssu_out_qus_send(mem_ctx, conn, _sbus_sss_key_uusssu_0_1_2_3_4_5,
+ return sbus_method_in_uusssu_out_qus_send(mem_ctx, conn, _sbus_sss_key_uusssu_0_1_2_3_4,
busname, object_path, "sssd.dataprovider", "getAccountInfo", arg_dp_flags, arg_entry_type, arg_filter, arg_domain, arg_extra, arg_cli_id);
}
@@ -2267,7 +2267,7 @@ sbus_call_dp_dp_resolverHandler_send
const char * arg_filter_value,
uint32_t arg_cli_id)
{
- return sbus_method_in_uuusu_out_qus_send(mem_ctx, conn, _sbus_sss_key_uuusu_0_1_2_3_4,
+ return sbus_method_in_uuusu_out_qus_send(mem_ctx, conn, _sbus_sss_key_uuusu_0_1_2_3,
busname, object_path, "sssd.dataprovider", "resolverHandler", arg_dp_flags, arg_entry_type, arg_filter_type, arg_filter_value, arg_cli_id);
}
diff --git a/src/sss_iface/sbus_sss_interface.h b/src/sss_iface/sbus_sss_interface.h
index fc86c71d90..5b4d1c362a 100644
--- a/src/sss_iface/sbus_sss_interface.h
+++ b/src/sss_iface/sbus_sss_interface.h
@@ -166,7 +166,7 @@
&_sbus_sss_args_sssd_DataProvider_Autofs_Enumerate, \
NULL, \
_sbus_sss_invoke_in_usu_out__send, \
- _sbus_sss_key_usu_0_1_2, \
+ _sbus_sss_key_usu_0_1, \
(handler), (data)); \
})
@@ -177,7 +177,7 @@
&_sbus_sss_args_sssd_DataProvider_Autofs_Enumerate, \
NULL, \
_sbus_sss_invoke_in_usu_out__send, \
- _sbus_sss_key_usu_0_1_2, \
+ _sbus_sss_key_usu_0_1, \
(handler_send), (handler_recv), (data)); \
})
@@ -188,7 +188,7 @@
&_sbus_sss_args_sssd_DataProvider_Autofs_GetEntry, \
NULL, \
_sbus_sss_invoke_in_ussu_out__send, \
- _sbus_sss_key_ussu_0_1_2_3, \
+ _sbus_sss_key_ussu_0_1_2, \
(handler), (data)); \
})
@@ -199,7 +199,7 @@
&_sbus_sss_args_sssd_DataProvider_Autofs_GetEntry, \
NULL, \
_sbus_sss_invoke_in_ussu_out__send, \
- _sbus_sss_key_ussu_0_1_2_3, \
+ _sbus_sss_key_ussu_0_1_2, \
(handler_send), (handler_recv), (data)); \
})
@@ -210,7 +210,7 @@
&_sbus_sss_args_sssd_DataProvider_Autofs_GetMap, \
NULL, \
_sbus_sss_invoke_in_usu_out__send, \
- _sbus_sss_key_usu_0_1_2, \
+ _sbus_sss_key_usu_0_1, \
(handler), (data)); \
})
@@ -221,7 +221,7 @@
&_sbus_sss_args_sssd_DataProvider_Autofs_GetMap, \
NULL, \
_sbus_sss_invoke_in_usu_out__send, \
- _sbus_sss_key_usu_0_1_2, \
+ _sbus_sss_key_usu_0_1, \
(handler_send), (handler_recv), (data)); \
})
@@ -522,7 +522,7 @@
&_sbus_sss_args_sssd_dataprovider_getAccountDomain, \
NULL, \
_sbus_sss_invoke_in_uusu_out_qus_send, \
- _sbus_sss_key_uusu_0_1_2_3, \
+ _sbus_sss_key_uusu_0_1_2, \
(handler), (data)); \
})
@@ -533,7 +533,7 @@
&_sbus_sss_args_sssd_dataprovider_getAccountDomain, \
NULL, \
_sbus_sss_invoke_in_uusu_out_qus_send, \
- _sbus_sss_key_uusu_0_1_2_3, \
+ _sbus_sss_key_uusu_0_1_2, \
(handler_send), (handler_recv), (data)); \
})
@@ -544,7 +544,7 @@
&_sbus_sss_args_sssd_dataprovider_getAccountInfo, \
NULL, \
_sbus_sss_invoke_in_uusssu_out_qus_send, \
- _sbus_sss_key_uusssu_0_1_2_3_4_5, \
+ _sbus_sss_key_uusssu_0_1_2_3_4, \
(handler), (data)); \
})
@@ -555,7 +555,7 @@
&_sbus_sss_args_sssd_dataprovider_getAccountInfo, \
NULL, \
_sbus_sss_invoke_in_uusssu_out_qus_send, \
- _sbus_sss_key_uusssu_0_1_2_3_4_5, \
+ _sbus_sss_key_uusssu_0_1_2_3_4, \
(handler_send), (handler_recv), (data)); \
})
@@ -632,7 +632,7 @@
&_sbus_sss_args_sssd_dataprovider_resolverHandler, \
NULL, \
_sbus_sss_invoke_in_uuusu_out_qus_send, \
- _sbus_sss_key_uuusu_0_1_2_3_4, \
+ _sbus_sss_key_uuusu_0_1_2_3, \
(handler), (data)); \
})
@@ -643,7 +643,7 @@
&_sbus_sss_args_sssd_dataprovider_resolverHandler, \
NULL, \
_sbus_sss_invoke_in_uuusu_out_qus_send, \
- _sbus_sss_key_uuusu_0_1_2_3_4, \
+ _sbus_sss_key_uuusu_0_1_2_3, \
(handler_send), (handler_recv), (data)); \
})
diff --git a/src/sss_iface/sbus_sss_keygens.c b/src/sss_iface/sbus_sss_keygens.c
index 1bffc1360f..0bded60f83 100644
--- a/src/sss_iface/sbus_sss_keygens.c
+++ b/src/sss_iface/sbus_sss_keygens.c
@@ -90,86 +90,86 @@ _sbus_sss_key_ussu_0_1
}
const char *
-_sbus_sss_key_ussu_0_1_2_3
+_sbus_sss_key_ussu_0_1_2
(TALLOC_CTX *mem_ctx,
struct sbus_request *sbus_req,
struct _sbus_sss_invoker_args_ussu *args)
{
if (sbus_req->sender == NULL) {
- return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%s:%s:%" PRIu32 "",
+ return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%s:%s",
sbus_req->type, sbus_req->interface, sbus_req->member,
- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3);
+ sbus_req->path, args->arg0, args->arg1, args->arg2);
}
- return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%s:%s:%" PRIu32 "",
+ return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%s:%s",
sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member,
- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3);
+ sbus_req->path, args->arg0, args->arg1, args->arg2);
}
const char *
-_sbus_sss_key_usu_0_1_2
+_sbus_sss_key_usu_0_1
(TALLOC_CTX *mem_ctx,
struct sbus_request *sbus_req,
struct _sbus_sss_invoker_args_usu *args)
{
if (sbus_req->sender == NULL) {
- return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%s:%" PRIu32 "",
+ return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%s",
sbus_req->type, sbus_req->interface, sbus_req->member,
- sbus_req->path, args->arg0, args->arg1, args->arg2);
+ sbus_req->path, args->arg0, args->arg1);
}
- return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%s:%" PRIu32 "",
+ return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%s",
sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member,
- sbus_req->path, args->arg0, args->arg1, args->arg2);
+ sbus_req->path, args->arg0, args->arg1);
}
const char *
-_sbus_sss_key_uusssu_0_1_2_3_4_5
+_sbus_sss_key_uusssu_0_1_2_3_4
(TALLOC_CTX *mem_ctx,
struct sbus_request *sbus_req,
struct _sbus_sss_invoker_args_uusssu *args)
{
if (sbus_req->sender == NULL) {
- return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s:%s:%s:%" PRIu32 "",
+ return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s:%s:%s",
sbus_req->type, sbus_req->interface, sbus_req->member,
- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3, args->arg4, args->arg5);
+ sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3, args->arg4);
}
- return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s:%s:%s:%" PRIu32 "",
+ return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s:%s:%s",
sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member,
- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3, args->arg4, args->arg5);
+ sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3, args->arg4);
}
const char *
-_sbus_sss_key_uusu_0_1_2_3
+_sbus_sss_key_uusu_0_1_2
(TALLOC_CTX *mem_ctx,
struct sbus_request *sbus_req,
struct _sbus_sss_invoker_args_uusu *args)
{
if (sbus_req->sender == NULL) {
- return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s:%" PRIu32 "",
+ return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s",
sbus_req->type, sbus_req->interface, sbus_req->member,
- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3);
+ sbus_req->path, args->arg0, args->arg1, args->arg2);
}
- return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s:%" PRIu32 "",
+ return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%s",
sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member,
- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3);
+ sbus_req->path, args->arg0, args->arg1, args->arg2);
}
const char *
-_sbus_sss_key_uuusu_0_1_2_3_4
+_sbus_sss_key_uuusu_0_1_2_3
(TALLOC_CTX *mem_ctx,
struct sbus_request *sbus_req,
struct _sbus_sss_invoker_args_uuusu *args)
{
if (sbus_req->sender == NULL) {
- return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%s:%" PRIu32 "",
+ return talloc_asprintf(mem_ctx, "-:%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%s",
sbus_req->type, sbus_req->interface, sbus_req->member,
- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3, args->arg4);
+ sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3);
}
- return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%s:%" PRIu32 "",
+ return talloc_asprintf(mem_ctx, "%"PRIi64":%u:%s.%s:%s:%" PRIu32 ":%" PRIu32 ":%" PRIu32 ":%s",
sbus_req->sender->uid, sbus_req->type, sbus_req->interface, sbus_req->member,
- sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3, args->arg4);
+ sbus_req->path, args->arg0, args->arg1, args->arg2, args->arg3);
}
diff --git a/src/sss_iface/sbus_sss_keygens.h b/src/sss_iface/sbus_sss_keygens.h
index 8f09b46de5..7e42c2c53f 100644
--- a/src/sss_iface/sbus_sss_keygens.h
+++ b/src/sss_iface/sbus_sss_keygens.h
@@ -49,31 +49,31 @@ _sbus_sss_key_ussu_0_1
struct _sbus_sss_invoker_args_ussu *args);
const char *
-_sbus_sss_key_ussu_0_1_2_3
+_sbus_sss_key_ussu_0_1_2
(TALLOC_CTX *mem_ctx,
struct sbus_request *sbus_req,
struct _sbus_sss_invoker_args_ussu *args);
const char *
-_sbus_sss_key_usu_0_1_2
+_sbus_sss_key_usu_0_1
(TALLOC_CTX *mem_ctx,
struct sbus_request *sbus_req,
struct _sbus_sss_invoker_args_usu *args);
const char *
-_sbus_sss_key_uusssu_0_1_2_3_4_5
+_sbus_sss_key_uusssu_0_1_2_3_4
(TALLOC_CTX *mem_ctx,
struct sbus_request *sbus_req,
struct _sbus_sss_invoker_args_uusssu *args);
const char *
-_sbus_sss_key_uusu_0_1_2_3
+_sbus_sss_key_uusu_0_1_2
(TALLOC_CTX *mem_ctx,
struct sbus_request *sbus_req,
struct _sbus_sss_invoker_args_uusu *args);
const char *
-_sbus_sss_key_uuusu_0_1_2_3_4
+_sbus_sss_key_uuusu_0_1_2_3
(TALLOC_CTX *mem_ctx,
struct sbus_request *sbus_req,
struct _sbus_sss_invoker_args_uuusu *args);
diff --git a/src/sss_iface/sss_iface.xml b/src/sss_iface/sss_iface.xml
index 6709c4e48a..82c65aa0b8 100644
--- a/src/sss_iface/sss_iface.xml
+++ b/src/sss_iface/sss_iface.xml
@@ -91,18 +91,18 @@
<method name="GetMap">
<arg name="dp_flags" type="u" direction="in" key="1" />
<arg name="mapname" type="s" direction="in" key="2" />
- <arg name="cli_id" type="u" direction="in" key="3" />
+ <arg name="cli_id" type="u" direction="in" />
</method>
<method name="GetEntry">
<arg name="dp_flags" type="u" direction="in" key="1" />
<arg name="mapname" type="s" direction="in" key="2" />
<arg name="entryname" type="s" direction="in" key="3" />
- <arg name="cli_id" type="u" direction="in" key="4" />
+ <arg name="cli_id" type="u" direction="in" />
</method>
<method name="Enumerate">
<arg name="dp_flags" type="u" direction="in" key="1" />
<arg name="mapname" type="s" direction="in" key="2" />
- <arg name="cli_id" type="u" direction="in" key="3" />
+ <arg name="cli_id" type="u" direction="in" />
</method>
</interface>
@@ -133,7 +133,7 @@
<arg name="entry_type" type="u" direction="in" key="2" />
<arg name="filter_type" type="u" direction="in" key="3" />
<arg name="filter_value" type="s" direction="in" key="4" />
- <arg name="cli_id" type="u" direction="in" key="5" />
+ <arg name="cli_id" type="u" direction="in" />
<arg name="dp_error" type="q" direction="out" />
<arg name="error" type="u" direction="out" />
<arg name="error_message" type="s" direction="out" />
@@ -150,7 +150,7 @@
<arg name="filter" type="s" direction="in" key="3" />
<arg name="domain" type="s" direction="in" key="4" />
<arg name="extra" type="s" direction="in" key="5" />
- <arg name="cli_id" type="u" direction="in" key="6" />
+ <arg name="cli_id" type="u" direction="in" />
<arg name="dp_error" type="q" direction="out" />
<arg name="error" type="u" direction="out" />
<arg name="error_message" type="s" direction="out" />
@@ -159,7 +159,7 @@
<arg name="dp_flags" type="u" direction="in" key="1" />
<arg name="entry_type" type="u" direction="in" key="2" />
<arg name="filter" type="s" direction="in" key="3" />
- <arg name="cli_id" type="u" direction="in" key="4" />
+ <arg name="cli_id" type="u" direction="in" />
<arg name="dp_error" type="q" direction="out" />
<arg name="error" type="u" direction="out" />
<arg name="domain_name" type="s" direction="out" />

View File

@ -1,28 +0,0 @@
From 74d0f4538deb766592079b1abca0d949d6dea105 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Thu, 15 Jun 2023 12:05:03 +0200
Subject: [PATCH] BUILD: Accept krb5 1.21 for building the PAC plugin
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/external/pac_responder.m4 | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/external/pac_responder.m4 b/src/external/pac_responder.m4
index 3cbe3c9cfb..90727185b5 100644
--- a/src/external/pac_responder.m4
+++ b/src/external/pac_responder.m4
@@ -22,7 +22,8 @@ then
Kerberos\ 5\ release\ 1.17* | \
Kerberos\ 5\ release\ 1.18* | \
Kerberos\ 5\ release\ 1.19* | \
- Kerberos\ 5\ release\ 1.20*)
+ Kerberos\ 5\ release\ 1.20* | \
+ Kerberos\ 5\ release\ 1.21*)
krb5_version_ok=yes
AC_MSG_RESULT([yes])
;;

View File

@ -0,0 +1,50 @@
From 8bf31924265baf81372fe42580dee4064a642375 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 23 Jan 2024 09:28:26 +0100
Subject: [PATCH] sss-client: handle key value in destructor
When the pthread key destructor is called the key value is already set
to NULL by the caller. As a result the data stored in the value can only
be accessed by the first argument passed to the destructor and not by
pthread_getspecific() as the previous code did.
Resolves: https://github.com/SSSD/sssd/issues/7189
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
(cherry picked from commit b439847bc88ad7b89f0596af822c0ffbf2a579df)
---
src/sss_client/common.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/src/sss_client/common.c b/src/sss_client/common.c
index 702d0597d..32555edf3 100644
--- a/src/sss_client/common.c
+++ b/src/sss_client/common.c
@@ -93,8 +93,22 @@ void sss_cli_close_socket(void)
#ifdef HAVE_PTHREAD_EXT
static void sss_at_thread_exit(void *v)
{
- sss_cli_close_socket();
+ /* At this point the key value is already set to NULL and the only way to
+ * access the data from the value is via the argument passed to the
+ * destructor (sss_at_thread_exit). See e.g.
+ * https://www.man7.org/linux/man-pages/man3/pthread_key_create.3p.html
+ * for details. */
+
+ struct sss_socket_descriptor_t *descriptor = (struct sss_socket_descriptor_t *) v;
+
+ if (descriptor->sd != -1) {
+ close(descriptor->sd);
+ descriptor->sd = -1;
+ }
+
free(v);
+
+ /* Most probably redudant, but better safe than sorry. */
pthread_setspecific(sss_sd_key, NULL);
}
--
2.42.0

View File

@ -1,332 +0,0 @@
From 88d8afbb115f18007dcc11f7ebac1b238c3ebd98 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Mon, 25 Sep 2023 12:36:09 +0200
Subject: [PATCH] MC: a couple of additions to 'recover from invalid memory
cache size' patch
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Additions to 641e5f73d3bd5b3d32cafd551013d3bfd2a52732 :
- handle all invalidations consistently
- supply a valid pointer to `sss_mmap_cache_validate_or_reinit()`,
not a pointer to a local var
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/responder/nss/nss_get_object.c | 10 ++---
src/responder/nss/nss_iface.c | 8 ++--
src/responder/nss/nsssrv_mmap_cache.c | 64 ++++++++++++++++++---------
src/responder/nss/nsssrv_mmap_cache.h | 10 ++---
4 files changed, 56 insertions(+), 36 deletions(-)
diff --git a/src/responder/nss/nss_get_object.c b/src/responder/nss/nss_get_object.c
index 5d62dd0985..29f9cb59b5 100644
--- a/src/responder/nss/nss_get_object.c
+++ b/src/responder/nss/nss_get_object.c
@@ -34,13 +34,13 @@ memcache_delete_entry_by_name(struct sss_nss_ctx *nss_ctx,
switch (type) {
case SSS_MC_PASSWD:
- ret = sss_mmap_cache_pw_invalidate(nss_ctx->pwd_mc_ctx, name);
+ ret = sss_mmap_cache_pw_invalidate(&nss_ctx->pwd_mc_ctx, name);
break;
case SSS_MC_GROUP:
- ret = sss_mmap_cache_gr_invalidate(nss_ctx->grp_mc_ctx, name);
+ ret = sss_mmap_cache_gr_invalidate(&nss_ctx->grp_mc_ctx, name);
break;
case SSS_MC_INITGROUPS:
- ret = sss_mmap_cache_initgr_invalidate(nss_ctx->initgr_mc_ctx, name);
+ ret = sss_mmap_cache_initgr_invalidate(&nss_ctx->initgr_mc_ctx, name);
break;
default:
return EINVAL;
@@ -66,10 +66,10 @@ memcache_delete_entry_by_id(struct sss_nss_ctx *nss_ctx,
switch (type) {
case SSS_MC_PASSWD:
- ret = sss_mmap_cache_pw_invalidate_uid(nss_ctx->pwd_mc_ctx, (uid_t)id);
+ ret = sss_mmap_cache_pw_invalidate_uid(&nss_ctx->pwd_mc_ctx, (uid_t)id);
break;
case SSS_MC_GROUP:
- ret = sss_mmap_cache_gr_invalidate_gid(nss_ctx->grp_mc_ctx, (gid_t)id);
+ ret = sss_mmap_cache_gr_invalidate_gid(&nss_ctx->grp_mc_ctx, (gid_t)id);
break;
default:
return EINVAL;
diff --git a/src/responder/nss/nss_iface.c b/src/responder/nss/nss_iface.c
index 07e91aa811..db743f8b7e 100644
--- a/src/responder/nss/nss_iface.c
+++ b/src/responder/nss/nss_iface.c
@@ -78,7 +78,7 @@ sss_nss_update_initgr_memcache(struct sss_nss_ctx *nctx,
if (ret == ENOENT || res->count == 0) {
/* The user is gone. Invalidate the mc record */
- ret = sss_mmap_cache_pw_invalidate(nctx->pwd_mc_ctx, delete_name);
+ ret = sss_mmap_cache_pw_invalidate(&nctx->pwd_mc_ctx, delete_name);
if (ret != EOK && ret != ENOENT) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Internal failure in memory cache code: %d [%s]\n",
@@ -125,7 +125,7 @@ sss_nss_update_initgr_memcache(struct sss_nss_ctx *nctx,
for (i = 0; i < gnum; i++) {
id = groups[i];
- ret = sss_mmap_cache_gr_invalidate_gid(nctx->grp_mc_ctx, id);
+ ret = sss_mmap_cache_gr_invalidate_gid(&nctx->grp_mc_ctx, id);
if (ret != EOK && ret != ENOENT) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Internal failure in memory cache code: %d [%s]\n",
@@ -134,7 +134,7 @@ sss_nss_update_initgr_memcache(struct sss_nss_ctx *nctx,
}
to_sized_string(delete_name, fq_name);
- ret = sss_mmap_cache_initgr_invalidate(nctx->initgr_mc_ctx,
+ ret = sss_mmap_cache_initgr_invalidate(&nctx->initgr_mc_ctx,
delete_name);
if (ret != EOK && ret != ENOENT) {
DEBUG(SSSDBG_CRIT_FAILURE,
@@ -208,7 +208,7 @@ sss_nss_memorycache_invalidate_group_by_id(TALLOC_CTX *mem_ctx,
DEBUG(SSSDBG_TRACE_LIBS,
"Invalidating group %u from memory cache\n", gid);
- sss_mmap_cache_gr_invalidate_gid(nctx->grp_mc_ctx, gid);
+ sss_mmap_cache_gr_invalidate_gid(&nctx->grp_mc_ctx, gid);
return EOK;
}
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index 90d12299a4..06f3d7a694 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -701,16 +701,22 @@ static inline void sss_mmap_chain_in_rec(struct sss_mc_ctx *mcc,
* generic invalidation
***************************************************************************/
-static errno_t sss_mmap_cache_invalidate(struct sss_mc_ctx *mcc,
+static errno_t sss_mmap_cache_validate_or_reinit(struct sss_mc_ctx **_mcc);
+
+static errno_t sss_mmap_cache_invalidate(struct sss_mc_ctx **_mcc,
const struct sized_string *key)
{
+ struct sss_mc_ctx *mcc;
struct sss_mc_rec *rec;
+ int ret;
- if (mcc == NULL) {
- /* cache not initialized? */
- return EINVAL;
+ ret = sss_mmap_cache_validate_or_reinit(_mcc);
+ if (ret != EOK) {
+ return ret;
}
+ mcc = *_mcc;
+
rec = sss_mc_find_record(mcc, key);
if (rec == NULL) {
/* nothing to invalidate */
@@ -785,7 +791,7 @@ errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc,
const struct sized_string *homedir,
const struct sized_string *shell)
{
- struct sss_mc_ctx *mcc = *_mcc;
+ struct sss_mc_ctx *mcc;
struct sss_mc_rec *rec;
struct sss_mc_pwd_data *data;
struct sized_string uidkey;
@@ -795,11 +801,13 @@ errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc,
size_t pos;
int ret;
- ret = sss_mmap_cache_validate_or_reinit(&mcc);
+ ret = sss_mmap_cache_validate_or_reinit(_mcc);
if (ret != EOK) {
return ret;
}
+ mcc = *_mcc;
+
ret = snprintf(uidstr, 11, "%ld", (long)uid);
if (ret > 10) {
return EINVAL;
@@ -851,14 +859,15 @@ errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc,
return EOK;
}
-errno_t sss_mmap_cache_pw_invalidate(struct sss_mc_ctx *mcc,
+errno_t sss_mmap_cache_pw_invalidate(struct sss_mc_ctx **_mcc,
const struct sized_string *name)
{
- return sss_mmap_cache_invalidate(mcc, name);
+ return sss_mmap_cache_invalidate(_mcc, name);
}
-errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid)
+errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx **_mcc, uid_t uid)
{
+ struct sss_mc_ctx *mcc;
struct sss_mc_rec *rec = NULL;
struct sss_mc_pwd_data *data;
uint32_t hash;
@@ -866,11 +875,13 @@ errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid)
char *uidstr;
errno_t ret;
- ret = sss_mmap_cache_validate_or_reinit(&mcc);
+ ret = sss_mmap_cache_validate_or_reinit(_mcc);
if (ret != EOK) {
return ret;
}
+ mcc = *_mcc;
+
uidstr = talloc_asprintf(NULL, "%ld", (long)uid);
if (!uidstr) {
return ENOMEM;
@@ -927,7 +938,7 @@ int sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc,
gid_t gid, size_t memnum,
const char *membuf, size_t memsize)
{
- struct sss_mc_ctx *mcc = *_mcc;
+ struct sss_mc_ctx *mcc;
struct sss_mc_rec *rec;
struct sss_mc_grp_data *data;
struct sized_string gidkey;
@@ -937,11 +948,13 @@ int sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc,
size_t pos;
int ret;
- ret = sss_mmap_cache_validate_or_reinit(&mcc);
+ ret = sss_mmap_cache_validate_or_reinit(_mcc);
if (ret != EOK) {
return ret;
}
+ mcc = *_mcc;
+
ret = snprintf(gidstr, 11, "%ld", (long)gid);
if (ret > 10) {
return EINVAL;
@@ -989,14 +1002,15 @@ int sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc,
return EOK;
}
-errno_t sss_mmap_cache_gr_invalidate(struct sss_mc_ctx *mcc,
+errno_t sss_mmap_cache_gr_invalidate(struct sss_mc_ctx **_mcc,
const struct sized_string *name)
{
- return sss_mmap_cache_invalidate(mcc, name);
+ return sss_mmap_cache_invalidate(_mcc, name);
}
-errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid)
+errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx **_mcc, gid_t gid)
{
+ struct sss_mc_ctx *mcc;
struct sss_mc_rec *rec = NULL;
struct sss_mc_grp_data *data;
uint32_t hash;
@@ -1004,11 +1018,13 @@ errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid)
char *gidstr;
errno_t ret;
- ret = sss_mmap_cache_validate_or_reinit(&mcc);
+ ret = sss_mmap_cache_validate_or_reinit(_mcc);
if (ret != EOK) {
return ret;
}
+ mcc = *_mcc;
+
gidstr = talloc_asprintf(NULL, "%ld", (long)gid);
if (!gidstr) {
return ENOMEM;
@@ -1061,7 +1077,7 @@ errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc,
uint32_t num_groups,
const uint8_t *gids_buf)
{
- struct sss_mc_ctx *mcc = *_mcc;
+ struct sss_mc_ctx *mcc;
struct sss_mc_rec *rec;
struct sss_mc_initgr_data *data;
size_t data_len;
@@ -1069,11 +1085,13 @@ errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc,
size_t pos;
int ret;
- ret = sss_mmap_cache_validate_or_reinit(&mcc);
+ ret = sss_mmap_cache_validate_or_reinit(_mcc);
if (ret != EOK) {
return ret;
}
+ mcc = *_mcc;
+
/* array of gids + name + unique_name */
data_len = num_groups * sizeof(uint32_t) + name->len + unique_name->len;
rec_len = sizeof(struct sss_mc_rec) + sizeof(struct sss_mc_initgr_data)
@@ -1119,10 +1137,10 @@ errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc,
return EOK;
}
-errno_t sss_mmap_cache_initgr_invalidate(struct sss_mc_ctx *mcc,
+errno_t sss_mmap_cache_initgr_invalidate(struct sss_mc_ctx **_mcc,
const struct sized_string *name)
{
- return sss_mmap_cache_invalidate(mcc, name);
+ return sss_mmap_cache_invalidate(_mcc, name);
}
errno_t sss_mmap_cache_sid_store(struct sss_mc_ctx **_mcc,
@@ -1131,18 +1149,20 @@ errno_t sss_mmap_cache_sid_store(struct sss_mc_ctx **_mcc,
uint32_t type,
bool explicit_lookup)
{
- struct sss_mc_ctx *mcc = *_mcc;
+ struct sss_mc_ctx *mcc;
struct sss_mc_rec *rec;
struct sss_mc_sid_data *data;
char idkey[16];
size_t rec_len;
int ret;
- ret = sss_mmap_cache_validate_or_reinit(&mcc);
+ ret = sss_mmap_cache_validate_or_reinit(_mcc);
if (ret != EOK) {
return ret;
}
+ mcc = *_mcc;
+
ret = snprintf(idkey, sizeof(idkey), "%d-%ld",
(type == SSS_ID_TYPE_GID) ? SSS_ID_TYPE_GID : SSS_ID_TYPE_UID,
(long)id);
diff --git a/src/responder/nss/nsssrv_mmap_cache.h b/src/responder/nss/nsssrv_mmap_cache.h
index 686b8e1b21..28ee5adb64 100644
--- a/src/responder/nss/nsssrv_mmap_cache.h
+++ b/src/responder/nss/nsssrv_mmap_cache.h
@@ -63,17 +63,17 @@ errno_t sss_mmap_cache_sid_store(struct sss_mc_ctx **_mcc,
uint32_t type, /* enum sss_id_type*/
bool explicit_lookup); /* false ~ by_id(), true ~ by_uid/gid() */
-errno_t sss_mmap_cache_pw_invalidate(struct sss_mc_ctx *mcc,
+errno_t sss_mmap_cache_pw_invalidate(struct sss_mc_ctx **_mcc,
const struct sized_string *name);
-errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid);
+errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx **_mcc, uid_t uid);
-errno_t sss_mmap_cache_gr_invalidate(struct sss_mc_ctx *mcc,
+errno_t sss_mmap_cache_gr_invalidate(struct sss_mc_ctx **_mcc,
const struct sized_string *name);
-errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid);
+errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx **_mcc, gid_t gid);
-errno_t sss_mmap_cache_initgr_invalidate(struct sss_mc_ctx *mcc,
+errno_t sss_mmap_cache_initgr_invalidate(struct sss_mc_ctx **_mcc,
const struct sized_string *name);
errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx,

View File

@ -0,0 +1,104 @@
From 23849f751315ea218e125f35cd419cce55d27355 Mon Sep 17 00:00:00 2001
From: Justin Stephenson <jstephen@redhat.com>
Date: Thu, 1 Feb 2024 14:22:09 -0500
Subject: [PATCH 6/7] krb5: Allow fallback between responder questions
Add support to try the next Preauth type when answering
krb5 questions. Fixes an issue when an IPA user has
both authtype passkey and authtype password set at
the same time.
Resolves: https://github.com/SSSD/sssd/issues/7152
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
(cherry picked from commit c9a333c5215b9ee6080038881a249c329141d0cf)
---
src/providers/krb5/krb5_child.c | 37 +++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 9 deletions(-)
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index d3e3d859a..26b0090b4 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -784,11 +784,14 @@ static krb5_error_code answer_pkinit(krb5_context ctx,
"krb5_responder_set_answer failed.\n");
}
+ goto done;
+ } else {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected authentication token type [%s]\n",
+ sss_authtok_type_to_str(sss_authtok_get_type(kr->pd->authtok)));
+ kerr = EAGAIN;
goto done;
}
- kerr = EOK;
-
done:
krb5_responder_pkinit_challenge_free(ctx, rctx, chl);
@@ -914,9 +917,9 @@ static krb5_error_code answer_idp_oauth2(krb5_context kctx,
type = sss_authtok_get_type(kr->pd->authtok);
if (type != SSS_AUTHTOK_TYPE_OAUTH2) {
- DEBUG(SSSDBG_OP_FAILURE, "Unexpected authentication token type [%s]\n",
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected authentication token type [%s]\n",
sss_authtok_type_to_str(type));
- kerr = EINVAL;
+ kerr = EAGAIN;
goto done;
}
@@ -1141,9 +1144,9 @@ static krb5_error_code answer_passkey(krb5_context kctx,
type = sss_authtok_get_type(kr->pd->authtok);
if (type != SSS_AUTHTOK_TYPE_PASSKEY_REPLY) {
- DEBUG(SSSDBG_OP_FAILURE, "Unexpected authentication token type [%s]\n",
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected authentication token type [%s]\n",
sss_authtok_type_to_str(type));
- kerr = EINVAL;
+ kerr = EAGAIN;
goto done;
}
@@ -1244,17 +1247,33 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx,
return kerr;
}
+
+ kerr = EOK;
} else if (strcmp(question_list[c],
KRB5_RESPONDER_QUESTION_PKINIT) == 0
&& (sss_authtok_get_type(kr->pd->authtok)
== SSS_AUTHTOK_TYPE_SC_PIN
|| sss_authtok_get_type(kr->pd->authtok)
== SSS_AUTHTOK_TYPE_SC_KEYPAD)) {
- return answer_pkinit(ctx, kr, rctx);
+ kerr = answer_pkinit(ctx, kr, rctx);
} else if (strcmp(question_list[c], SSSD_IDP_OAUTH2_QUESTION) == 0) {
- return answer_idp_oauth2(ctx, kr, rctx);
+ kerr = answer_idp_oauth2(ctx, kr, rctx);
} else if (strcmp(question_list[c], SSSD_PASSKEY_QUESTION) == 0) {
- return answer_passkey(ctx, kr, rctx);
+ kerr = answer_passkey(ctx, kr, rctx);
+ } else {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unknown question type [%s]\n", question_list[c]);
+ kerr = EINVAL;
+ }
+
+ /* Continue to the next question when the given authtype cannot be
+ * handled by the answer_* function. This allows fallback between auth
+ * types, such as passkey -> password. */
+ if (kerr == EAGAIN) {
+ DEBUG(SSSDBG_TRACE_ALL, "Auth type [%s] could not be handled by answer function, "
+ "continuing to next question.\n", question_list[c]);
+ continue;
+ } else {
+ return kerr;
}
}
}
--
2.42.0

View File

@ -1,384 +0,0 @@
From b0212b04f109875936612a52a7b30a80e5a85ee5 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Mon, 23 Oct 2023 16:11:17 +0200
Subject: [PATCH] SSS_CLIENT: replace `__thread` with `pthread_*specific()`
in sss_client code to properly handle OOM condition (with `__thread`
glibc terminates process in this case).
Solution relies on the fact that `sss_cli_check_socket()` is always
executed first, before touching socket.
Nonetheless, there are sanity guards in setters/getters just in case.
It's possible to move context initialization code into a separate
function and call it in every getter/setter, but probably not worth it.
Reviewed-by: Sumit Bose <sbose@redhat.com>
Reviewed-by: Carlos O'Donell <codonell@redhat.com>
---
src/sss_client/common.c | 202 ++++++++++++++++++++++++++++++++--------
1 file changed, 164 insertions(+), 38 deletions(-)
diff --git a/src/sss_client/common.c b/src/sss_client/common.c
index c80c8e74b7..1075af9419 100644
--- a/src/sss_client/common.c
+++ b/src/sss_client/common.c
@@ -62,22 +62,31 @@
/* common functions */
+static int sss_cli_sd_get(void);
+static void sss_cli_sd_set(int sd);
+static const struct stat *sss_cli_sb_get(void);
+static int sss_cli_sb_set_by_sd(int sd);
+
#ifdef HAVE_PTHREAD_EXT
static pthread_key_t sss_sd_key;
static pthread_once_t sss_sd_key_init = PTHREAD_ONCE_INIT;
static atomic_bool sss_sd_key_initialized = false;
-static __thread int sss_cli_sd = -1; /* the sss client socket descriptor */
-static __thread struct stat sss_cli_sb; /* the sss client stat buffer */
+struct sss_socket_descriptor_t {
+ int sd;
+ struct stat sb;
+};
#else
-static int sss_cli_sd = -1; /* the sss client socket descriptor */
-static struct stat sss_cli_sb; /* the sss client stat buffer */
+static int _sss_cli_sd = -1; /* the sss client socket descriptor */
+static struct stat _sss_cli_sb; /* the sss client stat buffer */
#endif
void sss_cli_close_socket(void)
{
- if (sss_cli_sd != -1) {
- close(sss_cli_sd);
- sss_cli_sd = -1;
+ int sd = sss_cli_sd_get();
+
+ if (sd != -1) {
+ close(sd);
+ sss_cli_sd_set(-1);
}
}
@@ -85,25 +94,30 @@ void sss_cli_close_socket(void)
static void sss_at_thread_exit(void *v)
{
sss_cli_close_socket();
+ free(v);
+ pthread_setspecific(sss_sd_key, NULL);
}
static void init_sd_key(void)
{
- pthread_key_create(&sss_sd_key, sss_at_thread_exit);
- sss_sd_key_initialized = true;
+ if (pthread_key_create(&sss_sd_key, sss_at_thread_exit) == 0) {
+ sss_sd_key_initialized = true;
+ }
}
#endif
#if HAVE_FUNCTION_ATTRIBUTE_DESTRUCTOR
__attribute__((destructor)) void sss_at_lib_unload(void)
{
+ sss_cli_close_socket();
#ifdef HAVE_PTHREAD_EXT
if (sss_sd_key_initialized) {
sss_sd_key_initialized = false;
+ free(pthread_getspecific(sss_sd_key));
+ pthread_setspecific(sss_sd_key, NULL);
pthread_key_delete(sss_sd_key);
}
#endif
- sss_cli_close_socket();
}
#endif
@@ -137,7 +151,7 @@ static enum sss_status sss_cli_send_req(enum sss_cli_command cmd,
int res, error;
*errnop = 0;
- pfd.fd = sss_cli_sd;
+ pfd.fd = sss_cli_sd_get();
pfd.events = POLLOUT;
do {
@@ -163,7 +177,7 @@ static enum sss_status sss_cli_send_req(enum sss_cli_command cmd,
*errnop = EPIPE;
} else if (pfd.revents & POLLNVAL) {
/* Invalid request: fd is not opened */
- sss_cli_sd = -1;
+ sss_cli_sd_set(-1);
*errnop = EPIPE;
} else if (!(pfd.revents & POLLOUT)) {
*errnop = EBUSY;
@@ -180,13 +194,13 @@ static enum sss_status sss_cli_send_req(enum sss_cli_command cmd,
errno = 0;
if (datasent < SSS_NSS_HEADER_SIZE) {
- res = send(sss_cli_sd,
+ res = send(sss_cli_sd_get(),
(char *)header + datasent,
SSS_NSS_HEADER_SIZE - datasent,
SSS_DEFAULT_WRITE_FLAGS);
} else {
rdsent = datasent - SSS_NSS_HEADER_SIZE;
- res = send(sss_cli_sd,
+ res = send(sss_cli_sd_get(),
(const char *)rd->data + rdsent,
rd->len - rdsent,
SSS_DEFAULT_WRITE_FLAGS);
@@ -249,7 +263,7 @@ static enum sss_status sss_cli_recv_rep(enum sss_cli_command cmd,
int bufrecv;
int res, error;
- pfd.fd = sss_cli_sd;
+ pfd.fd = sss_cli_sd_get();
pfd.events = POLLIN;
do {
@@ -278,7 +292,7 @@ static enum sss_status sss_cli_recv_rep(enum sss_cli_command cmd,
*errnop = EPIPE;
} else if (pfd.revents & POLLNVAL) {
/* Invalid request: fd is not opened */
- sss_cli_sd = -1;
+ sss_cli_sd_set(-1);
*errnop = EPIPE;
} else if (!(pfd.revents & POLLIN)) {
*errnop = EBUSY;
@@ -296,12 +310,12 @@ static enum sss_status sss_cli_recv_rep(enum sss_cli_command cmd,
errno = 0;
if (datarecv < SSS_NSS_HEADER_SIZE) {
- res = read(sss_cli_sd,
+ res = read(sss_cli_sd_get(),
(char *)header + datarecv,
SSS_NSS_HEADER_SIZE - datarecv);
} else {
bufrecv = datarecv - SSS_NSS_HEADER_SIZE;
- res = read(sss_cli_sd,
+ res = read(sss_cli_sd_get(),
(char *) buf + bufrecv,
header[0] - datarecv);
}
@@ -591,16 +605,6 @@ static int sss_cli_open_socket(int *errnop, const char *socket_name, int timeout
return -1;
}
-#ifdef HAVE_PTHREAD_EXT
- pthread_once(&sss_sd_key_init, init_sd_key); /* once for all threads */
-
- /* It actually doesn't matter what value to set for a key.
- * The only important thing: key must be non-NULL to ensure
- * destructor is executed at thread exit.
- */
- pthread_setspecific(sss_sd_key, &sss_cli_sd);
-#endif
-
/* set as non-blocking, close on exec, and make sure standard
* descriptors are not used */
sd = make_safe_fd(sd);
@@ -670,7 +674,7 @@ static int sss_cli_open_socket(int *errnop, const char *socket_name, int timeout
return -1;
}
- ret = fstat(sd, &sss_cli_sb);
+ ret = sss_cli_sb_set_by_sd(sd);
if (ret != 0) {
close(sd);
return -1;
@@ -686,33 +690,69 @@ static enum sss_status sss_cli_check_socket(int *errnop,
static pid_t mypid_s;
static ino_t myself_ino;
struct stat mypid_sb, myself_sb;
+ const struct stat *sss_cli_sb = NULL;
pid_t mypid_d;
int mysd;
int ret;
+#ifdef HAVE_PTHREAD_EXT
+ struct sss_socket_descriptor_t *descriptor = NULL;
+
+ ret = pthread_once(&sss_sd_key_init, init_sd_key); /* once for all threads */
+ if (ret != 0) {
+ *errnop = EFAULT;
+ return SSS_STATUS_UNAVAIL;
+ }
+ if (!sss_sd_key_initialized) {
+ /* pthread_once::init_sd_key::pthread_key_create failed -- game over? */
+ *errnop = EFAULT;
+ return SSS_STATUS_UNAVAIL;
+ }
+
+ if (pthread_getspecific(sss_sd_key) == NULL) { /* for every thread */
+ descriptor = (struct sss_socket_descriptor_t *)
+ calloc(1, sizeof(struct sss_socket_descriptor_t));
+ if (descriptor == NULL) {
+ *errnop = ENOMEM;
+ return SSS_STATUS_UNAVAIL;
+ }
+ descriptor->sd = -1;
+ ret = pthread_setspecific(sss_sd_key, descriptor);
+ if (ret != 0) {
+ free(descriptor);
+ *errnop = ENOMEM;
+ return SSS_STATUS_UNAVAIL;
+ }
+ }
+#endif
+ sss_cli_sb = sss_cli_sb_get();
+ if (sss_cli_sb == NULL) {
+ *errnop = EFAULT;
+ return SSS_STATUS_UNAVAIL;
+ }
ret = lstat("/proc/self/", &myself_sb);
mypid_d = getpid();
if (mypid_d != mypid_s || (ret == 0 && myself_sb.st_ino != myself_ino)) {
- ret = fstat(sss_cli_sd, &mypid_sb);
+ ret = fstat(sss_cli_sd_get(), &mypid_sb);
if (ret == 0) {
if (S_ISSOCK(mypid_sb.st_mode) &&
- mypid_sb.st_dev == sss_cli_sb.st_dev &&
- mypid_sb.st_ino == sss_cli_sb.st_ino) {
+ mypid_sb.st_dev == sss_cli_sb->st_dev &&
+ mypid_sb.st_ino == sss_cli_sb->st_ino) {
sss_cli_close_socket();
}
}
- sss_cli_sd = -1;
+ sss_cli_sd_set(-1);
mypid_s = mypid_d;
myself_ino = myself_sb.st_ino;
}
/* check if the socket has been closed on the other side */
- if (sss_cli_sd != -1) {
+ if (sss_cli_sd_get() != -1) {
struct pollfd pfd;
int res, error;
*errnop = 0;
- pfd.fd = sss_cli_sd;
+ pfd.fd = sss_cli_sd_get();
pfd.events = POLLIN | POLLOUT;
do {
@@ -738,7 +778,7 @@ static enum sss_status sss_cli_check_socket(int *errnop,
*errnop = EPIPE;
} else if (pfd.revents & POLLNVAL) {
/* Invalid request: fd is not opened */
- sss_cli_sd = -1;
+ sss_cli_sd_set(-1);
*errnop = EPIPE;
} else if (!(pfd.revents & (POLLIN | POLLOUT))) {
*errnop = EBUSY;
@@ -760,7 +800,7 @@ static enum sss_status sss_cli_check_socket(int *errnop,
return SSS_STATUS_UNAVAIL;
}
- sss_cli_sd = mysd;
+ sss_cli_sd_set(mysd);
if (sss_cli_check_version(socket_name, timeout)) {
return SSS_STATUS_SUCCESS;
@@ -1015,7 +1055,7 @@ int sss_pam_make_request(enum sss_cli_command cmd,
goto out;
}
- error = check_server_cred(sss_cli_sd);
+ error = check_server_cred(sss_cli_sd_get());
if (error != 0) {
sss_cli_close_socket();
*errnop = error;
@@ -1307,3 +1347,89 @@ errno_t sss_readrep_copy_string(const char *in,
return EOK;
}
+
+#ifdef HAVE_PTHREAD_EXT
+
+static int sss_cli_sd_get(void)
+{
+ if (!sss_sd_key_initialized) {
+ return -1;
+ }
+
+ struct sss_socket_descriptor_t *descriptor = pthread_getspecific(sss_sd_key);
+
+ if (descriptor == NULL) { /* sanity check */
+ return -1;
+ }
+
+ return descriptor->sd;
+}
+
+static void sss_cli_sd_set(int sd)
+{
+ if (!sss_sd_key_initialized) {
+ return;
+ }
+
+ struct sss_socket_descriptor_t *descriptor = pthread_getspecific(sss_sd_key);
+
+ if (descriptor == NULL) { /* sanity check */
+ return;
+ }
+
+ descriptor->sd = sd;
+}
+
+static const struct stat *sss_cli_sb_get(void)
+{
+ if (!sss_sd_key_initialized) {
+ return NULL;
+ }
+
+ struct sss_socket_descriptor_t *descriptor = pthread_getspecific(sss_sd_key);
+
+ if (descriptor == NULL) { /* sanity check */
+ return NULL;
+ }
+
+ return &descriptor->sb;
+}
+
+static int sss_cli_sb_set_by_sd(int sd)
+{
+ if (!sss_sd_key_initialized) {
+ return -1;
+ }
+
+ struct sss_socket_descriptor_t *descriptor = pthread_getspecific(sss_sd_key);
+
+ if (descriptor == NULL) { /* sanity check */
+ return -1;
+ }
+
+ return fstat(sd, &descriptor->sb);
+}
+
+#else
+
+static int sss_cli_sd_get(void)
+{
+ return _sss_cli_sd;
+}
+
+static void sss_cli_sd_set(int sd)
+{
+ _sss_cli_sd = sd;
+}
+
+static const struct stat *sss_cli_sb_get(void)
+{
+ return &_sss_cli_sb;
+}
+
+static int sss_cli_sb_set_by_sd(int sd)
+{
+ return fstat(sd, &_sss_cli_sb);
+}
+
+#endif

View File

@ -0,0 +1,206 @@
From 8d9ae754b50dffafef719ad3fa44e5dd1dde47b3 Mon Sep 17 00:00:00 2001
From: Justin Stephenson <jstephen@redhat.com>
Date: Fri, 1 Mar 2024 14:31:25 -0500
Subject: [PATCH 7/7] krb5: Add fallback password change support
handle password changes for IPA users with multiple auth types set
(passkey, password)
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
(cherry picked from commit 6c1272edf174eb4bdf236dc1ffd4287b71a43392)
---
src/krb5_plugin/passkey/passkey_clpreauth.c | 5 ++
src/providers/ipa/ipa_auth.c | 13 +++++
src/providers/krb5/krb5_auth.c | 12 +++++
src/providers/krb5/krb5_auth.h | 3 ++
src/providers/krb5/krb5_child.c | 5 ++
src/providers/krb5/krb5_child_handler.c | 53 +++++++++++++++++++++
src/responder/pam/pamsrv_cmd.c | 10 ++++
7 files changed, 101 insertions(+)
diff --git a/src/krb5_plugin/passkey/passkey_clpreauth.c b/src/krb5_plugin/passkey/passkey_clpreauth.c
index d2dfe6fe1..35b6a3fed 100644
--- a/src/krb5_plugin/passkey/passkey_clpreauth.c
+++ b/src/krb5_plugin/passkey/passkey_clpreauth.c
@@ -279,6 +279,11 @@ sss_passkeycl_process(krb5_context context,
goto done;
}
+ if (prompter == NULL) {
+ ret = EINVAL;
+ goto done;
+ }
+
/* Get FAST armor key. */
as_key = cb->fast_armor(context, rock);
if (as_key == NULL) {
diff --git a/src/providers/ipa/ipa_auth.c b/src/providers/ipa/ipa_auth.c
index 1d61a1052..e5e1bf30c 100644
--- a/src/providers/ipa/ipa_auth.c
+++ b/src/providers/ipa/ipa_auth.c
@@ -258,6 +258,19 @@ static void ipa_pam_auth_handler_krb5_done(struct tevent_req *subreq)
if (dp_err != DP_ERR_OK) {
goto done;
}
+ if (state->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM
+ && state->pd->pam_status == PAM_TRY_AGAIN) {
+ /* Reset this to fork a new krb5_child in handle_child_send() */
+ state->pd->child_pid = 0;
+ subreq = krb5_auth_queue_send(state, state->ev, state->be_ctx, state->pd,
+ state->auth_ctx->krb5_auth_ctx);
+ if (subreq == NULL) {
+ goto done;
+ }
+
+ tevent_req_set_callback(subreq, ipa_pam_auth_handler_retry_done, req);
+ return;
+ }
if (state->pd->cmd == SSS_PAM_AUTHENTICATE
&& state->pd->pam_status == PAM_CRED_ERR
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
index be34880b4..e34943b82 100644
--- a/src/providers/krb5/krb5_auth.c
+++ b/src/providers/krb5/krb5_auth.c
@@ -532,6 +532,18 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
ret = EOK;
goto done;
}
+
+ /* If krb5_child is still running from SSS_PAM_PREAUTH,
+ * terminate the waiting krb5_child and send the
+ * CHAUTHTOK_PRELIM request again */
+ if (pd->child_pid != 0) {
+ soft_terminate_krb5_child(state, pd, krb5_ctx);
+ state->pam_status = PAM_TRY_AGAIN;
+ state->dp_err = DP_ERR_OK;
+ ret = EOK;
+ goto done;
+ }
+
break;
case SSS_CMD_RENEW:
if (authtok_type != SSS_AUTHTOK_TYPE_CCFILE) {
diff --git a/src/providers/krb5/krb5_auth.h b/src/providers/krb5/krb5_auth.h
index bbdbf61fc..783292bc0 100644
--- a/src/providers/krb5/krb5_auth.h
+++ b/src/providers/krb5/krb5_auth.h
@@ -135,6 +135,9 @@ errno_t init_renew_tgt(struct krb5_ctx *krb5_ctx, struct be_ctx *be_ctx,
errno_t add_tgt_to_renew_table(struct krb5_ctx *krb5_ctx, const char *ccfile,
struct tgt_times *tgtt, struct pam_data *pd,
const char *upn);
+errno_t soft_terminate_krb5_child(TALLOC_CTX *mem_ctx,
+ struct pam_data *pd,
+ struct krb5_ctx *krb5_ctx);
/* krb5_access.c */
struct tevent_req *krb5_access_send(TALLOC_CTX *mem_ctx,
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 26b0090b4..b8acae7d7 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -1259,6 +1259,11 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx,
} else if (strcmp(question_list[c], SSSD_IDP_OAUTH2_QUESTION) == 0) {
kerr = answer_idp_oauth2(ctx, kr, rctx);
} else if (strcmp(question_list[c], SSSD_PASSKEY_QUESTION) == 0) {
+ /* Skip answer_passkey for expired password changes, e.g. user with auth types
+ * passkey AND password set */
+ if (kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM || kr->pd->cmd == SSS_PAM_CHAUTHTOK) {
+ continue;
+ }
kerr = answer_passkey(ctx, kr, rctx);
} else {
DEBUG(SSSDBG_MINOR_FAILURE, "Unknown question type [%s]\n", question_list[c]);
diff --git a/src/providers/krb5/krb5_child_handler.c b/src/providers/krb5/krb5_child_handler.c
index 54088e4d6..cab84b37d 100644
--- a/src/providers/krb5/krb5_child_handler.c
+++ b/src/providers/krb5/krb5_child_handler.c
@@ -1020,3 +1020,56 @@ parse_krb5_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, ssize_t len,
*_res = res;
return EOK;
}
+
+/* Closes the write end of waiting krb5_child */
+errno_t soft_terminate_krb5_child(TALLOC_CTX *mem_ctx,
+ struct pam_data *pd,
+ struct krb5_ctx *krb5_ctx)
+{
+ char *io_key;
+ struct child_io_fds *io;
+ TALLOC_CTX *tmp_ctx;
+ int ret;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ if (pd->child_pid == 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Expected waiting krb5_child.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ io_key = talloc_asprintf(tmp_ctx, "%d", pd->child_pid);
+ if (io_key == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ io = sss_ptr_hash_lookup(krb5_ctx->io_table, io_key,
+ struct child_io_fds);
+ if (io == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "PTR hash lookup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ if (io->write_to_child_fd != -1) {
+ ret = close(io->write_to_child_fd);
+ io->write_to_child_fd = -1;
+ if (ret != EOK) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "close failed [%d][%s].\n", ret, strerror(ret));
+ }
+ }
+
+ ret = EOK;
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index a7c181733..de408ced8 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -1418,6 +1418,15 @@ void pam_reply(struct pam_auth_req *preq)
goto done;
}
+#if BUILD_PASSKEY
+ if(pd->cmd == SSS_PAM_AUTHENTICATE &&
+ pd->pam_status == PAM_NEW_AUTHTOK_REQD &&
+ sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_PASSKEY_REPLY) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Passkey authentication reply, ignoring "
+ "new authtok required status\n");
+ pd->pam_status = PAM_SUCCESS;
+ }
+
/* Passkey auth user notification if no TGT is granted */
if (pd->cmd == SSS_PAM_AUTHENTICATE &&
pd->pam_status == PAM_SUCCESS &&
@@ -1429,6 +1438,7 @@ void pam_reply(struct pam_auth_req *preq)
"User [%s] logged in with local passkey authentication, single "
"sign on ticket is not obtained.\n", pd->user);
}
+#endif /* BUILD_PASSKEY */
/* Account expiration warning is printed for sshd. If pam_verbosity
* is equal or above PAM_VERBOSITY_INFO then all services are informed
--
2.42.0

View File

@ -1,28 +0,0 @@
From 39cd0baa06742b349ed763aa40ea4de366e80f1a Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Thu, 7 Dec 2023 09:47:25 +0100
Subject: [PATCH] DP: reduce log level in case a responder asks for unknown
domain
Since 9358a74d3a56c738890353aaf6bc956bfe72df99 a domain might be
skipped by 'ad_enabled_domains' option
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/providers/data_provider/dp_request.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/providers/data_provider/dp_request.c b/src/providers/data_provider/dp_request.c
index df2db26662..9c0fcf1f52 100644
--- a/src/providers/data_provider/dp_request.c
+++ b/src/providers/data_provider/dp_request.c
@@ -204,7 +204,8 @@ dp_req_new(TALLOC_CTX *mem_ctx,
if (domainname != NULL) {
dp_req->domain = find_domain_by_name(be_ctx->domain, domainname, true);
if (dp_req->domain == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unknown domain: %s\n", domainname);
+ /* domain might be skipped by 'ad_enabled_domains' option */
+ DEBUG(SSSDBG_CONF_SETTINGS, "Unknown domain: %s\n", domainname);
return ERR_DOMAIN_NOT_FOUND;
}
}

View File

@ -0,0 +1,30 @@
From bebb150720620aae97dcae5c11e0b9bea0119b5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 13 Mar 2024 13:27:02 +0100
Subject: [PATCH] pam: fix invalid #if condition
ifdef should be used as anywhere else, otherwise we hit a build
error if sssd is being built without passkey.
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
(cherry picked from commit 603399a43d7bd0b8b6de3b512388b08abb9521ed)
---
src/responder/pam/pamsrv_cmd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index de408ced8..13ba13131 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -1418,7 +1418,7 @@ void pam_reply(struct pam_auth_req *preq)
goto done;
}
-#if BUILD_PASSKEY
+#ifdef BUILD_PASSKEY
if(pd->cmd == SSS_PAM_AUTHENTICATE &&
pd->pam_status == PAM_NEW_AUTHTOK_REQD &&
sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_PASSKEY_REPLY) {
--
2.42.0

View File

@ -1,44 +0,0 @@
From 958a5e25c447dc502e8f8fbecf3253e62f92b0b2 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Fri, 8 Dec 2023 19:02:24 +0100
Subject: [PATCH] SSS_CLIENT: MC: in case mem-cache file validation fails,
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
don't return anything but EINVAL, because `_nss_sss_*()` functions
can have a special handling for other error codes (for ERANGE in
particular).
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
src/sss_client/nss_mc_common.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/sss_client/nss_mc_common.c b/src/sss_client/nss_mc_common.c
index e227c0bae3..37119fa8d3 100644
--- a/src/sss_client/nss_mc_common.c
+++ b/src/sss_client/nss_mc_common.c
@@ -79,17 +79,17 @@ static errno_t sss_nss_mc_validate(struct sss_cli_mc_ctx *ctx)
}
if (fstat(ctx->fd, &fdstat) == -1) {
- return errno;
+ return EINVAL;
}
/* Memcache was removed. */
if (fdstat.st_nlink == 0) {
- return ENOENT;
+ return EINVAL;
}
/* Invalid size. */
if (fdstat.st_size != ctx->mmap_size) {
- return ERANGE;
+ return EINVAL;
}
return EOK;

View File

@ -0,0 +1,185 @@
From 5b9bc0a1a6116e6fb001c7dce7497854fcdd40c4 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 14 Mar 2024 09:18:45 +0100
Subject: [PATCH 09/12] krb5: add OTP to krb5 response selection
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Originally where there was only password and OTP authentication we
checked for password authentication and used OTP as a fallback. This was
continued as other (pre)-authentication types were added. But so far
only one authentication type was returned.
This changed recently to allow the user a better selection and as a
result OTP cannot be handled as a fallback anymore but has to be added
to the selection. In case there are no types (questions) available now
password is used as a fallback.
Resolves: https://github.com/SSSD/sssd/issues/7152
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
(cherry picked from commit bf6cb6dcdd94d9f47e4e74acd51e30f86b488943)
---
src/providers/krb5/krb5_child.c | 107 ++++++++++++++++++++++----------
1 file changed, 75 insertions(+), 32 deletions(-)
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index b8acae7d7..116f2adda 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -1200,6 +1200,44 @@ done:
#endif /* BUILD_PASSKEY */
}
+static krb5_error_code answer_password(krb5_context kctx,
+ struct krb5_req *kr,
+ krb5_responder_context rctx)
+{
+ krb5_error_code kerr;
+ int ret;
+ const char *pwd;
+
+ kr->password_prompting = true;
+
+ if ((kr->pd->cmd == SSS_PAM_AUTHENTICATE
+ || kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM
+ || kr->pd->cmd == SSS_PAM_CHAUTHTOK)
+ && sss_authtok_get_type(kr->pd->authtok)
+ == SSS_AUTHTOK_TYPE_PASSWORD) {
+ ret = sss_authtok_get_password(kr->pd->authtok, &pwd, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sss_authtok_get_password failed.\n");
+ return ret;
+ }
+
+ kerr = krb5_responder_set_answer(kctx, rctx,
+ KRB5_RESPONDER_QUESTION_PASSWORD,
+ pwd);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "krb5_responder_set_answer failed.\n");
+ }
+
+ return kerr;
+ }
+
+ /* For SSS_PAM_PREAUTH and the other remaining commands the caller should
+ * continue to iterate over the available authentication methods. */
+ return EAGAIN;
+}
+
static krb5_error_code sss_krb5_responder(krb5_context ctx,
void *data,
krb5_responder_context rctx)
@@ -1207,9 +1245,7 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx,
struct krb5_req *kr = talloc_get_type(data, struct krb5_req);
const char * const *question_list;
size_t c;
- const char *pwd;
- int ret;
- krb5_error_code kerr;
+ krb5_error_code kerr = EINVAL;
if (kr == NULL) {
return EINVAL;
@@ -1221,34 +1257,18 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx,
for (c = 0; question_list[c] != NULL; c++) {
DEBUG(SSSDBG_TRACE_ALL, "Got question [%s].\n", question_list[c]);
+ /* It is expected that the answer_*() functions only return EOK
+ * (success) if the authentication was successful, i.e. during
+ * SSS_PAM_AUTHENTICATE. In all other cases, e.g. during
+ * SSS_PAM_PREAUTH either EAGAIN should be returned to indicate
+ * that the other available authentication methods should be
+ * checked as well. Or some other error code to indicate a fatal
+ * error where no other methods should be tried.
+ * Especially if setting the answer failed neither EOK nor EAGAIN
+ * should be returned. */
if (strcmp(question_list[c],
KRB5_RESPONDER_QUESTION_PASSWORD) == 0) {
- kr->password_prompting = true;
-
- if ((kr->pd->cmd == SSS_PAM_AUTHENTICATE
- || kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM
- || kr->pd->cmd == SSS_PAM_CHAUTHTOK)
- && sss_authtok_get_type(kr->pd->authtok)
- == SSS_AUTHTOK_TYPE_PASSWORD) {
- ret = sss_authtok_get_password(kr->pd->authtok, &pwd, NULL);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "sss_authtok_get_password failed.\n");
- return ret;
- }
-
- kerr = krb5_responder_set_answer(ctx, rctx,
- KRB5_RESPONDER_QUESTION_PASSWORD,
- pwd);
- if (kerr != 0) {
- DEBUG(SSSDBG_OP_FAILURE,
- "krb5_responder_set_answer failed.\n");
- }
-
- return kerr;
- }
-
- kerr = EOK;
+ kerr = answer_password(ctx, kr, rctx);
} else if (strcmp(question_list[c],
KRB5_RESPONDER_QUESTION_PKINIT) == 0
&& (sss_authtok_get_type(kr->pd->authtok)
@@ -1265,6 +1285,8 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx,
continue;
}
kerr = answer_passkey(ctx, kr, rctx);
+ } else if (strcmp(question_list[c], KRB5_RESPONDER_QUESTION_OTP) == 0) {
+ kerr = answer_otp(ctx, kr, rctx);
} else {
DEBUG(SSSDBG_MINOR_FAILURE, "Unknown question type [%s]\n", question_list[c]);
kerr = EINVAL;
@@ -1274,16 +1296,37 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx,
* handled by the answer_* function. This allows fallback between auth
* types, such as passkey -> password. */
if (kerr == EAGAIN) {
- DEBUG(SSSDBG_TRACE_ALL, "Auth type [%s] could not be handled by answer function, "
- "continuing to next question.\n", question_list[c]);
+ /* During pre-auth iterating over all authentication methods
+ * is expected and no message will be displayed. */
+ if (kr->pd->cmd == SSS_PAM_AUTHENTICATE) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Auth type [%s] could not be handled by answer "
+ "function, continuing to next question.\n",
+ question_list[c]);
+ }
continue;
} else {
return kerr;
}
}
+ } else {
+ kerr = answer_password(ctx, kr, rctx);
}
- return answer_otp(ctx, kr, rctx);
+ /* During SSS_PAM_PREAUTH 'EAGAIN' is expected because we will run
+ * through all offered authentication methods and all are expect to return
+ * 'EAGAIN' in the positive case to indicate that the other methods should
+ * be checked as well. If all methods are checked we are done and should
+ * return success.
+ * In the other steps, especially SSS_PAM_AUTHENTICATE, having 'EAGAIN' at
+ * this stage would mean that no method feels responsible for the provided
+ * credentials i.e. authentication failed and we should return an error.
+ */
+ if (kr->pd->cmd == SSS_PAM_PREAUTH) {
+ return kerr == EAGAIN ? 0 : kerr;
+ } else {
+ return kerr;
+ }
}
#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_SET_RESPONDER */
--
2.42.0

View File

@ -1,82 +0,0 @@
From 0344c41aca0d6fcaa33e081ed77297607e48ced4 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Fri, 15 Dec 2023 14:52:51 +0100
Subject: [PATCH] SSS_CLIENT: check if mem-cache fd was hijacked
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Real life example would be:
https://github.com/TigerVNC/tigervnc/blob/effd854bfd19654fa67ff3d39514a91a246b8ae6/unix/xserver/hw/vnc/xvnc.c#L369
- TigerVNC unconditionally overwrites fd=3
Resolves: https://github.com/SSSD/sssd/issues/6986
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
src/sss_client/nss_mc.h | 6 ++++--
src/sss_client/nss_mc_common.c | 10 ++++++++++
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/sss_client/nss_mc.h b/src/sss_client/nss_mc.h
index 9ab2736fa6..646861ba52 100644
--- a/src/sss_client/nss_mc.h
+++ b/src/sss_client/nss_mc.h
@@ -53,6 +53,8 @@ struct sss_cli_mc_ctx {
pthread_mutex_t *mutex;
#endif
int fd;
+ ino_t fd_inode;
+ dev_t fd_device;
uint32_t seed; /* seed from the tables header */
@@ -69,9 +71,9 @@ struct sss_cli_mc_ctx {
};
#if HAVE_PTHREAD
-#define SSS_CLI_MC_CTX_INITIALIZER(mtx) {UNINITIALIZED, (mtx), -1, 0, NULL, 0, NULL, 0, NULL, 0, 0}
+#define SSS_CLI_MC_CTX_INITIALIZER(mtx) {UNINITIALIZED, (mtx), -1, 0, 0, 0, NULL, 0, NULL, 0, NULL, 0, 0}
#else
-#define SSS_CLI_MC_CTX_INITIALIZER {UNINITIALIZED, -1, 0, NULL, 0, NULL, 0, NULL, 0, 0}
+#define SSS_CLI_MC_CTX_INITIALIZER {UNINITIALIZED, -1, 0, 0, 0, NULL, 0, NULL, 0, NULL, 0, 0}
#endif
errno_t sss_nss_mc_get_ctx(const char *name, struct sss_cli_mc_ctx *ctx);
diff --git a/src/sss_client/nss_mc_common.c b/src/sss_client/nss_mc_common.c
index 37119fa8d3..17683ac0e5 100644
--- a/src/sss_client/nss_mc_common.c
+++ b/src/sss_client/nss_mc_common.c
@@ -87,6 +87,12 @@ static errno_t sss_nss_mc_validate(struct sss_cli_mc_ctx *ctx)
return EINVAL;
}
+ /* FD was hijacked */
+ if ((fdstat.st_dev != ctx->fd_device) || (fdstat.st_ino != ctx->fd_inode)) {
+ ctx->fd = -1; /* don't ruin app even if it's misbehaving */
+ return EINVAL;
+ }
+
/* Invalid size. */
if (fdstat.st_size != ctx->mmap_size) {
return EINVAL;
@@ -161,6 +167,8 @@ static void sss_nss_mc_destroy_ctx(struct sss_cli_mc_ctx *ctx)
close(ctx->fd);
}
ctx->fd = -1;
+ ctx->fd_inode = 0;
+ ctx->fd_device = 0;
ctx->seed = 0;
ctx->data_table = NULL;
@@ -202,6 +210,8 @@ static errno_t sss_nss_mc_init_ctx(const char *name,
ret = EIO;
goto done;
}
+ ctx->fd_inode = fdstat.st_ino;
+ ctx->fd_device = fdstat.st_dev;
if (fdstat.st_size < MC_HEADER_SIZE) {
ret = ENOMEM;

View File

@ -0,0 +1,119 @@
From c3725a13ef694c2c34813953153f33ebfbaf1c27 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 15 Mar 2024 11:29:47 +0100
Subject: [PATCH 10/12] krb5: make sure answer_pkinit() use matching debug
messages
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves: https://github.com/SSSD/sssd/issues/7152
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
(cherry picked from commit 7c33f9d57cebfff80778f930ff0cc3144a7cc261)
---
src/providers/krb5/krb5_child.c | 77 ++++++++++++++++++---------------
1 file changed, 42 insertions(+), 35 deletions(-)
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 116f2adda..926109588 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -745,51 +745,58 @@ static krb5_error_code answer_pkinit(krb5_context ctx,
DEBUG(SSSDBG_TRACE_ALL, "Setting pkinit_prompting.\n");
kr->pkinit_prompting = true;
- if (kr->pd->cmd == SSS_PAM_AUTHENTICATE
- && (sss_authtok_get_type(kr->pd->authtok)
+ if (kr->pd->cmd == SSS_PAM_AUTHENTICATE) {
+ if ((sss_authtok_get_type(kr->pd->authtok)
== SSS_AUTHTOK_TYPE_SC_PIN
|| sss_authtok_get_type(kr->pd->authtok)
== SSS_AUTHTOK_TYPE_SC_KEYPAD)) {
- kerr = sss_authtok_get_sc(kr->pd->authtok, &pin, NULL,
- &token_name, NULL,
- &module_name, NULL,
- NULL, NULL, NULL, NULL);
- if (kerr != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "sss_authtok_get_sc failed.\n");
- goto done;
- }
+ kerr = sss_authtok_get_sc(kr->pd->authtok, &pin, NULL,
+ &token_name, NULL,
+ &module_name, NULL,
+ NULL, NULL, NULL, NULL);
+ if (kerr != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sss_authtok_get_sc failed.\n");
+ goto done;
+ }
- for (c = 0; chl->identities[c] != NULL; c++) {
- if (chl->identities[c]->identity != NULL
- && pkinit_identity_matches(chl->identities[c]->identity,
- token_name, module_name)) {
- break;
+ for (c = 0; chl->identities[c] != NULL; c++) {
+ if (chl->identities[c]->identity != NULL
+ && pkinit_identity_matches(chl->identities[c]->identity,
+ token_name, module_name)) {
+ break;
+ }
}
- }
- if (chl->identities[c] == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "No matching identity for [%s][%s] found in pkinit challenge.\n",
- token_name, module_name);
- kerr = EINVAL;
- goto done;
- }
+ if (chl->identities[c] == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "No matching identity for [%s][%s] found in pkinit "
+ "challenge.\n", token_name, module_name);
+ kerr = EINVAL;
+ goto done;
+ }
- kerr = krb5_responder_pkinit_set_answer(ctx, rctx,
- chl->identities[c]->identity,
- pin);
- if (kerr != 0) {
- DEBUG(SSSDBG_OP_FAILURE,
- "krb5_responder_set_answer failed.\n");
- }
+ kerr = krb5_responder_pkinit_set_answer(ctx, rctx,
+ chl->identities[c]->identity,
+ pin);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "krb5_responder_set_answer failed.\n");
+ }
- goto done;
+ goto done;
+ } else {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Unexpected authentication token type [%s]\n",
+ sss_authtok_type_to_str(sss_authtok_get_type(kr->pd->authtok)));
+ kerr = EAGAIN;
+ goto done;
+ }
} else {
- DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected authentication token type [%s]\n",
- sss_authtok_type_to_str(sss_authtok_get_type(kr->pd->authtok)));
+ /* We only expect SSS_PAM_PREAUTH here, but also for all other
+ * commands the graceful solution would be to let the caller
+ * check other authentication methods as well. */
kerr = EAGAIN;
- goto done;
}
done:
--
2.42.0

View File

@ -1,40 +0,0 @@
From 2bcfb7f9238c27025e99e6445e9ba799e0bde7b8 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Wed, 20 Dec 2023 09:43:48 +0100
Subject: [PATCH] SSS_CLIENT: check if reponder socket was hijacked
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Real life example would be:
https://github.com/TigerVNC/tigervnc/blob/effd854bfd19654fa67ff3d39514a91a246b8ae6/unix/xserver/hw/vnc/xvnc.c#L369
- TigerVNC unconditionally overwrites fd=3
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
src/sss_client/common.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/sss_client/common.c b/src/sss_client/common.c
index 07976fbdcd..630f4798fe 100644
--- a/src/sss_client/common.c
+++ b/src/sss_client/common.c
@@ -746,6 +746,16 @@ static enum sss_status sss_cli_check_socket(int *errnop,
myself_ino = myself_sb.st_ino;
}
+ /* check if the socket has been hijacked */
+ if (sss_cli_sd_get() != -1) {
+ ret = fstat(sss_cli_sd_get(), &mypid_sb);
+ if ((ret != 0) || (!S_ISSOCK(mypid_sb.st_mode))
+ || (mypid_sb.st_dev != sss_cli_sb->st_dev)
+ || (mypid_sb.st_ino != sss_cli_sb->st_ino)) {
+ sss_cli_sd_set(-1); /* don't ruin app even if it's misbehaving */
+ }
+ }
+
/* check if the socket has been closed on the other side */
if (sss_cli_sd_get() != -1) {
struct pollfd pfd;

View File

@ -0,0 +1,67 @@
From 87b54bd8448760241e7071a585f95b3e2604355a Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 15 Mar 2024 12:35:00 +0100
Subject: [PATCH 11/12] krb5: make prompter and pre-auth debug message less
irritating
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves: https://github.com/SSSD/sssd/issues/7152
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
(cherry picked from commit e26cc69341bcfd2bbc758eca30df296431c70a28)
---
src/providers/krb5/krb5_child.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 926109588..494711de9 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -1355,13 +1355,14 @@ static krb5_error_code sss_krb5_prompter(krb5_context context, void *data,
int ret;
size_t c;
struct krb5_req *kr = talloc_get_type(data, struct krb5_req);
+ const char *err_msg;
if (kr == NULL) {
return EINVAL;
}
DEBUG(SSSDBG_TRACE_ALL,
- "sss_krb5_prompter name [%s] banner [%s] num_prompts [%d] EINVAL.\n",
+ "sss_krb5_prompter name [%s] banner [%s] num_prompts [%d].\n",
name, banner, num_prompts);
if (num_prompts != 0) {
@@ -1370,7 +1371,12 @@ static krb5_error_code sss_krb5_prompter(krb5_context context, void *data,
prompts[c].prompt);
}
- DEBUG(SSSDBG_FUNC_DATA, "Prompter interface isn't used for password prompts by SSSD.\n");
+ err_msg = krb5_get_error_message(context, KRB5_LIBOS_CANTREADPWD);
+ DEBUG(SSSDBG_FUNC_DATA,
+ "Prompter interface isn't used for prompting by SSSD."
+ "Returning the expected error [%ld/%s].\n",
+ KRB5_LIBOS_CANTREADPWD, err_msg);
+ krb5_free_error_message(context, err_msg);
return KRB5_LIBOS_CANTREADPWD;
}
@@ -2839,8 +2845,9 @@ static errno_t tgt_req_child(struct krb5_req *kr)
* should now know which authentication methods are available to
* update the password. */
DEBUG(SSSDBG_TRACE_FUNC,
- "krb5_get_init_creds_password returned [%d] during pre-auth, "
- "ignored.\n", kerr);
+ "krb5_get_init_creds_password returned [%d] while collecting "
+ "available authentication types, errors are expected "
+ "and ignored.\n", kerr);
ret = pam_add_prompting(kr);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_prompting failed.\n");
--
2.42.0

View File

@ -1,69 +0,0 @@
From 9b73614c49aeb3cfc3208dba5f472354086180b5 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 3 Nov 2023 18:43:13 +0100
Subject: [PATCH] LDAP: make groups_by_user_send/recv public
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves: https://github.com/SSSD/sssd/issues/5708
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
src/providers/ldap/ldap_common.h | 12 ++++++++++++
src/providers/ldap/ldap_id.c | 18 +++++++++---------
2 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 1b35cbd208..6df7b3df44 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -298,6 +298,18 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
bool no_members);
int groups_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret);
+struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
+ struct tevent_context *ev,
+ struct sdap_id_ctx *ctx,
+ struct sdap_domain *sdom,
+ struct sdap_id_conn_ctx *conn,
+ const char *filter_value,
+ int filter_type,
+ const char *extra_value,
+ bool noexist_delete);
+
+int groups_by_user_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret);
+
struct tevent_req *ldap_netgroup_get_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
struct sdap_id_ctx *ctx,
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index a60aed0686..fb81a17937 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -1151,15 +1151,15 @@ static int groups_by_user_retry(struct tevent_req *req);
static void groups_by_user_connect_done(struct tevent_req *subreq);
static void groups_by_user_done(struct tevent_req *subreq);
-static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct sdap_id_ctx *ctx,
- struct sdap_domain *sdom,
- struct sdap_id_conn_ctx *conn,
- const char *filter_value,
- int filter_type,
- const char *extra_value,
- bool noexist_delete)
+struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
+ struct tevent_context *ev,
+ struct sdap_id_ctx *ctx,
+ struct sdap_domain *sdom,
+ struct sdap_id_conn_ctx *conn,
+ const char *filter_value,
+ int filter_type,
+ const char *extra_value,
+ bool noexist_delete)
{
struct tevent_req *req;
struct groups_by_user_state *state;

View File

@ -0,0 +1,70 @@
From d06b4a3eda612d1a54b6bdb3c3b779543bc23b0f Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 20 Mar 2024 11:26:16 +0100
Subject: [PATCH 12/12] pam_sss: prefer Smartcard authentication
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The current behavior is that Smartcard authentication is preferred if
possible, i.e. if a Smartcard is present. Since the Smartcard (or
equivalent) must be inserted manually the assumption is that if the user
has inserted it they most probably want to use it for authentication.
With the latest patches pam_sss might receive multiple available
authentication methods. With this patch the checks for available
authentication types start Smartcard authentication to mimic the
existing behavior.
Resolves: https://github.com/SSSD/sssd/issues/7152
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
(cherry picked from commit 0d5e8f11714e8e6cc0ad28e03fecf0f5732528b3)
---
src/sss_client/pam_sss.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index a1c353604..41a528dda 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -2544,17 +2544,7 @@ static int get_authtok_for_authentication(pam_handle_t *pamh,
} else if (pi->pc != NULL) {
ret = prompt_by_config(pamh, pi);
} else {
- 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: "),
- _("Second Factor (optional): "));
- } else {
- ret = prompt_2fa(pamh, pi, _("First Factor: "),
- _("Second Factor: "));
- }
- } else if (pi->cert_list != NULL) {
+ if (pi->cert_list != NULL) {
if (pi->cert_list->next == NULL) {
/* Only one certificate */
pi->selected_cert = pi->cert_list;
@@ -2570,6 +2560,16 @@ static int get_authtok_for_authentication(pam_handle_t *pamh,
|| (pi->flags & PAM_CLI_FLAGS_REQUIRE_CERT_AUTH)) {
/* Use pin prompt as fallback for gdm-smartcard */
ret = prompt_sc_pin(pamh, pi);
+ } else 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: "),
+ _("Second Factor (optional): "));
+ } else {
+ ret = prompt_2fa(pamh, pi, _("First Factor: "),
+ _("Second Factor: "));
+ }
} else if (pi->passkey_prompt_pin) {
ret = prompt_passkey(pamh, pi,
_("Insert your passkey device, then press ENTER."),
--
2.42.0

View File

@ -1,623 +0,0 @@
From c02e09afe9610d872121708893db8a21fb201b12 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 6 Nov 2023 18:17:28 +0100
Subject: [PATCH] ad: gpo evalute host groups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
With this patch the group-memberships of the client running SSSD are
included in the evaluation of the security filtering. Similar as in AD
the host object is more or less handled as a user object which allows
to skip some code dedicated to computers only.
Resolves: https://github.com/SSSD/sssd/issues/5708
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
src/providers/ad/ad_gpo.c | 332 +++++++++++----------------------
src/tests/cmocka/test_ad_gpo.c | 25 ++-
2 files changed, 134 insertions(+), 223 deletions(-)
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index b119aa3776..1c731b222b 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -661,6 +661,8 @@ ad_gpo_ace_includes_client_sid(const char *user_sid,
const char *host_sid,
const char **group_sids,
int group_size,
+ const char **host_group_sids,
+ int host_group_size,
struct dom_sid ace_dom_sid,
struct sss_idmap_ctx *idmap_ctx,
bool *_included)
@@ -718,6 +720,22 @@ ad_gpo_ace_includes_client_sid(const char *user_sid,
}
}
+ for (i = 0; i < host_group_size; i++) {
+ err = sss_idmap_sid_to_smb_sid(idmap_ctx, host_group_sids[i], &group_dom_sid);
+ if (err != IDMAP_SUCCESS) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "sss_idmap_sid_to_smb_sid() failed for group_sid '%s': %d\n",
+ group_sids[i], err);
+ return EFAULT;
+ }
+ included = ad_gpo_dom_sid_equal(&ace_dom_sid, group_dom_sid);
+ sss_idmap_free_smb_sid(idmap_ctx, group_dom_sid);
+ if (included) {
+ *_included = true;
+ return EOK;
+ }
+ }
+
*_included = false;
return EOK;
}
@@ -770,7 +788,9 @@ static enum ace_eval_agp_status ad_gpo_evaluate_ace(struct security_ace *ace,
const char *user_sid,
const char *host_sid,
const char **group_sids,
- int group_size)
+ int group_size,
+ const char **host_group_sids,
+ int host_group_size)
{
bool included = false;
int ret = 0;
@@ -782,9 +802,9 @@ static enum ace_eval_agp_status ad_gpo_evaluate_ace(struct security_ace *ace,
}
ret = ad_gpo_ace_includes_client_sid(user_sid, host_sid, group_sids,
- group_size, ace->trustee, idmap_ctx,
- &included);
-
+ group_size, host_group_sids,
+ host_group_size, ace->trustee,
+ idmap_ctx, &included);
if (ret != EOK) {
return AD_GPO_ACE_DENIED;
}
@@ -844,6 +864,8 @@ static errno_t ad_gpo_simple_evaluate_ace(struct security_ace *ace,
const char *host_sid,
const char **group_sids,
int group_size,
+ const char **host_group_sids,
+ int host_group_size,
uint32_t *_gpo_access_granted_status,
uint32_t *_gpo_access_denied_status)
{
@@ -856,6 +878,7 @@ static errno_t ad_gpo_simple_evaluate_ace(struct security_ace *ace,
}
ret = ad_gpo_ace_includes_client_sid(user_sid, host_sid, group_sids, group_size,
+ host_group_sids, host_group_size,
ace->trustee, idmap_ctx, &included);
if (ret != EOK || !included) {
@@ -895,6 +918,8 @@ static errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl,
const char *host_sid,
const char **group_sids,
int group_size,
+ const char **host_group_sids,
+ int host_group_size,
bool *_dacl_access_allowed)
{
uint32_t num_aces = 0;
@@ -931,6 +956,7 @@ static errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl,
ret = ad_gpo_simple_evaluate_ace(ace, idmap_ctx, user_sid, host_sid,
group_sids, group_size,
+ host_group_sids, host_group_size,
&access_granted_status,
&access_denied_status);
@@ -963,7 +989,8 @@ static errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl,
}
ace_status = ad_gpo_evaluate_ace(ace, idmap_ctx, user_sid, host_sid,
- group_sids, group_size);
+ group_sids, group_size,
+ host_group_sids, host_group_size);
switch (ace_status) {
case AD_GPO_ACE_NEUTRAL:
@@ -1016,8 +1043,9 @@ static errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl,
static errno_t
ad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx,
const char *user,
- const char *host_sid,
+ const char *host_fqdn,
struct sss_domain_info *domain,
+ struct sss_domain_info *host_domain,
struct sss_idmap_ctx *idmap_ctx,
struct gp_gpo **candidate_gpos,
int num_candidate_gpos,
@@ -1033,6 +1061,9 @@ ad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx,
const char *user_sid = NULL;
const char **group_sids = NULL;
int group_size = 0;
+ const char *host_sid = NULL;
+ const char **host_group_sids = NULL;
+ int host_group_size = 0;
int gpo_dn_idx = 0;
bool access_allowed = false;
struct gp_gpo **dacl_filtered_gpos = NULL;
@@ -1052,6 +1083,15 @@ ad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx,
goto done;
}
+ ret = ad_gpo_get_sids(tmp_ctx, host_fqdn, host_domain, &host_sid,
+ &host_group_sids, &host_group_size);
+ if (ret != EOK) {
+ ret = ERR_NO_SIDS;
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Unable to retrieve host SIDs: [%d](%s)\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
dacl_filtered_gpos = talloc_array(tmp_ctx,
struct gp_gpo *,
num_candidate_gpos + 1);
@@ -1096,7 +1136,8 @@ ad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx,
if ((sd->type & SEC_DESC_DACL_PRESENT) && (dacl != NULL)) {
ret = ad_gpo_evaluate_dacl(dacl, idmap_ctx, user_sid, host_sid,
- group_sids, group_size, &access_allowed);
+ group_sids, group_size, host_group_sids,
+ host_group_size, &access_allowed);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE,
"Could not determine if GPO is applicable\n");
@@ -1773,6 +1814,8 @@ struct ad_gpo_access_state {
int timeout;
struct sss_domain_info *user_domain;
struct sss_domain_info *host_domain;
+ const char *host_sam_account_name;
+ char *host_fqdn;
const char *user;
int gpo_timeout_option;
const char *ad_hostname;
@@ -1793,7 +1836,6 @@ static void ad_gpo_process_gpo_done(struct tevent_req *subreq);
static errno_t ad_gpo_cse_step(struct tevent_req *req);
static void ad_gpo_cse_done(struct tevent_req *subreq);
-static void ad_gpo_get_host_sid_retrieval_done(struct tevent_req *subreq);
struct tevent_req *
ad_gpo_access_send(TALLOC_CTX *mem_ctx,
@@ -1967,15 +2009,11 @@ ad_gpo_connect_done(struct tevent_req *subreq)
{
struct tevent_req *req;
struct ad_gpo_access_state *state;
- char *filter;
- const char *sam_account_name;
- char *domain_dn;
int dp_error;
errno_t ret;
char *server_uri;
LDAPURLDesc *lud;
-
- const char *attrs[] = {AD_AT_DN, AD_AT_UAC, NULL};
+ struct sdap_domain *sdom;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct ad_gpo_access_state);
@@ -2041,47 +2079,40 @@ ad_gpo_connect_done(struct tevent_req *subreq)
/* SDAP_SASL_AUTHID contains the name used for kinit and SASL bind which
* in the AD case is the NetBIOS name. */
- sam_account_name = dp_opt_get_string(state->opts->basic, SDAP_SASL_AUTHID);
- if (sam_account_name == NULL) {
+ state->host_sam_account_name = dp_opt_get_string(state->opts->basic,
+ SDAP_SASL_AUTHID);
+ if (state->host_sam_account_name == NULL) {
ret = ENOMEM;
goto done;
}
- DEBUG(SSSDBG_TRACE_FUNC, "sam_account_name is %s\n", sam_account_name);
+ DEBUG(SSSDBG_TRACE_FUNC, "sam_account_name is %s\n",
+ state->host_sam_account_name);
- /* Convert the domain name into domain DN */
- ret = domain_to_basedn(state, state->ad_domain, &domain_dn);
- if (ret != EOK) {
+ state->host_fqdn = sss_create_internal_fqname(state, state->host_sam_account_name,
+ state->host_domain->name);
+ if (state->host_fqdn == NULL) {
DEBUG(SSSDBG_OP_FAILURE,
- "Cannot convert domain name [%s] to base DN [%d]: %s\n",
- state->ad_domain, ret, sss_strerror(ret));
- goto done;
- }
-
- /* SDAP_OC_USER objectclass covers both users and computers */
- filter = talloc_asprintf(state,
- "(&(objectclass=%s)(%s=%s))",
- state->opts->user_map[SDAP_OC_USER].name,
- AD_AT_SAMACCOUNTNAME,
- sam_account_name);
- if (filter == NULL) {
+ "Failed to create fully-qualified host name.\n");
ret = ENOMEM;
goto done;
}
- subreq = sdap_get_generic_send(state, state->ev, state->opts,
- sdap_id_op_handle(state->sdap_op),
- domain_dn, LDAP_SCOPE_SUBTREE,
- filter, attrs, NULL, 0,
- state->timeout,
- false);
-
- if (subreq == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n");
+ /* AD handle computers the same as users */
+ sdom = sdap_domain_get(state->access_ctx->ad_id_ctx->sdap_id_ctx->opts,
+ state->host_domain);
+ if (sdom == NULL) {
ret = EIO;
goto done;
}
+ subreq = groups_by_user_send(state, state->ev,
+ state->access_ctx->ad_id_ctx->sdap_id_ctx,
+ sdom, state->conn,
+ state->host_fqdn,
+ BE_FILTER_NAME,
+ NULL,
+ true);
tevent_req_set_callback(subreq, ad_gpo_target_dn_retrieval_done, req);
ret = EOK;
@@ -2100,22 +2131,20 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq)
struct ad_gpo_access_state *state;
int ret;
int dp_error;
- size_t reply_count;
- struct sysdb_attrs **reply;
+ int sdap_ret;
const char *target_dn = NULL;
uint32_t uac;
- const char *attrs[] = {AD_AT_SID, NULL};
- struct ldb_message *msg;
- static const char *host_attrs[] = { SYSDB_SID_STR, NULL };
+ static const char *host_attrs[] = { SYSDB_ORIG_DN, SYSDB_AD_USER_ACCOUNT_CONTROL, SYSDB_SID_STR, NULL };
+ struct ldb_result *res = NULL;
+ const char *tmp = NULL;
+ char *endptr;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct ad_gpo_access_state);
- ret = sdap_get_generic_recv(subreq, state,
- &reply_count, &reply);
+ ret = groups_by_user_recv(subreq, &dp_error, &sdap_ret);
talloc_zfree(subreq);
if (ret != EOK) {
- ret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
- if (ret == EAGAIN && dp_error == DP_ERR_OFFLINE) {
+ if (sdap_ret == EAGAIN && dp_error == DP_ERR_OFFLINE) {
DEBUG(SSSDBG_TRACE_FUNC, "Preparing for offline operation.\n");
ret = process_offline_gpos(state,
state->user,
@@ -2144,27 +2173,25 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq)
goto done;
}
- /* make sure there is only one non-NULL reply returned */
-
- if (reply_count < 1) {
- DEBUG(SSSDBG_OP_FAILURE, "No DN retrieved for policy target.\n");
- ret = ENOENT;
- goto done;
- } else if (reply_count > 1) {
- DEBUG(SSSDBG_OP_FAILURE, "Multiple replies for policy target\n");
- ret = ERR_INTERNAL;
+ ret = sysdb_get_user_attr(state, state->host_domain,
+ state->host_fqdn,
+ host_attrs, &res);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to read host attributes.\n");
goto done;
- } else if (reply == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "reply_count is 1, but reply is NULL\n");
- ret = ERR_INTERNAL;
+ }
+ if (res->count != 1) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unexpected number [%d] of results searching "
+ "for [%s], expected 1.\n", res->count,
+ state->host_sam_account_name);
+ ret = EINVAL;
goto done;
}
- /* reply[0] holds requested attributes of single reply */
- ret = sysdb_attrs_get_string(reply[0], AD_AT_DN, &target_dn);
- if (ret != EOK) {
+ target_dn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_ORIG_DN, NULL);
+ if (target_dn == NULL) {
DEBUG(SSSDBG_OP_FAILURE,
- "sysdb_attrs_get_string failed: [%d](%s)\n",
+ "ldb_msg_find_attr_as_string failed: [%d](%s)\n",
ret, sss_strerror(ret));
goto done;
}
@@ -2174,14 +2201,29 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq)
goto done;
}
- ret = sysdb_attrs_get_uint32_t(reply[0], AD_AT_UAC, &uac);
- if (ret != EOK) {
+ tmp = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_AD_USER_ACCOUNT_CONTROL,
+ NULL);
+ if (tmp == NULL) {
DEBUG(SSSDBG_OP_FAILURE,
- "sysdb_attrs_get_uint32_t failed: [%d](%s)\n",
+ "ldb_msg_find_attr_as_string failed: [%d](%s)\n",
ret, sss_strerror(ret));
goto done;
}
+ uac = strtouint32(tmp, &endptr, 10);
+ if (errno != 0) {
+ ret = errno;
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to convert UAC [%s] into uint32_t.\n",
+ tmp);
+ goto done;
+ }
+ if (*endptr != '\0') {
+ ret = EINVAL;
+ DEBUG(SSSDBG_OP_FAILURE, "UAC [%s] is not a pure numerical value.\n",
+ tmp);
+ goto done;
+ }
+
/* we only support computer policy targets, not users */
if (!(uac & UAC_WORKSTATION_TRUST_ACCOUNT ||
uac & UAC_SERVER_TRUST_ACCOUNT)) {
@@ -2192,36 +2234,8 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq)
goto done;
}
- /* Check if computer exists in cache */
- ret = sysdb_get_computer(state, state->user_domain, state->ad_hostname,
- host_attrs, &msg);
- if (ret == ENOENT) {
- /* The computer is not in cache so query LDAP server */
- subreq = sdap_get_generic_send(state, state->ev, state->opts,
- sdap_id_op_handle(state->sdap_op),
- state->target_dn, LDAP_SCOPE_BASE,
- "(&)", attrs, NULL, 0,
- state->timeout,
- false);
-
- if (subreq == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n");
- ret = ENOMEM;
- goto done;
- }
-
- tevent_req_set_callback(subreq, ad_gpo_get_host_sid_retrieval_done, req);
- return;
- } else if (ret != EOK) {
- ret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
- goto done;
- }
-
- /* The computer exists in the cache, there is no need to query LDAP.
- * Store the retrieved host sid from cache in the state to avoid querying
- * the cache again in ad_gpo_get_sids.
- */
- state->host_sid = ldb_msg_find_attr_as_string(msg, SYSDB_SID_STR, NULL);
+ state->host_sid = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SID_STR,
+ NULL);
talloc_steal(state, state->host_sid);
subreq = ad_gpo_process_som_send(state,
@@ -2251,125 +2265,6 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq)
}
-enum ndr_err_code
-ndr_pull_dom_sid(struct ndr_pull *ndr,
- int ndr_flags,
- struct dom_sid *r);
-
-static void ad_gpo_get_host_sid_retrieval_done(struct tevent_req *subreq)
-{
- struct tevent_req *req;
- struct ad_gpo_access_state *state;
- int ret;
- int dp_error;
- size_t reply_count;
- struct sysdb_attrs **reply;
- struct ldb_message_element *el = NULL;
- enum ndr_err_code ndr_err;
- struct dom_sid host_sid;
- char *sid_str;
-
- req = tevent_req_callback_data(subreq, struct tevent_req);
- state = tevent_req_data(req, struct ad_gpo_access_state);
-
- ret = sdap_get_generic_recv(subreq, state,
- &reply_count, &reply);
- talloc_zfree(subreq);
-
- if (ret != EOK) {
- ret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
-
- DEBUG(SSSDBG_OP_FAILURE,
- "sdap_get_generic_recv failed: [%d](%s)\n",
- ret, sss_strerror(ret));
- ret = ENOENT;
- tevent_req_error(req, ret);
- return;
- }
-
- if (reply_count == 0 || !reply) {
- DEBUG(SSSDBG_OP_FAILURE,
- "sdap_get_generic_recv failed to receive host sid\n");
- ret = EIO;
- goto done;
- }
-
- /* reply[0] holds the requested attribute */
- ret = sysdb_attrs_get_el(reply[0], AD_AT_SID, &el);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "sysdb_attrs_get_el failed: [%d](%s)\n",
- ret, sss_strerror(ret));
- goto done;
- }
- if (el->num_values != 1) {
- DEBUG(SSSDBG_OP_FAILURE,
- "ad_gpo_get_host_sid_retrieval_done failed: sid not present\n");
- ret = EIO;
- goto done;
- }
-
- /* parse the dom_sid from the ldb blob */
- ndr_err = ndr_pull_struct_blob_all((DATA_BLOB*)&(el->values[0]),
- subreq, &host_sid,
- (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- DEBUG(SSSDBG_OP_FAILURE,
- "ndr_pull_struct_blob_all failed: [%d]\n",
- ndr_err);
- ret = EIO;
- goto done;
- }
-
- /* Convert the dom_sid to a sid string */
- ret = sss_idmap_smb_sid_to_sid(state->opts->idmap_ctx->map,
- &host_sid, &sid_str);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "sss_idmap_smb_sid_to_sid failed: [%d](%s)\n",
- ret, sss_strerror(ret));
- goto done;
- }
- state->host_sid = talloc_steal(state, sid_str);
-
- /* Put the sid string in the sysdb */
- ret = sysdb_set_computer(subreq, state->user_domain,
- state->ad_hostname, state->host_sid,
- state->user_domain->computer_timeout,
- time(NULL));
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "sysdb_set_computer failed: [%d](%s)\n",
- ret, sss_strerror(ret));
- goto done;
- }
-
- subreq = ad_gpo_process_som_send(state,
- state->ev,
- state->conn,
- state->ldb_ctx,
- state->sdap_op,
- state->opts,
- state->access_ctx->ad_options,
- state->timeout,
- state->target_dn,
- state->ad_domain);
- if (subreq == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- tevent_req_set_callback(subreq, ad_gpo_process_som_done, req);
-
- ret = EOK;
-
- done:
-
- if (ret != EOK) {
- tevent_req_error(req, ret);
- }
-}
-
static void
ad_gpo_process_som_done(struct tevent_req *subreq)
{
@@ -2487,8 +2382,9 @@ ad_gpo_process_gpo_done(struct tevent_req *subreq)
goto done;
}
- ret = ad_gpo_filter_gpos_by_dacl(state, state->user, state->host_sid,
+ ret = ad_gpo_filter_gpos_by_dacl(state, state->user, state->host_fqdn,
state->user_domain,
+ state->host_domain,
state->opts->idmap_ctx->map,
candidate_gpos, num_candidate_gpos,
&state->dacl_filtered_gpos,
diff --git a/src/tests/cmocka/test_ad_gpo.c b/src/tests/cmocka/test_ad_gpo.c
index 8660b05107..d49f6c54c2 100644
--- a/src/tests/cmocka/test_ad_gpo.c
+++ b/src/tests/cmocka/test_ad_gpo.c
@@ -270,6 +270,8 @@ static void test_ad_gpo_ace_includes_client_sid(const char *user_sid,
const char *host_sid,
const char **group_sids,
int group_size,
+ const char **host_group_sids,
+ int host_group_size,
struct dom_sid ace_dom_sid,
bool expected)
{
@@ -288,8 +290,9 @@ static void test_ad_gpo_ace_includes_client_sid(const char *user_sid,
assert_int_equal(err, IDMAP_SUCCESS);
ret = ad_gpo_ace_includes_client_sid(user_sid, host_sid, group_sids,
- group_size, ace_dom_sid, idmap_ctx,
- &includes_client_sid);
+ group_size, host_group_sids,
+ host_group_size, ace_dom_sid,
+ idmap_ctx, &includes_client_sid);
talloc_free(idmap_ctx);
assert_int_equal(ret, EOK);
@@ -312,8 +315,12 @@ void test_ad_gpo_ace_includes_client_sid_true(void **state)
const char *group_sids[] = {"S-1-5-21-2-3-4",
"S-1-5-21-2-3-5"};
+ int host_group_size = 0;
+ const char *host_group_sids[] = { NULL };
+
test_ad_gpo_ace_includes_client_sid(user_sid, host_sid, group_sids,
- group_size, ace_dom_sid, true);
+ group_size, host_group_sids,
+ host_group_size, ace_dom_sid, true);
}
void test_ad_gpo_ace_includes_client_sid_false(void **state)
@@ -328,8 +335,12 @@ void test_ad_gpo_ace_includes_client_sid_false(void **state)
const char *group_sids[] = {"S-1-5-21-2-3-5",
"S-1-5-21-2-3-6"};
+ int host_group_size = 0;
+ const char *host_group_sids[] = { NULL };
+
test_ad_gpo_ace_includes_client_sid(user_sid, host_sid, group_sids,
- group_size, ace_dom_sid, false);
+ group_size, host_group_sids,
+ host_group_size, ace_dom_sid, false);
}
void test_ad_gpo_ace_includes_host_sid_true(void **state)
@@ -343,8 +354,12 @@ void test_ad_gpo_ace_includes_host_sid_true(void **state)
int group_size = 0;
const char *group_sids[] = {};
+ int host_group_size = 0;
+ const char *host_group_sids[] = { NULL };
+
test_ad_gpo_ace_includes_client_sid(user_sid, host_sid, group_sids,
- group_size, ace_dom_sid, true);
+ group_size, host_group_sids,
+ host_group_size, ace_dom_sid, true);
}
uint8_t test_sid_data[] = {

View File

@ -0,0 +1,57 @@
From 163db8465e815984abac0ba9af097589045791da Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 22 Mar 2024 19:53:29 +0100
Subject: [PATCH] pam: fix storing auth types for offline auth
Before the recent patches which allow krb5_child to iterate over all
available authentication methods typically only one method was returned.
E.g. is Smartcard authentication (pkinit) was possible it was typically
the first method the in question list and the result of the
answer_pkinit() function was immediately returned. As a result only the
Smartcard authentication type was set and a missing password
authentication type while others were present might have been a
reasonable indicator for the online state.
With the recent patches, all available methods, including password
authentication if available, are return and a new indicator is needed.
---
src/responder/pam/pamsrv.h | 1 +
src/responder/pam/pamsrv_cmd.c | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
index 618836189..2aa14ae02 100644
--- a/src/responder/pam/pamsrv.h
+++ b/src/responder/pam/pamsrv.h
@@ -114,6 +114,7 @@ struct pam_resp_auth_type {
bool otp_auth;
bool cert_auth;
bool passkey_auth;
+ bool backend_returned_no_auth_type;
};
struct sss_cmd_table *get_pam_cmds(void);
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 13ba13131..94895d48e 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -915,6 +915,7 @@ errno_t pam_get_auth_types(struct pam_data *pd,
/* If the backend cannot determine which authentication types are
* available the default would be to prompt for a password. */
types.password_auth = true;
+ types.backend_returned_no_auth_type = true;
}
DEBUG(SSSDBG_TRACE_ALL, "Authentication types for user [%s] and service "
@@ -1002,7 +1003,7 @@ static errno_t pam_eval_local_auth_policy(TALLOC_CTX *mem_ctx,
}
/* Store the local auth types, in case we go offline */
- if (!auth_types.password_auth) {
+ if (!auth_types.backend_returned_no_auth_type) {
ret = set_local_auth_type(preq, sc_allow, passkey_allow);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE,
--
2.42.0

View File

@ -0,0 +1,218 @@
From e1bfbc2493c4194988acc3b2413df3dde0735ae3 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 8 Nov 2023 14:50:24 +0100
Subject: [PATCH] ad-gpo: use hash to store intermediate results
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Currently after the evaluation of a single GPO file the intermediate
results are stored in the cache and this cache entry is updated until
all applicable GPO files are evaluated. Finally the data in the cache is
used to make the decision of access is granted or rejected.
If there are two or more access-control request running in parallel one
request might overwrite the cache object with intermediate data while
another request reads the cached data for the access decision and as a
result will do this decision based on intermediate data.
To avoid this the intermediate results are not stored in the cache
anymore but in hash tables which are specific to the request. Only the
final result is written to the cache to have it available for offline
authentication.
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
(cherry picked from commit d7db7971682da2dbf7642ac94940d6b0577ec35a)
---
src/providers/ad/ad_gpo.c | 116 +++++++++++++++++++++++++++++++++-----
1 file changed, 102 insertions(+), 14 deletions(-)
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index 3d1ad39c7..b879b0a08 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -1431,6 +1431,33 @@ ad_gpo_extract_policy_setting(TALLOC_CTX *mem_ctx,
return ret;
}
+static errno_t
+add_result_to_hash(hash_table_t *hash, const char *key, char *value)
+{
+ int hret;
+ hash_key_t k;
+ hash_value_t v;
+
+ if (hash == NULL || key == NULL || value == NULL) {
+ return EINVAL;
+ }
+
+ k.type = HASH_KEY_CONST_STRING;
+ k.c_str = key;
+
+ v.type = HASH_VALUE_PTR;
+ v.ptr = value;
+
+ hret = hash_enter(hash, &k, &v);
+ if (hret != HASH_SUCCESS) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to add [%s][%s] to hash: [%s].\n",
+ key, value, hash_error_string(hret));
+ return EIO;
+ }
+
+ return EOK;
+}
+
/*
* This function parses the cse-specific (GP_EXT_GUID_SECURITY) filename,
* and stores the allow_key and deny_key of all of the gpo_map_types present
@@ -1438,6 +1465,7 @@ ad_gpo_extract_policy_setting(TALLOC_CTX *mem_ctx,
*/
static errno_t
ad_gpo_store_policy_settings(struct sss_domain_info *domain,
+ hash_table_t *allow_maps, hash_table_t *deny_maps,
const char *filename)
{
struct ini_cfgfile *file_ctx = NULL;
@@ -1571,14 +1599,14 @@ ad_gpo_store_policy_settings(struct sss_domain_info *domain,
goto done;
} else if (ret != ENOENT) {
const char *value = allow_value ? allow_value : empty_val;
- ret = sysdb_gpo_store_gpo_result_setting(domain,
- allow_key,
- value);
+ ret = add_result_to_hash(allow_maps, allow_key,
+ talloc_strdup(allow_maps, value));
if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "sysdb_gpo_store_gpo_result_setting failed for key:"
- "'%s' value:'%s' [%d][%s]\n", allow_key, allow_value,
- ret, sss_strerror(ret));
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add key: [%s] "
+ "value: [%s] to allow maps "
+ "[%d][%s].\n",
+ allow_key, value, ret,
+ sss_strerror(ret));
goto done;
}
}
@@ -1598,14 +1626,14 @@ ad_gpo_store_policy_settings(struct sss_domain_info *domain,
goto done;
} else if (ret != ENOENT) {
const char *value = deny_value ? deny_value : empty_val;
- ret = sysdb_gpo_store_gpo_result_setting(domain,
- deny_key,
- value);
+ ret = add_result_to_hash(deny_maps, deny_key,
+ talloc_strdup(deny_maps, value));
if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "sysdb_gpo_store_gpo_result_setting failed for key:"
- "'%s' value:'%s' [%d][%s]\n", deny_key, deny_value,
- ret, sss_strerror(ret));
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add key: [%s] "
+ "value: [%s] to deny maps "
+ "[%d][%s].\n",
+ deny_key, value, ret,
+ sss_strerror(ret));
goto done;
}
}
@@ -1902,6 +1930,8 @@ struct ad_gpo_access_state {
int num_cse_filtered_gpos;
int cse_gpo_index;
const char *ad_domain;
+ hash_table_t *allow_maps;
+ hash_table_t *deny_maps;
};
static void ad_gpo_connect_done(struct tevent_req *subreq);
@@ -2023,6 +2053,19 @@ ad_gpo_access_send(TALLOC_CTX *mem_ctx,
goto immediately;
}
+ ret = sss_hash_create(state, 0, &state->allow_maps);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "Could not create allow maps "
+ "hash table [%d]: %s\n", ret, sss_strerror(ret));
+ goto immediately;
+ }
+
+ ret = sss_hash_create(state, 0, &state->deny_maps);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "Could not create deny maps "
+ "hash table [%d]: %s\n", ret, sss_strerror(ret));
+ goto immediately;
+ }
subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret);
if (subreq == NULL) {
@@ -2713,6 +2756,43 @@ ad_gpo_cse_step(struct tevent_req *req)
return EAGAIN;
}
+static errno_t
+store_hash_maps_in_cache(struct sss_domain_info *domain,
+ hash_table_t *allow_maps, hash_table_t *deny_maps)
+{
+ int ret;
+ struct hash_iter_context_t *iter;
+ hash_entry_t *entry;
+ size_t c;
+ hash_table_t *hash_list[] = { allow_maps, deny_maps, NULL};
+
+
+ for (c = 0; hash_list[c] != NULL; c++) {
+ iter = new_hash_iter_context(hash_list[c]);
+ if (iter == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to create hash iterator.\n");
+ return EINVAL;
+ }
+
+ while ((entry = iter->next(iter)) != NULL) {
+ ret = sysdb_gpo_store_gpo_result_setting(domain,
+ entry->key.c_str,
+ entry->value.ptr);
+ if (ret != EOK) {
+ free(iter);
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sysdb_gpo_store_gpo_result_setting failed for key:"
+ "[%s] value:[%s] [%d][%s]\n", entry->key.c_str,
+ (char *) entry->value.ptr, ret, sss_strerror(ret));
+ return ret;
+ }
+ }
+ talloc_free(iter);
+ }
+
+ return EOK;
+}
+
/*
* This cse-specific function (GP_EXT_GUID_SECURITY) increments the
* cse_gpo_index until the policy settings for all applicable GPOs have been
@@ -2754,6 +2834,7 @@ ad_gpo_cse_done(struct tevent_req *subreq)
* (as part of the GPO Result object in the sysdb cache).
*/
ret = ad_gpo_store_policy_settings(state->host_domain,
+ state->allow_maps, state->deny_maps,
cse_filtered_gpo->policy_filename);
if (ret != EOK && ret != ENOENT) {
DEBUG(SSSDBG_OP_FAILURE,
@@ -2767,6 +2848,13 @@ ad_gpo_cse_done(struct tevent_req *subreq)
if (ret == EOK) {
/* ret is EOK only after all GPO policy files have been downloaded */
+ ret = store_hash_maps_in_cache(state->host_domain,
+ state->allow_maps, state->deny_maps);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to store evaluated GPO maps "
+ "[%d][%s].\n", ret, sss_strerror(ret));
+ goto done;
+ }
ret = ad_gpo_perform_hbac_processing(state,
state->gpo_mode,
state->gpo_map_type,
--
2.44.0

View File

@ -1,303 +0,0 @@
From ff23e7e2879f94a907d05b615dbdb547aaa2e542 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 17 Nov 2023 19:09:05 +0100
Subject: [PATCH] sysdb: remove sysdb_computer.[ch]
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The related calls are not needed anymore.
Resolves: https://github.com/SSSD/sssd/issues/5708
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
Makefile.am | 2 -
src/db/sysdb_computer.c | 185 --------------------------------------
src/db/sysdb_computer.h | 51 -----------
src/providers/ad/ad_gpo.c | 1 -
4 files changed, 239 deletions(-)
delete mode 100644 src/db/sysdb_computer.c
delete mode 100644 src/db/sysdb_computer.h
diff --git a/Makefile.am b/Makefile.am
index ead2bf7c0b..7ec14fc476 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -810,7 +810,6 @@ dist_noinst_HEADERS = \
src/db/sysdb_subid.h \
src/db/sysdb_domain_resolution_order.h \
src/db/sysdb_passkey_user_verification.h \
- src/db/sysdb_computer.h \
src/db/sysdb_iphosts.h \
src/db/sysdb_ipnetworks.h \
src/confdb/confdb.h \
@@ -1249,7 +1248,6 @@ libsss_util_la_SOURCES = \
src/db/sysdb_iphosts.c \
src/db/sysdb_ipnetworks.c \
src/util/sss_pam_data.c \
- src/db/sysdb_computer.c \
src/db/sysdb_subid.c \
src/util/util.c \
src/util/util_ext.c \
diff --git a/src/db/sysdb_computer.c b/src/db/sysdb_computer.c
deleted file mode 100644
index 9fcaf5a7c3..0000000000
--- a/src/db/sysdb_computer.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- SSSD
-
- Authors:
- Samuel Cabrero <scabrero@suse.com>
- David Mulder <dmulder@suse.com>
-
- Copyright (C) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <arpa/inet.h>
-
-#include "db/sysdb.h"
-#include "db/sysdb_private.h"
-#include "db/sysdb_computer.h"
-
-static errno_t
-sysdb_search_computer(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- const char *filter,
- const char **attrs,
- size_t *_num_hosts,
- struct ldb_message ***_hosts)
-{
- errno_t ret;
- TALLOC_CTX *tmp_ctx;
- struct ldb_message **results;
- size_t num_results;
-
- tmp_ctx = talloc_new(NULL);
- if (!tmp_ctx) {
- return ENOMEM;
- }
-
- ret = sysdb_search_custom(tmp_ctx, domain, filter,
- COMPUTERS_SUBDIR, attrs,
- &num_results, &results);
- if (ret != EOK && ret != ENOENT) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Error looking up host [%d]: %s\n",
- ret, strerror(ret));
- goto done;
- } else if (ret == ENOENT) {
- DEBUG(SSSDBG_TRACE_FUNC, "No such host\n");
- *_hosts = NULL;
- *_num_hosts = 0;
- goto done;
- }
-
- *_hosts = talloc_steal(mem_ctx, results);
- *_num_hosts = num_results;
- ret = EOK;
-
-done:
- talloc_free(tmp_ctx);
-
- return ret;
-}
-
-int
-sysdb_get_computer(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- const char *computer_name,
- const char **attrs,
- struct ldb_message **_computer)
-{
- TALLOC_CTX *tmp_ctx;
- errno_t ret;
- const char *filter;
- struct ldb_message **hosts;
- size_t num_hosts;
-
- tmp_ctx = talloc_new(NULL);
- if (!tmp_ctx) {
- return ENOMEM;
- }
-
- filter = talloc_asprintf(tmp_ctx, SYSDB_COMP_FILTER, computer_name);
- if (!filter) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = sysdb_search_computer(tmp_ctx, domain, filter, attrs,
- &num_hosts, &hosts);
- if (ret != EOK) {
- goto done;
- }
-
- if (num_hosts != 1) {
- ret = EINVAL;
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Did not find a single host with name %s\n", computer_name);
- goto done;
- }
-
- *_computer = talloc_steal(mem_ctx, hosts[0]);
- ret = EOK;
-
-done:
- talloc_free(tmp_ctx);
-
- return ret;
-}
-
-int
-sysdb_set_computer(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- const char *computer_name,
- const char *sid_str,
- int cache_timeout,
- time_t now)
-{
- TALLOC_CTX *tmp_ctx;
- int ret;
- struct sysdb_attrs *attrs;
-
- tmp_ctx = talloc_new(NULL);
- if (!tmp_ctx) {
- return ENOMEM;
- }
-
- attrs = sysdb_new_attrs(tmp_ctx);
- if (!attrs) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, sid_str);
- if (ret) goto done;
-
- ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, SYSDB_COMPUTER_CLASS);
- if (ret) goto done;
-
- ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, computer_name);
- if (ret) goto done;
-
- /* creation time */
- ret = sysdb_attrs_add_time_t(attrs, SYSDB_CREATE_TIME, now);
- if (ret) goto done;
-
- /* Set a cache expire time. There is a periodic task that cleans up
- * expired entries from the cache even when enumeration is disabled */
- ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE,
- cache_timeout ? (now + cache_timeout) : 0);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Could not set sysdb cache expire [%d]: %s\n",
- ret, strerror(ret));
- goto done;
- }
-
- ret = sysdb_store_custom(domain, computer_name, COMPUTERS_SUBDIR, attrs);
- if (ret) goto done;
-
- /* FIXME As a future improvement we have to extend domain enumeration.
- * When 'enumerate = true' for a domain, sssd starts a periodic task
- * that brings all users and groups to the cache, cleaning up
- * stale objects after each run. If enumeration is disabled, the cleanup
- * task for expired entries is started instead.
- *
- * We have to extend the enumeration task to fetch 'computer'
- * objects as well (see ad_id_enumeration_send, the entry point of the
- * enumeration task for the id provider).
- */
-done:
- if (ret) {
- DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret));
- }
- talloc_zfree(tmp_ctx);
-
- return ret;
-}
diff --git a/src/db/sysdb_computer.h b/src/db/sysdb_computer.h
deleted file mode 100644
index 4be67fdf51..0000000000
--- a/src/db/sysdb_computer.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- SSSD
-
- Authors:
- Samuel Cabrero <scabrero@suse.com>
- David Mulder <dmulder@suse.com>
-
- Copyright (C) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef SYSDB_COMPUTERS_H_
-#define SYSDB_COMPUTERS_H_
-
-#include "db/sysdb.h"
-
-#define COMPUTERS_SUBDIR "computers"
-#define SYSDB_COMPUTER_CLASS "computer"
-#define SYSDB_COMPUTERS_CONTAINER "cn="COMPUTERS_SUBDIR
-#define SYSDB_TMPL_COMPUTER_BASE SYSDB_COMPUTERS_CONTAINER","SYSDB_DOM_BASE
-#define SYSDB_TMPL_COMPUTER SYSDB_NAME"=%s,"SYSDB_TMPL_COMPUTER_BASE
-#define SYSDB_COMP_FILTER "(&("SYSDB_NAME"=%s)("SYSDB_OBJECTCLASS"="SYSDB_COMPUTER_CLASS"))"
-
-int
-sysdb_get_computer(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- const char *computer_name,
- const char **attrs,
- struct ldb_message **computer);
-
-int
-sysdb_set_computer(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- const char *computer_name,
- const char *sid_str,
- int cache_timeout,
- time_t now);
-
-#endif /* SYSDB_COMPUTERS_H_ */
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index 1c731b222b..f78f17f7b4 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -53,7 +53,6 @@
#include "util/sss_chain_id.h"
#include <ndr.h>
#include <gen_ndr/security.h>
-#include <db/sysdb_computer.h>
/* == gpo-ldap constants =================================================== */

View File

@ -1,347 +0,0 @@
From 5f63d9bfc71b271844db1ee122172630be1afed0 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 9 Jan 2024 11:14:42 +0100
Subject: [PATCH] sdap: add set_non_posix parameter
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch adds a new parameter set_non_posix to the user and group
lookup calls. Currently the domain type is used to determine if the
search should be restricted to POSIX objects or not. The new option
allows to drop this restriction explicitly to look up non-POSIX objects.
Resolves: https://github.com/SSSD/sssd/issues/5708
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
src/providers/ad/ad_gpo.c | 1 +
src/providers/ipa/ipa_subdomains_ext_groups.c | 2 +-
src/providers/ldap/ldap_common.h | 6 ++-
src/providers/ldap/ldap_id.c | 38 +++++++++++--------
src/providers/ldap/sdap_async.h | 3 +-
src/providers/ldap/sdap_async_initgroups.c | 9 +++--
src/providers/ldap/sdap_async_initgroups_ad.c | 2 +-
src/providers/ldap/sdap_async_users.c | 9 +++--
src/providers/ldap/sdap_users.h | 3 +-
9 files changed, 44 insertions(+), 29 deletions(-)
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index f78f17f7b4..336d475d19 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -2111,6 +2111,7 @@ ad_gpo_connect_done(struct tevent_req *subreq)
state->host_fqdn,
BE_FILTER_NAME,
NULL,
+ true,
true);
tevent_req_set_callback(subreq, ad_gpo_target_dn_retrieval_done, req);
diff --git a/src/providers/ipa/ipa_subdomains_ext_groups.c b/src/providers/ipa/ipa_subdomains_ext_groups.c
index b385c2f272..f4f84749a2 100644
--- a/src/providers/ipa/ipa_subdomains_ext_groups.c
+++ b/src/providers/ipa/ipa_subdomains_ext_groups.c
@@ -883,7 +883,7 @@ static void ipa_add_ad_memberships_get_next(struct tevent_req *req)
state->sdap_id_ctx->conn,
fq_name,
BE_FILTER_NAME,
- false, false);
+ false, false, false);
if (subreq == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "groups_get_send failed.\n");
ret = ENOMEM;
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 6df7b3df44..7159d63564 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -295,7 +295,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
const char *name,
int filter_type,
bool noexist_delete,
- bool no_members);
+ bool no_members,
+ bool set_non_posix);
int groups_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret);
struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
@@ -306,7 +307,8 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
const char *filter_value,
int filter_type,
const char *extra_value,
- bool noexist_delete);
+ bool noexist_delete,
+ bool set_non_posix);
int groups_by_user_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret);
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index fb81a17937..da54816bdf 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -165,7 +165,8 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
const char *filter_value,
int filter_type,
const char *extra_value,
- bool noexist_delete)
+ bool noexist_delete,
+ bool set_non_posix)
{
struct tevent_req *req;
struct users_get_state *state;
@@ -202,7 +203,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
state->filter_value = filter_value;
state->filter_type = filter_type;
- if (state->domain->type == DOM_TYPE_APPLICATION) {
+ if (state->domain->type == DOM_TYPE_APPLICATION || set_non_posix) {
state->non_posix = true;
}
@@ -582,7 +583,8 @@ static void users_get_done(struct tevent_req *subreq)
ret = sdap_fallback_local_user(state, state->shortname, uid, &usr_attrs);
if (ret == EOK) {
ret = sdap_save_user(state, state->ctx->opts, state->domain,
- usr_attrs[0], NULL, NULL, 0);
+ usr_attrs[0], NULL, NULL, 0,
+ state->non_posix);
}
}
}
@@ -665,7 +667,8 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
const char *filter_value,
int filter_type,
bool noexist_delete,
- bool no_members)
+ bool no_members,
+ bool set_non_posix)
{
struct tevent_req *req;
struct groups_get_state *state;
@@ -703,7 +706,7 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
state->filter_value = filter_value;
state->filter_type = filter_type;
- if (state->domain->type == DOM_TYPE_APPLICATION) {
+ if (state->domain->type == DOM_TYPE_APPLICATION || set_non_posix) {
state->non_posix = true;
}
@@ -991,7 +994,8 @@ static void groups_get_done(struct tevent_req *subreq)
state->filter_value,
state->filter_type,
NULL,
- state->noexist_delete);
+ state->noexist_delete,
+ false);
if (subreq == NULL) {
tevent_req_error(req, ENOMEM);
return;
@@ -1159,7 +1163,8 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
const char *filter_value,
int filter_type,
const char *extra_value,
- bool noexist_delete)
+ bool noexist_delete,
+ bool set_non_posix)
{
struct tevent_req *req;
struct groups_by_user_state *state;
@@ -1188,7 +1193,7 @@ struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
state->domain = sdom->dom;
state->sysdb = sdom->dom->sysdb;
- if (state->domain->type == DOM_TYPE_APPLICATION) {
+ if (state->domain->type == DOM_TYPE_APPLICATION || set_non_posix) {
state->non_posix = true;
}
@@ -1252,7 +1257,8 @@ static void groups_by_user_connect_done(struct tevent_req *subreq)
state->filter_value,
state->filter_type,
state->extra_value,
- state->attrs);
+ state->attrs,
+ state->non_posix);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
@@ -1421,7 +1427,8 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
ar->filter_value,
ar->filter_type,
ar->extra_value,
- noexist_delete);
+ noexist_delete,
+ false);
break;
case BE_REQ_GROUP: /* group */
@@ -1429,7 +1436,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
sdom, conn,
ar->filter_value,
ar->filter_type,
- noexist_delete, false);
+ noexist_delete, false, false);
break;
case BE_REQ_INITGROUPS: /* init groups for user */
@@ -1446,7 +1453,7 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
ar->filter_value,
ar->filter_type,
ar->extra_value,
- noexist_delete);
+ noexist_delete, false);
break;
case BE_REQ_SUBID_RANGES:
@@ -1545,7 +1552,8 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
ar->filter_value,
ar->filter_type,
ar->extra_value,
- noexist_delete);
+ noexist_delete,
+ false);
break;
default: /*fail*/
@@ -1741,7 +1749,7 @@ static struct tevent_req *get_user_and_group_send(TALLOC_CTX *memctx,
subreq = groups_get_send(req, state->ev, state->id_ctx,
state->sdom, state->conn,
state->filter_val, state->filter_type,
- state->noexist_delete, false);
+ state->noexist_delete, false, false);
if (subreq == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "groups_get_send failed.\n");
ret = ENOMEM;
@@ -1795,7 +1803,7 @@ static void get_user_and_group_groups_done(struct tevent_req *subreq)
subreq = users_get_send(req, state->ev, state->id_ctx,
state->sdom, user_conn,
state->filter_val, state->filter_type, NULL,
- state->noexist_delete);
+ state->noexist_delete, false);
if (subreq == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "users_get_send failed.\n");
tevent_req_error(req, ENOMEM);
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index 02d84672e1..f9027a776d 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -161,7 +161,8 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
const char *name,
int filter_type,
const char *extra_value,
- const char **grp_attrs);
+ const char **grp_attrs,
+ bool set_non_posix);
int sdap_get_initgr_recv(struct tevent_req *req);
struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx,
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 4c8538e8a5..97be594a38 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2735,7 +2735,8 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
const char *filter_value,
int filter_type,
const char *extra_value,
- const char **grp_attrs)
+ const char **grp_attrs,
+ bool set_non_posix)
{
struct tevent_req *req;
struct sdap_get_initgr_state *state;
@@ -2771,7 +2772,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
goto done;
}
- if (state->dom->type == DOM_TYPE_APPLICATION) {
+ if (state->dom->type == DOM_TYPE_APPLICATION || set_non_posix) {
state->non_posix = true;
}
@@ -3099,7 +3100,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
DEBUG(SSSDBG_TRACE_ALL, "Storing the user\n");
ret = sdap_save_user(state, state->opts, state->dom, state->orig_user,
- NULL, NULL, 0);
+ NULL, NULL, 0, state->non_posix);
if (ret) {
goto fail;
}
@@ -3435,7 +3436,7 @@ static void sdap_get_initgr_done(struct tevent_req *subreq)
subreq = groups_get_send(req, state->ev, state->id_ctx,
state->id_ctx->opts->sdom, state->conn,
gid, BE_FILTER_IDNUM, false,
- false);
+ false, false);
if (!subreq) {
ret = ENOMEM;
goto done;
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
index bb18f35dc3..fb80c92429 100644
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
@@ -346,7 +346,7 @@ static errno_t sdap_ad_resolve_sids_step(struct tevent_req *req)
subreq = groups_get_send(state, state->ev, state->id_ctx, sdap_domain,
state->conn, state->current_sid,
- BE_FILTER_SECID, false, true);
+ BE_FILTER_SECID, false, true, false);
if (subreq == NULL) {
return ENOMEM;
}
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index 9dcb59e233..728295d9df 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -175,7 +175,8 @@ int sdap_save_user(TALLOC_CTX *memctx,
struct sysdb_attrs *attrs,
struct sysdb_attrs *mapped_attrs,
char **_usn_value,
- time_t now)
+ time_t now,
+ bool set_non_posix)
{
struct ldb_message_element *el;
int ret;
@@ -352,7 +353,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
ret = sysdb_attrs_get_uint32_t(attrs,
opts->user_map[SDAP_AT_USER_UID].sys_name,
&uid);
- if (ret == ENOENT && dom->type == DOM_TYPE_APPLICATION) {
+ if (ret == ENOENT && (dom->type == DOM_TYPE_APPLICATION || set_non_posix)) {
DEBUG(SSSDBG_TRACE_INTERNAL,
"Marking object as non-POSIX and setting ID=0!\n");
ret = sdap_set_non_posix_flag(user_attrs,
@@ -450,7 +451,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
ret = sysdb_attrs_get_uint32_t(attrs,
opts->user_map[SDAP_AT_USER_GID].sys_name,
&gid);
- if (ret == ENOENT && dom->type == DOM_TYPE_APPLICATION) {
+ if (ret == ENOENT && (dom->type == DOM_TYPE_APPLICATION || set_non_posix)) {
DEBUG(SSSDBG_TRACE_INTERNAL,
"Marking object as non-POSIX and setting ID=0!\n");
ret = sdap_set_non_posix_flag(attrs,
@@ -696,7 +697,7 @@ int sdap_save_users(TALLOC_CTX *memctx,
usn_value = NULL;
ret = sdap_save_user(tmpctx, opts, dom, users[i], mapped_attrs,
- &usn_value, now);
+ &usn_value, now, false);
/* Do not fail completely on errors.
* Just report the failure to save and go on */
diff --git a/src/providers/ldap/sdap_users.h b/src/providers/ldap/sdap_users.h
index a6d088a6d7..74284cd0ac 100644
--- a/src/providers/ldap/sdap_users.h
+++ b/src/providers/ldap/sdap_users.h
@@ -36,6 +36,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
struct sysdb_attrs *attrs,
struct sysdb_attrs *mapped_attrs,
char **_usn_value,
- time_t now);
+ time_t now,
+ bool set_non_posix);
#endif /* _SDAP_USERS_H_ */

View File

@ -0,0 +1,49 @@
From a453f9625b40a0a1fbcf055ffa196121f2b248b5 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Date: Wed, 24 Jan 2024 23:03:04 +0100
Subject: [PATCH] tests: Drop -extensions from openssl command if there is no
-x509
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The 'openssl req' ignores the '-extensions' option without '-x509'.
OpenSSL versions prior 3.2 simply ignored it. Starting with version 3.2
an error is generated:
| /usr/bin/openssl req -batch -config
| ../../../../../src/tests/test_CA/intermediate_CA/SSSD_test_intermediate_CA.config
| -new -nodes -key
| …/build/../src/tests/test_CA/intermediate_CA/SSSD_test_intermediate_CA_key.pem
-sha256 -extensions v3_ca -out SSSD_test_intermediate_CA_req.pem
| Error adding request extensions from section v3_ca
| 003163BAB27F0000:error:11000079:X509 V3 routines:v2i_AUTHORITY_KEYID:no issuer certificate:../crypto/x509/v3_akid.c:156:
| 003163BAB27F0000:error:11000080:X509 V3 routines:X509V3_EXT_nconf_int:error in extension:../crypto/x509/v3_conf.c:48:section=v3_ca, name=authorityKeyIdentifier, value=keyid:always,issuer:always
|
Remove the '-extensions' option.
Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 32b72c7c3303edb2bf55ae9a22e8db7855f3d7d1)
---
src/tests/test_CA/intermediate_CA/Makefile.am | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/tests/test_CA/intermediate_CA/Makefile.am b/src/tests/test_CA/intermediate_CA/Makefile.am
index b439f82cb..50fcddb8d 100644
--- a/src/tests/test_CA/intermediate_CA/Makefile.am
+++ b/src/tests/test_CA/intermediate_CA/Makefile.am
@@ -33,7 +33,7 @@ SSSD_test_CA.pem:
ln -s $(builddir)/../$@
SSSD_test_intermediate_CA_req.pem: $(openssl_intermediate_ca_key) $(openssl_intermediate_ca_config) SSSD_test_CA.pem
- $(OPENSSL) req -batch -config ${openssl_intermediate_ca_config} -new -nodes -key $< -sha256 -extensions v3_ca -out $@
+ $(OPENSSL) req -batch -config ${openssl_intermediate_ca_config} -new -nodes -key $< -sha256 -out $@
SSSD_test_intermediate_CA.pem: SSSD_test_intermediate_CA_req.pem $(openssl_root_ca_config) $(openssl_root_ca_key)
cd .. && $(OPENSSL) ca -config ${openssl_root_ca_config} -batch -notext -keyfile $(openssl_root_ca_key) -in $(abs_builddir)/$< -days 200 -extensions v3_intermediate_ca -out $(abs_builddir)/$@
--
2.44.0

View File

@ -1,58 +0,0 @@
From 7cf9a1ff0e876ea0970a3f0b3c389b87be834b4f Mon Sep 17 00:00:00 2001
From: Justin Stephenson <jstephen@redhat.com>
Date: Tue, 15 Aug 2023 13:33:03 -0400
Subject: [PATCH] ipa: Add `BUILD_PASSKEY` conditional for passkey codepath
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
---
Makefile.am | 2 ++
src/providers/ipa/ipa_subdomains.c | 4 ++++
2 files changed, 6 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index 273ac1c523..c68461675f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4568,9 +4568,10 @@ if BUILD_SSH
libsss_ipa_la_SOURCES += src/providers/ipa/ipa_hostid.c
endif
+if BUILD_PASSKEY
libsss_ipa_la_SOURCES += \
src/providers/ipa/ipa_subdomains_passkey.c
-
+endif
libsss_ad_la_SOURCES = \
src/providers/ad/ad_opts.c \
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index 34cedc0362..e19343a77d 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -30,7 +30,9 @@
#include "providers/ipa/ipa_id.h"
#include "providers/ipa/ipa_opts.h"
#include "providers/ipa/ipa_config.h"
+#ifdef BUILD_PASSKEY
#include "providers/ipa/ipa_subdomains_passkey.h"
+#endif /* BUILD_PASSKEY */
#include <ctype.h>
@@ -2762,6 +2764,7 @@ static void ipa_subdomains_refresh_certmap_done(struct tevent_req *subreq)
/* Not good, but let's try to continue with other server side options */
}
+#ifdef BUILD_PASSKEY
subreq = ipa_subdomains_passkey_send(state, state->ev, state->sd_ctx,
sdap_id_op_handle(state->sdap_op));
if (subreq == NULL) {
@@ -2792,6 +2795,7 @@ static void ipa_subdomains_refresh_passkey_done(struct tevent_req *subreq)
DEBUG(SSSDBG_IMPORTANT_INFO, "Passkey feature is not configured "
"on IPA server");
}
+#endif /* BUILD_PASSKEY */
subreq = ipa_subdomains_master_send(state, state->ev, state->sd_ctx,
sdap_id_op_handle(state->sdap_op));

View File

@ -1,871 +0,0 @@
From eadee9a2a8f0dfe4f22c460537d6c87c493fa622 Mon Sep 17 00:00:00 2001
From: Justin Stephenson <jstephen@redhat.com>
Date: Mon, 14 Aug 2023 14:42:51 -0400
Subject: [PATCH] pam: Conditionalize passkey code
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
---
Makefile.am | 4 +-
src/responder/pam/pamsrv_cmd.c | 364 +----------------------------
src/responder/pam/pamsrv_passkey.c | 351 ++++++++++++++++++++++++++++
src/responder/pam/pamsrv_passkey.h | 8 +
4 files changed, 372 insertions(+), 355 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 066f5d94ee..273ac1c523 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1558,8 +1558,10 @@ sssd_pam_SOURCES = \
src/responder/pam/pam_prompting_config.c \
src/sss_client/pam_sss_prompt_config.c \
src/responder/pam/pam_helpers.c \
- src/responder/pam/pamsrv_passkey.c \
$(SSSD_RESPONDER_OBJ)
+if BUILD_PASSKEY
+ sssd_pam_SOURCES += src/responder/pam/pamsrv_passkey.c
+endif
sssd_pam_CFLAGS = \
$(AM_CFLAGS) \
$(GSSAPI_KRB5_CFLAGS) \
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 94cbf13e8d..eed283f4e9 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -50,12 +50,6 @@ struct pam_initgroup_enum_str {
const char *option;
};
-struct pam_passkey_table_data {
- hash_table_t *table;
- char *key;
- struct pk_child_user_data *data;
-};
-
struct pam_initgroup_enum_str pam_initgroup_enum_str[] = {
{ PAM_INITGR_NEVER, "never" },
{ PAM_INITGR_NO_SESSION, "no_session" },
@@ -105,10 +99,6 @@ static errno_t check_cert(TALLOC_CTX *mctx,
struct pam_auth_req *preq,
struct pam_data *pd);
-errno_t passkey_kerberos(struct pam_ctx *pctx,
- struct pam_data *pd,
- struct pam_auth_req *preq);
-
int pam_check_user_done(struct pam_auth_req *preq, int ret);
static errno_t pack_user_info_msg(TALLOC_CTX *mem_ctx,
@@ -871,228 +861,6 @@ done:
return ret;
}
-errno_t decode_pam_passkey_msg(TALLOC_CTX *mem_ctx,
- uint8_t *buf,
- size_t len,
- struct pk_child_user_data **_data)
-{
-
- size_t p = 0;
- size_t pctr = 0;
- errno_t ret;
- size_t offset;
- struct pk_child_user_data *data = NULL;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- return ENOMEM;
- }
-
- data = talloc_zero(tmp_ctx, struct pk_child_user_data);
- if (data == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "Failed to talloc passkey data.\n");
- ret = ENOMEM;
- goto done;
- }
-
- data->user_verification = talloc_strdup(data, (char *) &buf[p]);
- if (data->user_verification == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey prompt.\n");
- ret = ENOMEM;
- goto done;
- }
-
- offset = strlen(data->user_verification) + 1;
- if (offset >= len) {
- DEBUG(SSSDBG_OP_FAILURE, "passkey prompt offset failure.\n");
- ret = EIO;
- goto done;
- }
-
- data->crypto_challenge = talloc_strdup(data, (char *) &buf[p + offset]);
- if (data->crypto_challenge == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey challenge.\n");
- ret = ENOMEM;
- goto done;
- }
-
- offset += strlen(data->crypto_challenge) + 1;
- if (offset >= len) {
- DEBUG(SSSDBG_OP_FAILURE, "passkey challenge offset failure.\n");
- ret = EIO;
- goto done;
- }
-
-
- data->domain = talloc_strdup(data, (char *) &buf[p] + offset);
- if (data->domain == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey domain.\n");
- ret = ENOMEM;
- goto done;
- }
-
- offset += strlen(data->domain) + 1;
- if (offset >= len) {
- DEBUG(SSSDBG_OP_FAILURE, "passkey domain offset failure.\n");
- ret = EIO;
- goto done;
- }
-
- SAFEALIGN_COPY_UINT32(&data->num_credentials, &buf[p + offset], &pctr);
- size_t list_sz = (size_t) data->num_credentials;
-
- offset += sizeof(uint32_t);
-
- data->key_handles = talloc_zero_array(data, const char *, list_sz);
-
- for (int i = 0; i < list_sz; i++) {
- data->key_handles[i] = talloc_strdup(data->key_handles, (char *) &buf[p + offset]);
- if (data->key_handles[i] == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey list.\n");
- ret = ENOMEM;
- goto done;
- }
-
- offset += strlen(data->key_handles[i]) + 1;
- }
-
- *_data = talloc_steal(mem_ctx, data);
-
- ret = EOK;
-done:
- talloc_free(tmp_ctx);
- return ret;
-}
-
-
-errno_t save_passkey_data(TALLOC_CTX *mem_ctx,
- struct pam_ctx *pctx,
- struct pk_child_user_data *data,
- struct pam_auth_req *preq)
-{
- char *pk_key;
- errno_t ret;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- return ENOMEM;
- }
-
- /* Passkey data (pk_table_data) is stolen onto client ctx, it will
- * be freed when the client closes, and the sss_ptr_hash interface
- * takes care of automatically removing it from the hash table then */
- pctx->pk_table_data = talloc_zero(tmp_ctx, struct pam_passkey_table_data);
- if (pctx->pk_table_data == NULL) {
- return ENOMEM;
- }
-
- if (pctx->pk_table_data->table == NULL) {
- pctx->pk_table_data->table = sss_ptr_hash_create(pctx->pk_table_data,
- NULL, NULL);
- if (pctx->pk_table_data->table == NULL) {
- ret = ENOMEM;
- goto done;
- }
- }
-
- pk_key = talloc_asprintf(tmp_ctx, "%s", data->crypto_challenge);
- if (pk_key == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- pctx->pk_table_data->key = talloc_strdup(pctx->pk_table_data, pk_key);
- if (pctx->pk_table_data->key == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = sss_ptr_hash_add(pctx->pk_table_data->table, pk_key, data,
- struct pk_child_user_data);
- if (ret == EEXIST) {
- DEBUG(SSSDBG_TRACE_FUNC, "pk_table key [%s] already exists\n",
- pk_key);
- goto done;
- } else if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Unable to add pk data to hash table "
- "[%d]: %s\n", ret, sss_strerror(ret));
- goto done;
- }
-
- talloc_steal(mem_ctx, pctx->pk_table_data);
- pctx->pk_table_data->data = talloc_steal(mem_ctx, data);
-
- ret = EOK;
-
-done:
- talloc_free(tmp_ctx);
-
- return ret;
-}
-
-errno_t pam_eval_passkey_response(struct pam_ctx *pctx,
- struct pam_data *pd,
- struct pam_auth_req *preq,
- bool *_pk_preauth_done)
-{
- struct response_data *pk_resp;
- struct pk_child_user_data *pk_data;
- errno_t ret;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- return ENOMEM;
- }
-
- pk_resp = pd->resp_list;
-
- while (pk_resp != NULL) {
- switch (pk_resp->type) {
- case SSS_PAM_PASSKEY_KRB_INFO:
- if (!pctx->passkey_auth) {
- /* Passkey auth is disabled. To avoid passkey prompts appearing,
- * don't send SSS_PAM_PASSKEY_KRB_INFO to the client and
- * add a dummy response to fallback to normal auth */
- pk_resp->do_not_send_to_client = true;
- ret = pam_add_response(pd, SSS_OTP, 0, NULL);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
- goto done;
- }
- break;
- }
- ret = decode_pam_passkey_msg(tmp_ctx, pk_resp->data, pk_resp->len, &pk_data);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Failed to decode passkey msg\n");
- ret = EIO;
- goto done;
- }
-
- ret = save_passkey_data(preq->cctx, pctx, pk_data, preq);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Failed to save passkey msg\n");
- ret = EIO;
- goto done;
- }
- break;
- /* Passkey non-kerberos preauth has already run */
- case SSS_PAM_PASSKEY_INFO:
- *_pk_preauth_done = true;
- default:
- break;
- }
- pk_resp = pk_resp->next;
- }
-
- ret = EOK;
-done:
- talloc_free(tmp_ctx);
-
- return ret;
-}
void pam_reply(struct pam_auth_req *preq)
{
@@ -1342,6 +1110,7 @@ void pam_reply(struct pam_auth_req *preq)
"using defaults.\n");
}
+#ifdef BUILD_PASSKEY
ret = pam_eval_passkey_response(pctx, pd, preq, &pk_preauth_done);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Failed to eval passkey response\n");
@@ -1353,6 +1122,7 @@ void pam_reply(struct pam_auth_req *preq)
pam_check_user_done(preq, ret);
return;
}
+#endif /* BUILD_PASSKEY */
}
/*
@@ -1810,6 +1580,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
* It is checked in pam_reply() to avoid an endless loop */
preq->passkey_data_exists = true;
+#ifdef BUILD_PASSKEY
if ((pd->cmd == SSS_PAM_AUTHENTICATE)) {
if (may_do_passkey_auth(pctx, pd)) {
if (sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_PASSKEY_KRB) {
@@ -1822,6 +1593,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
}
}
}
+#endif /* BUILD_PASSKEY */
ret = pam_check_user_search(preq);
@@ -2220,6 +1992,7 @@ static void pam_forwarder_cb(struct tevent_req *req)
goto done;
}
+#ifdef BUILD_PASSKEY
/* This is set to false inside passkey_non_kerberos() if no passkey data is found.
* It is checked in pam_reply() to avoid an endless loop */
preq->passkey_data_exists = true;
@@ -2236,6 +2009,7 @@ static void pam_forwarder_cb(struct tevent_req *req)
}
}
}
+#endif /* BUILD_PASSKEY */
ret = pam_check_user_search(preq);
@@ -2557,127 +2331,6 @@ static bool pam_can_user_cache_auth(struct sss_domain_info *domain,
return result;
}
-void passkey_kerberos_cb(struct tevent_req *req)
-{
- struct pam_auth_req *preq = tevent_req_callback_data(req,
- struct pam_auth_req);
- errno_t ret = EOK;
- int child_status;
-
- ret = pam_passkey_auth_recv(req, &child_status);
- talloc_free(req);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "PAM passkey auth failed [%d]: %s\n",
- ret, sss_strerror(ret));
- goto done;
- }
-
- DEBUG(SSSDBG_TRACE_FUNC, "passkey child finished with status [%d]\n", child_status);
-
- pam_check_user_search(preq);
-
-done:
- pam_check_user_done(preq, ret);
-}
-
-errno_t passkey_kerberos(struct pam_ctx *pctx,
- struct pam_data *pd,
- struct pam_auth_req *preq)
-{
- errno_t ret;
- const char *prompt;
- const char *key;
- const char *pin;
- size_t pin_len;
- struct pk_child_user_data *data;
- struct tevent_req *req;
- int timeout;
- char *verify_opts;
- bool debug_libfido2;
- enum passkey_user_verification verification;
-
- ret = sss_authtok_get_passkey(preq, preq->pd->authtok,
- &prompt, &key, &pin, &pin_len);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Failure to get passkey authtok\n");
- return EIO;
- }
-
- if (prompt == NULL || key == NULL) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Passkey prompt and key are missing or invalid.\n");
- return EIO;
- }
-
- data = sss_ptr_hash_lookup(pctx->pk_table_data->table, key,
- struct pk_child_user_data);
- if (data == NULL) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Failed to lookup passkey authtok\n");
- return EIO;
- }
-
- ret = confdb_get_int(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY,
- CONFDB_PAM_PASSKEY_CHILD_TIMEOUT, PASSKEY_CHILD_TIMEOUT_DEFAULT,
- &timeout);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Failed to read passkey_child_timeout from confdb: [%d]: %s\n",
- ret, sss_strerror(ret));
- goto done;
- }
-
- ret = confdb_get_string(pctx->rctx->cdb, preq, CONFDB_MONITOR_CONF_ENTRY,
- CONFDB_MONITOR_PASSKEY_VERIFICATION, NULL,
- &verify_opts);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Failed to read '"CONFDB_MONITOR_PASSKEY_VERIFICATION"' from confdb: [%d]: %s\n",
- ret, sss_strerror(ret));
- goto done;
- }
-
- /* Always use verification sent from passkey krb5 plugin */
- ret = read_passkey_conf_verification(preq, verify_opts, NULL);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE, "Unable to parse passkey verificaton options.\n");
- }
-
- if (strcasecmp(data->user_verification, "false") == 0) {
- verification = PAM_PASSKEY_VERIFICATION_OFF;
- } else {
- verification = PAM_PASSKEY_VERIFICATION_ON;
- }
-
- ret = confdb_get_bool(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY,
- CONFDB_PAM_PASSKEY_DEBUG_LIBFIDO2, false,
- &debug_libfido2);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Failed to read '"CONFDB_PAM_PASSKEY_DEBUG_LIBFIDO2"' from confdb: [%d]: %s\n",
- ret, sss_strerror(ret));
- goto done;
- }
-
- req = pam_passkey_auth_send(preq->cctx, preq->cctx->ev, timeout, debug_libfido2,
- verification, pd, data, true);
- if (req == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "passkey auth send failed [%d]: [%s]\n",
- ret, sss_strerror(ret));
- goto done;
- }
-
- tevent_req_set_callback(req, passkey_kerberos_cb, preq);
-
- ret = EAGAIN;
-
-done:
-
- return ret;
-
-}
-
static void pam_dom_forwarder(struct pam_auth_req *preq)
{
int ret;
diff --git a/src/responder/pam/pamsrv_passkey.c b/src/responder/pam/pamsrv_passkey.c
index eb62db03d7..57cba845ae 100644
--- a/src/responder/pam/pamsrv_passkey.c
+++ b/src/responder/pam/pamsrv_passkey.c
@@ -32,6 +32,12 @@ struct pam_passkey_verification_enum_str {
const char *option;
};
+struct pam_passkey_table_data {
+ hash_table_t *table;
+ char *key;
+ struct pk_child_user_data *data;
+};
+
struct pam_passkey_verification_enum_str pam_passkey_verification_enum_str[] = {
{ PAM_PASSKEY_VERIFICATION_ON, "on" },
{ PAM_PASSKEY_VERIFICATION_OFF, "off" },
@@ -85,6 +91,127 @@ struct passkey_get_mapping_state {
struct cache_req_result *result;
};
+void passkey_kerberos_cb(struct tevent_req *req)
+{
+ struct pam_auth_req *preq = tevent_req_callback_data(req,
+ struct pam_auth_req);
+ errno_t ret = EOK;
+ int child_status;
+
+ ret = pam_passkey_auth_recv(req, &child_status);
+ talloc_free(req);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "PAM passkey auth failed [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, "passkey child finished with status [%d]\n", child_status);
+
+ pam_check_user_search(preq);
+
+done:
+ pam_check_user_done(preq, ret);
+}
+
+errno_t passkey_kerberos(struct pam_ctx *pctx,
+ struct pam_data *pd,
+ struct pam_auth_req *preq)
+{
+ errno_t ret;
+ const char *prompt;
+ const char *key;
+ const char *pin;
+ size_t pin_len;
+ struct pk_child_user_data *data;
+ struct tevent_req *req;
+ int timeout;
+ char *verify_opts;
+ bool debug_libfido2;
+ enum passkey_user_verification verification;
+
+ ret = sss_authtok_get_passkey(preq, preq->pd->authtok,
+ &prompt, &key, &pin, &pin_len);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failure to get passkey authtok\n");
+ return EIO;
+ }
+
+ if (prompt == NULL || key == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Passkey prompt and key are missing or invalid.\n");
+ return EIO;
+ }
+
+ data = sss_ptr_hash_lookup(pctx->pk_table_data->table, key,
+ struct pk_child_user_data);
+ if (data == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failed to lookup passkey authtok\n");
+ return EIO;
+ }
+
+ ret = confdb_get_int(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY,
+ CONFDB_PAM_PASSKEY_CHILD_TIMEOUT, PASSKEY_CHILD_TIMEOUT_DEFAULT,
+ &timeout);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failed to read passkey_child_timeout from confdb: [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = confdb_get_string(pctx->rctx->cdb, preq, CONFDB_MONITOR_CONF_ENTRY,
+ CONFDB_MONITOR_PASSKEY_VERIFICATION, NULL,
+ &verify_opts);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failed to read '"CONFDB_MONITOR_PASSKEY_VERIFICATION"' from confdb: [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ /* Always use verification sent from passkey krb5 plugin */
+ ret = read_passkey_conf_verification(preq, verify_opts, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to parse passkey verificaton options.\n");
+ }
+
+ if (strcasecmp(data->user_verification, "false") == 0) {
+ verification = PAM_PASSKEY_VERIFICATION_OFF;
+ } else {
+ verification = PAM_PASSKEY_VERIFICATION_ON;
+ }
+
+ ret = confdb_get_bool(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY,
+ CONFDB_PAM_PASSKEY_DEBUG_LIBFIDO2, false,
+ &debug_libfido2);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failed to read '"CONFDB_PAM_PASSKEY_DEBUG_LIBFIDO2"' from confdb: [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ req = pam_passkey_auth_send(preq->cctx, preq->cctx->ev, timeout, debug_libfido2,
+ verification, pd, data, true);
+ if (req == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "passkey auth send failed [%d]: [%s]\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ tevent_req_set_callback(req, passkey_kerberos_cb, preq);
+
+ ret = EAGAIN;
+
+done:
+
+ return ret;
+
+}
+
errno_t passkey_non_kerberos(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct pam_ctx *pam_ctx,
@@ -994,6 +1121,229 @@ errno_t pam_passkey_auth_recv(struct tevent_req *req,
return EOK;
}
+errno_t decode_pam_passkey_msg(TALLOC_CTX *mem_ctx,
+ uint8_t *buf,
+ size_t len,
+ struct pk_child_user_data **_data)
+{
+
+ size_t p = 0;
+ size_t pctr = 0;
+ errno_t ret;
+ size_t offset;
+ struct pk_child_user_data *data = NULL;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ data = talloc_zero(tmp_ctx, struct pk_child_user_data);
+ if (data == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to talloc passkey data.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ data->user_verification = talloc_strdup(data, (char *) &buf[p]);
+ if (data->user_verification == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey prompt.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ offset = strlen(data->user_verification) + 1;
+ if (offset >= len) {
+ DEBUG(SSSDBG_OP_FAILURE, "passkey prompt offset failure.\n");
+ ret = EIO;
+ goto done;
+ }
+
+ data->crypto_challenge = talloc_strdup(data, (char *) &buf[p + offset]);
+ if (data->crypto_challenge == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey challenge.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ offset += strlen(data->crypto_challenge) + 1;
+ if (offset >= len) {
+ DEBUG(SSSDBG_OP_FAILURE, "passkey challenge offset failure.\n");
+ ret = EIO;
+ goto done;
+ }
+
+
+ data->domain = talloc_strdup(data, (char *) &buf[p] + offset);
+ if (data->domain == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey domain.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ offset += strlen(data->domain) + 1;
+ if (offset >= len) {
+ DEBUG(SSSDBG_OP_FAILURE, "passkey domain offset failure.\n");
+ ret = EIO;
+ goto done;
+ }
+
+ SAFEALIGN_COPY_UINT32(&data->num_credentials, &buf[p + offset], &pctr);
+ size_t list_sz = (size_t) data->num_credentials;
+
+ offset += sizeof(uint32_t);
+
+ data->key_handles = talloc_zero_array(data, const char *, list_sz);
+
+ for (int i = 0; i < list_sz; i++) {
+ data->key_handles[i] = talloc_strdup(data->key_handles, (char *) &buf[p + offset]);
+ if (data->key_handles[i] == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to strdup passkey list.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ offset += strlen(data->key_handles[i]) + 1;
+ }
+
+ *_data = talloc_steal(mem_ctx, data);
+
+ ret = EOK;
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+
+errno_t save_passkey_data(TALLOC_CTX *mem_ctx,
+ struct pam_ctx *pctx,
+ struct pk_child_user_data *data,
+ struct pam_auth_req *preq)
+{
+ char *pk_key;
+ errno_t ret;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ /* Passkey data (pk_table_data) is stolen onto client ctx, it will
+ * be freed when the client closes, and the sss_ptr_hash interface
+ * takes care of automatically removing it from the hash table then */
+ pctx->pk_table_data = talloc_zero(tmp_ctx, struct pam_passkey_table_data);
+ if (pctx->pk_table_data == NULL) {
+ return ENOMEM;
+ }
+
+ if (pctx->pk_table_data->table == NULL) {
+ pctx->pk_table_data->table = sss_ptr_hash_create(pctx->pk_table_data,
+ NULL, NULL);
+ if (pctx->pk_table_data->table == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ pk_key = talloc_asprintf(tmp_ctx, "%s", data->crypto_challenge);
+ if (pk_key == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ pctx->pk_table_data->key = talloc_strdup(pctx->pk_table_data, pk_key);
+ if (pctx->pk_table_data->key == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sss_ptr_hash_add(pctx->pk_table_data->table, pk_key, data,
+ struct pk_child_user_data);
+ if (ret == EEXIST) {
+ DEBUG(SSSDBG_TRACE_FUNC, "pk_table key [%s] already exists\n",
+ pk_key);
+ goto done;
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to add pk data to hash table "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
+ talloc_steal(mem_ctx, pctx->pk_table_data);
+ pctx->pk_table_data->data = talloc_steal(mem_ctx, data);
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+
+ return ret;
+}
+
+errno_t pam_eval_passkey_response(struct pam_ctx *pctx,
+ struct pam_data *pd,
+ struct pam_auth_req *preq,
+ bool *_pk_preauth_done)
+{
+ struct response_data *pk_resp;
+ struct pk_child_user_data *pk_data;
+ errno_t ret;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ pk_resp = pd->resp_list;
+
+ while (pk_resp != NULL) {
+ switch (pk_resp->type) {
+ case SSS_PAM_PASSKEY_KRB_INFO:
+ if (!pctx->passkey_auth) {
+ /* Passkey auth is disabled. To avoid passkey prompts appearing,
+ * don't send SSS_PAM_PASSKEY_KRB_INFO to the client and
+ * add a dummy response to fallback to normal auth */
+ pk_resp->do_not_send_to_client = true;
+ ret = pam_add_response(pd, SSS_OTP, 0, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
+ goto done;
+ }
+ break;
+ }
+ ret = decode_pam_passkey_msg(tmp_ctx, pk_resp->data, pk_resp->len, &pk_data);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to decode passkey msg\n");
+ ret = EIO;
+ goto done;
+ }
+
+ ret = save_passkey_data(preq->cctx, pctx, pk_data, preq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to save passkey msg\n");
+ ret = EIO;
+ goto done;
+ }
+ break;
+ /* Passkey non-kerberos preauth has already run */
+ case SSS_PAM_PASSKEY_INFO:
+ *_pk_preauth_done = true;
+ default:
+ break;
+ }
+ pk_resp = pk_resp->next;
+ }
+
+ ret = EOK;
+done:
+ talloc_free(tmp_ctx);
+
+ return ret;
+}
+
static void
pam_passkey_auth_done(int child_status,
struct tevent_signal *sige,
diff --git a/src/responder/pam/pamsrv_passkey.h b/src/responder/pam/pamsrv_passkey.h
index 6b0d62071f..7c5a532e91 100644
--- a/src/responder/pam/pamsrv_passkey.h
+++ b/src/responder/pam/pamsrv_passkey.h
@@ -23,6 +23,7 @@
#include <security/pam_appl.h>
#include "util/util.h"
+#include "util/sss_ptr_hash.h"
#include "responder/common/responder.h"
#include "responder/common/cache_req/cache_req.h"
#include "responder/pam/pamsrv.h"
@@ -40,6 +41,9 @@ errno_t passkey_non_kerberos(TALLOC_CTX *mem_ctx,
struct pam_ctx *pam_ctx,
struct pam_auth_req *preq,
struct pam_data *pd);
+errno_t passkey_kerberos(struct pam_ctx *pctx,
+ struct pam_data *pd,
+ struct pam_auth_req *preq);
struct pk_child_user_data {
/* Both Kerberos and non-kerberos */
@@ -69,6 +73,10 @@ struct tevent_req *pam_passkey_auth_send(TALLOC_CTX *mem_ctx,
bool kerberos_pa);
errno_t pam_passkey_auth_recv(struct tevent_req *req,
int *child_status);
+errno_t pam_eval_passkey_response(struct pam_ctx *pctx,
+ struct pam_data *pd,
+ struct pam_auth_req *preq,
+ bool *_pk_preauth_done);
bool may_do_passkey_auth(struct pam_ctx *pctx,
struct pam_data *pd);

View File

@ -1,79 +0,0 @@
From a20dadc7ec9b21687356d1b0b0218db89f438c67 Mon Sep 17 00:00:00 2001
From: Justin Stephenson <jstephen@redhat.com>
Date: Tue, 15 Aug 2023 16:27:39 -0400
Subject: [PATCH] Makefile: Respect `BUILD_PASSKEY` conditional
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
---
Makefile.am | 11 ++++++++---
src/providers/krb5/krb5_child.c | 5 +++++
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index a3952ce78d..066f5d94ee 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1315,7 +1315,9 @@ endif
if BUILD_SYSTEMTAP
libsss_util_la_LIBADD += stap_generated_probes.lo
endif
+if BUILD_PASSKEY
libsss_util_la_SOURCES += src/db/sysdb_passkey_user_verification.c
+endif # BUILD_PASSKEY
libsss_util_la_LDFLAGS = -avoid-version
pkglib_LTLIBRARIES += libsss_semanage.la
@@ -2616,7 +2618,6 @@ pam_srv_tests_SOURCES = \
src/responder/pam/pamsrv_cmd.c \
src/responder/pam/pamsrv_p11.c \
src/responder/pam/pamsrv_gssapi.c \
- src/responder/pam/pamsrv_passkey.c \
src/responder/pam/pam_helpers.c \
src/responder/pam/pamsrv_dp.c \
src/responder/pam/pam_prompting_config.c \
@@ -2650,6 +2651,9 @@ pam_srv_tests_LDADD = \
libsss_iface.la \
libsss_sbus.la \
$(NULL)
+if BUILD_PASSKEY
+ pam_srv_tests_SOURCES += src/responder/pam/pamsrv_passkey.c
+endif # BUILD_PASSKEY
EXTRA_ssh_srv_tests_DEPENDENCIES = \
$(ldblib_LTLIBRARIES) \
@@ -4656,8 +4660,10 @@ krb5_child_SOURCES = \
src/sss_client/common.c \
src/krb5_plugin/common/utils.c \
src/krb5_plugin/idp/idp_utils.c \
- src/krb5_plugin/passkey/passkey_utils.c \
$(NULL)
+if BUILD_PASSKEY
+ krb5_child_SOURCES += src/krb5_plugin/passkey/passkey_utils.c
+endif # BUILD_PASSKEY
krb5_child_CFLAGS = \
$(AM_CFLAGS) \
$(POPT_CFLAGS) \
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index a3d83b4c8c..7e43042bff 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -999,6 +999,10 @@ static krb5_error_code answer_passkey(krb5_context kctx,
struct krb5_req *kr,
krb5_responder_context rctx)
{
+#ifndef BUILD_PASSKEY
+ DEBUG(SSSDBG_TRACE_FUNC, "Passkey auth not possible, SSSD built without passkey support!\n");
+ return EINVAL;
+#else
enum sss_authtok_type type;
struct sss_passkey_message *msg;
struct sss_passkey_message *reply_msg = NULL;
@@ -1090,6 +1094,7 @@ done:
}
return kerr;
+#endif /* BUILD_PASSKEY */
}
static krb5_error_code sss_krb5_responder(krb5_context ctx,

View File

@ -26,50 +26,29 @@
%global samba_package_version %(rpm -q samba-devel --queryformat %{version}-%{release}) %global samba_package_version %(rpm -q samba-devel --queryformat %{version}-%{release})
Name: sssd Name: sssd
Version: 2.9.1 Version: 2.9.4
Release: 4%{?dist}.5.alma.1 Release: 6%{?dist}
Summary: System Security Services Daemon Summary: System Security Services Daemon
License: GPLv3+ License: GPLv3+
URL: https://github.com/SSSD/sssd/ URL: https://github.com/SSSD/sssd/
Source0: https://github.com/SSSD/sssd/releases/download/%{version}/sssd-%{version}.tar.gz Source0: https://github.com/SSSD/sssd/releases/download/%{version}/sssd-%{version}.tar.gz
### Patches ### ### Patches ###
Patch0001: 0001-watchdog-add-arm_watchdog-and-disarm_watchdog-calls.patch Patch0001: 0001-sssd-adding-mail-as-case-insensitive.patch
Patch0002: 0002-sbus-arm-watchdog-for-sbus_connect_init_send.patch Patch0002: 0002-sdap-add-search_bases-option-to-groups_by_user_send.patch
Patch0003: 0003-sdap-add-naming_context-as-new-member-of-struct-sdap.patch
# Patches were taken from: Patch0004: 0004-pam-fix-SC-auth-with-multiple-certs-and-missing-logi.patch
# https://github.com/SSSD/sssd/commit/641e5f73d3bd5b3d32cafd551013d3bfd2a52732 Patch0005: 0005-sss-client-handle-key-value-in-destructor.patch
Patch0003: 0003-mc-recover-from-invalid-memory-cache-size.patch Patch0006: 0006-krb5-Allow-fallback-between-responder-questions.patch
# https://github.com/SSSD/sssd/commit/1e5dfc187c7659cca567d2f7d5592e72794ef13c Patch0007: 0007-krb5-Add-fallback-password-change-support.patch
Patch0004: 0004-sss_iface-do-not-add-cli_id-to-chain-key.patch Patch0008: 0008-pam-fix-invalid-if-condition.patch
# https://github.com/SSSD/sssd/commit/74d0f4538deb766592079b1abca0d949d6dea105 Patch0009: 0009-krb5-add-OTP-to-krb5-response-selection.patch
Patch0005: 0005-Accept-krb5-1.21-for-building-the-PAC-plugin.patch Patch0010: 0010-krb5-make-sure-answer_pkinit-use-matching-debug-mess.patch
# https://github.com/SSSD/sssd/commit/88d8afbb115f18007dcc11f7ebac1b238c3ebd98 Patch0011: 0011-krb5-make-prompter-and-pre-auth-debug-message-less-i.patch
Patch0006: 0006-MC-a-couple-of-additions-to-recover-from-invalid-memory.patch Patch0012: 0012-pam_sss-prefer-Smartcard-authentication.patch
# https://github.com/SSSD/sssd/commit/b0212b04f109875936612a52a7b30a80e5a85ee5 Patch0013: 0013-pam-fix-storing-auth-types-for-offline-auth.patch
Patch0007: 0007-SSS_CLIENT-replace-__thread-with-pthread_-specific.patch Patch0014: 0014-ad-gpo-use-hash-to-store-intermediate-results.patch
# https://github.com/SSSD/sssd/commit/39cd0baa06742b349ed763aa40ea4de366e80f1a Patch0015: 0015-tests-Drop-extensions-from-openssl-command-if-there-.patch
Patch0008: 0008-DP-reduce-log-level-in-case-a-responder-asks.patch
# https://github.com/SSSD/sssd/commit/958a5e25c447dc502e8f8fbecf3253e62f92b0b2
Patch0009: 0009-SSS_CLIENT-MC-in-case-mem-cache-file-validation-fails.patch
# https://github.com/SSSD/sssd/commit/0344c41aca0d6fcaa33e081ed77297607e48ced4
Patch0010: 0010-SSS_CLIENT-check-if-mem-cache-fd-was-hijacked.patch
# https://github.com/SSSD/sssd/commit/2bcfb7f9238c27025e99e6445e9ba799e0bde7b8
Patch0011: 0011-SSS_CLIENT-check-if-reponder-socket-was-hijacked.patch
# https://github.com/SSSD/sssd/commit/9b73614c49aeb3cfc3208dba5f472354086180b5
Patch0012: 0012-LDAP-make-groups_by_user_send-recv-public.patch
# https://github.com/SSSD/sssd/commit/c02e09afe9610d872121708893db8a21fb201b12
Patch0013: 0013-ad-gpo-evalute-host-groups.patch
# https://github.com/SSSD/sssd/commit/ff23e7e2879f94a907d05b615dbdb547aaa2e542
Patch0014: 0014-sysdb-remove-sysdb_computer.ch.patch
# https://github.com/SSSD/sssd/commit/5f63d9bfc71b271844db1ee122172630be1afed0
Patch0015: 0015-sdap-add-set_non_posix-parameter.patch
# https://github.com/SSSD/sssd/commit/7cf9a1ff0e876ea0970a3f0b3c389b87be834b4f
Patch0016: 0016-ipa-Add-BUILD_PASSKEY-conditional-for-passkey-codepath.patch
# https://github.com/SSSD/sssd/commit/eadee9a2a8f0dfe4f22c460537d6c87c493fa622
Patch0017: 0017-pam-Conditionalize-passkey-code.patch
# https://github.com/SSSD/sssd/commit/a20dadc7ec9b21687356d1b0b0218db89f438c67
Patch0018: 0018-Makefile-Respect-BUILD_PASSKEY-conditional.patch
### Dependencies ### ### Dependencies ###
@ -119,6 +98,7 @@ BuildRequires: krb5-devel
BuildRequires: krb5-libs >= 1.18.2-11 BuildRequires: krb5-libs >= 1.18.2-11
BuildRequires: libcmocka-devel >= 1.0.0 BuildRequires: libcmocka-devel >= 1.0.0
BuildRequires: libdhash-devel >= 0.4.2 BuildRequires: libdhash-devel >= 0.4.2
BuildRequires: libfido2-devel
BuildRequires: libini_config-devel >= 1.1 BuildRequires: libini_config-devel >= 1.1
BuildRequires: libldb-devel >= %{ldb_version} BuildRequires: libldb-devel >= %{ldb_version}
BuildRequires: libnfsidmap-devel BuildRequires: libnfsidmap-devel
@ -359,6 +339,7 @@ identity data from and authenticate against an Active Directory server.
Summary: The proxy back end of the SSSD Summary: The proxy back end of the SSSD
License: GPLv3+ License: GPLv3+
Requires: sssd-common = %{version}-%{release} Requires: sssd-common = %{version}-%{release}
Requires: libsss_certmap = %{version}-%{release}
%description proxy %description proxy
Provides the proxy back end which can be used to wrap an existing NSS and/or Provides the proxy back end which can be used to wrap an existing NSS and/or
@ -527,6 +508,16 @@ This package provides Kerberos plugins that are required to enable
authentication against external identity providers. Additionally a helper authentication against external identity providers. Additionally a helper
program to handle the OAuth 2.0 Device Authorization Grant is provided. program to handle the OAuth 2.0 Device Authorization Grant is provided.
%package passkey
Summary: SSSD helpers and plugins needed for authentication with passkey token
License: GPLv3+
Requires: sssd-common = %{version}-%{release}
Requires: libfido2
%description passkey
This package provides helper processes and Kerberos plugins that are required to
enable authentication with passkey token.
%prep %prep
%autosetup -p1 %autosetup -p1
@ -558,6 +549,7 @@ autoreconf -ivf
--with-subid \ --with-subid \
--with-files-provider \ --with-files-provider \
--with-libsifp \ --with-libsifp \
--with-passkey \
%if 0%{?fedora} %if 0%{?fedora}
--disable-polkit-rules-path \ --disable-polkit-rules-path \
%endif %endif
@ -602,6 +594,10 @@ cp $RPM_BUILD_ROOT/%{_datadir}/sssd-kcm/kcm_default_ccache \
cp $RPM_BUILD_ROOT/%{_datadir}/sssd/krb5-snippets/sssd_enable_idp \ cp $RPM_BUILD_ROOT/%{_datadir}/sssd/krb5-snippets/sssd_enable_idp \
$RPM_BUILD_ROOT/%{_sysconfdir}/krb5.conf.d/sssd_enable_idp $RPM_BUILD_ROOT/%{_sysconfdir}/krb5.conf.d/sssd_enable_idp
# Enable krb5 passkey plugins by default (when sssd-passkey package is installed)
cp $RPM_BUILD_ROOT/%{_datadir}/sssd/krb5-snippets/sssd_enable_passkey \
$RPM_BUILD_ROOT/%{_sysconfdir}/krb5.conf.d/sssd_enable_passkey
# krb5 configuration snippet # krb5 configuration snippet
cp $RPM_BUILD_ROOT/%{_datadir}/sssd/krb5-snippets/enable_sssd_conf_dir \ cp $RPM_BUILD_ROOT/%{_datadir}/sssd/krb5-snippets/enable_sssd_conf_dir \
$RPM_BUILD_ROOT/%{_sysconfdir}/krb5.conf.d/enable_sssd_conf_dir $RPM_BUILD_ROOT/%{_sysconfdir}/krb5.conf.d/enable_sssd_conf_dir
@ -1007,6 +1003,12 @@ done
%{_datadir}/sssd/krb5-snippets/sssd_enable_idp %{_datadir}/sssd/krb5-snippets/sssd_enable_idp
%config(noreplace) %{_sysconfdir}/krb5.conf.d/sssd_enable_idp %config(noreplace) %{_sysconfdir}/krb5.conf.d/sssd_enable_idp
%files passkey
%attr(755,%{sssd_user},%{sssd_user}) %{_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
%if 0%{?rhel} %if 0%{?rhel}
%pre common %pre common
getent group sssd >/dev/null || groupadd -r sssd getent group sssd >/dev/null || groupadd -r sssd
@ -1096,27 +1098,52 @@ fi
%systemd_postun_with_restart sssd.service %systemd_postun_with_restart sssd.service
%changelog %changelog
* Thu Jan 25 2024 Eduard Abdullin <eabdullin@almalinux.org> - 2.9.1-4.5.alma.1 * Thu Apr 18 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.4-6
- Apply 0008-DP-reduce-log-level-in-case-a-responder-asks.patch - Resolves: RHEL-27209 - Race condition during authorization leads to GPO policies functioning inconsistently [rhel-9.4.0]
- Apply 0009-SSS_CLIENT-MC-in-case-mem-cache-file-validation-fails.patch
- Apply 0010-SSS_CLIENT-check-if-mem-cache-fd-was-hijacked.patch
- Apply 0011-SSS_CLIENT-check-if-reponder-socket-was-hijacked.patch
- Apply 0012-LDAP-make-groups_by_user_send-recv-public.patch
- Apply 0013-ad-gpo-evalute-host-groups.patch
- Apply 0014-sysdb-remove-sysdb_computer.ch.patch
- Apply 0015-sdap-add-set_non_posix-parameter.patch
- Apply 0016-ipa-Add-BUILD_PASSKEY-conditional-for-passkey-codepath.patch
- Apply 0017-pam-Conditionalize-passkey-code.patch
- Apply 0018-Makefile-Respect-BUILD_PASSKEY-conditional.patch
* Wed Dec 13 2023 Eduard Abdullin <eabdullin@almalinux.org> - 2.9.1-4.1.alma.1 * Mon Mar 25 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.4-5
- Apply 0007-SSS_CLIENT-replace-__thread-with-pthread_-specific.patch - Resolves: RHEL-28161 - Passkey cannot fall back to password
* Thu Mar 21 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.4-4
- Resolves: RHEL-28161 - Passkey cannot fall back to password
* Wed Mar 13 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.4-3
- Resolves: RHEL-22340 - socket leak
- Resolves: RHEL-28161 - Passkey cannot fall back to password
* Mon Feb 12 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.4-2
- Resolves: RHEL-12503 - AD users are unable to log in due to case sensitivity of user because the domain is found as an alias to the email address.
- Resolves: RHEL-22288 - ssh pubkey stored in ldap/AD no longer works to authenticate via sssd
- Resolves: RHEL-22194 - gdm smartcard login fails with sssd-2.9.3 in case of multiple identities
* Fri Jan 12 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.4-1
- Resolves: RHEL-2632 - Rebase SSSD for RHEL 9.4
- Resolves: RHEL-18395 - latest sssd breaks logging in via XDMCP for LDAP/Kerberos users
- Resolves: RHEL-17498 - New sssd.conf seems not to be backwards compatible (wrt SmartCard auth of local users using 'files provider') [rhel-9]
- Resolves: RHEL-21079 - SSSD GPO lacks group resolution on hosts [rhel-9]
- Resolves: RHEL-19211 - Excessive logging to sssd_nss and sssd_be in multi-domain AD forest [rhel-9]
* Mon Nov 13 2023 Alexey Tikhonov <atikhono@redhat.com> - 2.9.3-2
- Resolves: RHEL-2632 - Rebase SSSD for RHEL 9.4
* Mon Nov 13 2023 Alexey Tikhonov <atikhono@redhat.com> - 2.9.3-1
- Resolves: RHEL-2632 - Rebase SSSD for RHEL 9.4
- Resolves: RHEL-14427 - Expected cn in RDN, got uid
- Resolves: RHEL-12229 - HANA validation on RHEL 9.2 issue possibly related to libc/nss_sss behaviour
- Resolves: RHEL-3925 - SSSD goes offline when, while reading a single user, misses a required attribute (i.e. SID)
- Resolves: RHEL-2319 - Passkey authentication for centrally managed users
- Resolves: RHEL-4146 - Incorrect handling of reverse IPv6 update results in update failure
- Resolves: RHEL-4971 - sssd-kcm does not appear to expire Kerberos tickets (RFE: sssd_kcm should have the option to automatically delete the expired tickets)
* Thu Oct 5 2023 Alexey Tikhonov <atikhono@redhat.com> - 2.9.2-2
- Resolves: RHEL-2319 - Passkey authentication for centrally managed users
* Fri Sep 8 2023 Alexey Tikhonov <atikhono@redhat.com> - 2.9.2-1
- Resolves: RHEL-2632 - Rebase SSSD for RHEL 9.4
- Resolves: RHEL-2319 - Passkey authentication for centrally managed users
- Resolves: rhbz#2234829 - SSSD runs multiples lookup search for each NFS request (SBUS req chaining stopped working)
- Resolves: rhbz#2236119 - dbus and crond getting terminated with SIGBUS in sss_client code
* Wed Nov 08 2023 Eduard Abdullin <eabdullin@almalinux.org> - 2.9.1-4.alma.1
- Apply 0003-mc-recover-from-invalid-memory-cache-size.patch
- Apply 0004-sss_iface-do-not-add-cli_id-to-chain-key.patch
- Apply 0005-Accept-krb5-1.21-for-building-the-PAC-plugin.patch
- Apply 0006-MC-a-couple-of-additions-to-recover-from-invalid-memory.patch
* Mon Jul 10 2023 Alexey Tikhonov <atikhono@redhat.com> - 2.9.1-2 * Mon Jul 10 2023 Alexey Tikhonov <atikhono@redhat.com> - 2.9.1-2
- Resolves: rhbz#2218858 - [sssd] SSSD enters failed state after heavy load in the system - Resolves: rhbz#2218858 - [sssd] SSSD enters failed state after heavy load in the system