import CS sssd-2.9.4-6.el9_4
This commit is contained in:
		
							parent
							
								
									c31b9d577e
								
							
						
					
					
						commit
						5a0b01d98a
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1 +1 @@ | |||||||
| SOURCES/sssd-2.9.1.tar.gz | SOURCES/sssd-2.9.4.tar.gz | ||||||
|  | |||||||
| @ -1 +1 @@ | |||||||
| 5eb0d3e600aed685a7e3ea49154dadef52361f84 SOURCES/sssd-2.9.1.tar.gz | 574f6cec9ee12dd943e4305286845343ab7bb891 SOURCES/sssd-2.9.4.tar.gz | ||||||
|  | |||||||
							
								
								
									
										144
									
								
								SOURCES/0001-sssd-adding-mail-as-case-insensitive.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								SOURCES/0001-sssd-adding-mail-as-case-insensitive.patch
									
									
									
									
									
										Normal 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 | ||||||
|  | 
 | ||||||
| @ -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 |  | ||||||
| 
 |  | ||||||
| @ -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 |  | ||||||
| 
 |  | ||||||
| @ -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 | ||||||
|  | 
 | ||||||
| @ -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 | ||||||
|  | 
 | ||||||
| @ -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 | ||||||
|  | 
 | ||||||
							
								
								
									
										50
									
								
								SOURCES/0005-sss-client-handle-key-value-in-destructor.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								SOURCES/0005-sss-client-handle-key-value-in-destructor.patch
									
									
									
									
									
										Normal 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 | ||||||
|  | 
 | ||||||
| @ -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 | ||||||
|  | 
 | ||||||
							
								
								
									
										206
									
								
								SOURCES/0007-krb5-Add-fallback-password-change-support.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								SOURCES/0007-krb5-Add-fallback-password-change-support.patch
									
									
									
									
									
										Normal 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 | ||||||
|  | 
 | ||||||
							
								
								
									
										30
									
								
								SOURCES/0008-pam-fix-invalid-if-condition.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								SOURCES/0008-pam-fix-invalid-if-condition.patch
									
									
									
									
									
										Normal 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 | ||||||
|  | 
 | ||||||
							
								
								
									
										185
									
								
								SOURCES/0009-krb5-add-OTP-to-krb5-response-selection.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								SOURCES/0009-krb5-add-OTP-to-krb5-response-selection.patch
									
									
									
									
									
										Normal 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 | ||||||
|  | 
 | ||||||
| @ -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 | ||||||
|  | 
 | ||||||
| @ -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 | ||||||
|  | 
 | ||||||
							
								
								
									
										70
									
								
								SOURCES/0012-pam_sss-prefer-Smartcard-authentication.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								SOURCES/0012-pam_sss-prefer-Smartcard-authentication.patch
									
									
									
									
									
										Normal 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 | ||||||
|  | 
 | ||||||
| @ -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 | ||||||
|  | 
 | ||||||
							
								
								
									
										218
									
								
								SOURCES/0014-ad-gpo-use-hash-to-store-intermediate-results.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								SOURCES/0014-ad-gpo-use-hash-to-store-intermediate-results.patch
									
									
									
									
									
										Normal 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 | ||||||
|  | 
 | ||||||
| @ -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 | ||||||
|  | 
 | ||||||
| @ -26,16 +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: 2%{?dist} | 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 | ||||||
|  | Patch0004: 0004-pam-fix-SC-auth-with-multiple-certs-and-missing-logi.patch | ||||||
|  | Patch0005: 0005-sss-client-handle-key-value-in-destructor.patch | ||||||
|  | Patch0006: 0006-krb5-Allow-fallback-between-responder-questions.patch | ||||||
|  | Patch0007: 0007-krb5-Add-fallback-password-change-support.patch | ||||||
|  | Patch0008: 0008-pam-fix-invalid-if-condition.patch | ||||||
|  | Patch0009: 0009-krb5-add-OTP-to-krb5-response-selection.patch | ||||||
|  | Patch0010: 0010-krb5-make-sure-answer_pkinit-use-matching-debug-mess.patch | ||||||
|  | Patch0011: 0011-krb5-make-prompter-and-pre-auth-debug-message-less-i.patch | ||||||
|  | Patch0012: 0012-pam_sss-prefer-Smartcard-authentication.patch | ||||||
|  | Patch0013: 0013-pam-fix-storing-auth-types-for-offline-auth.patch | ||||||
|  | Patch0014: 0014-ad-gpo-use-hash-to-store-intermediate-results.patch | ||||||
|  | Patch0015: 0015-tests-Drop-extensions-from-openssl-command-if-there-.patch | ||||||
| 
 | 
 | ||||||
| ### Dependencies ### | ### Dependencies ### | ||||||
| 
 | 
 | ||||||
| @ -85,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 | ||||||
| @ -325,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 | ||||||
| @ -493,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 | ||||||
| 
 | 
 | ||||||
| @ -524,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 | ||||||
| @ -568,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 | ||||||
| @ -973,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 | ||||||
| @ -1062,6 +1098,53 @@ fi | |||||||
| %systemd_postun_with_restart sssd.service | %systemd_postun_with_restart sssd.service | ||||||
| 
 | 
 | ||||||
| %changelog | %changelog | ||||||
|  | * Thu Apr 18 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.4-6 | ||||||
|  | - Resolves: RHEL-27209 - Race condition during authorization leads to GPO policies functioning inconsistently [rhel-9.4.0] | ||||||
|  | 
 | ||||||
|  | * Mon Mar 25 2024 Alexey Tikhonov <atikhono@redhat.com> - 2.9.4-5 | ||||||
|  | - 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 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| * 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 | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user