diff --git a/SOURCES/0044-kdb-apply-combinatorial-logic-for-ticket-flags.patch b/SOURCES/0044-kdb-apply-combinatorial-logic-for-ticket-flags.patch
new file mode 100644
index 0000000..7f219df
--- /dev/null
+++ b/SOURCES/0044-kdb-apply-combinatorial-logic-for-ticket-flags.patch
@@ -0,0 +1,622 @@
+From 5b83cb4769a61068ad02cacc455c51fe3cc28b6f Mon Sep 17 00:00:00 2001
+From: Julien Rische <jrische@redhat.com>
+Date: Mon, 25 Mar 2024 18:25:52 +0200
+Subject: [PATCH] kdb: apply combinatorial logic for ticket flags
+
+The initial design for ticket flags was implementing this logic:
+* If a ticket policy is defined for the principal entry, use flags from
+  this policy if they are set. Otherwise, use default ticket flags.
+* If no ticket policy is defined for the principal entry, but there is a
+  global one, use flags from the global ticket policy if they are set.
+  Otherwise, use default ticket flags.
+* If no policy (principal nor global) is defined, use default ticket
+  flags.
+
+However, this logic was broken by a1165ffb which introduced creation of
+a principal-level ticket policy in case the ticket flag set is modified.
+This was typically the case for the -allow_tix flag, which was set
+virtually by the KDB driver when a user was locked until they initialize
+their password on first kinit pre-authentication.
+
+This was causing multiple issues, which are mitigated by the new
+approach:
+
+Now flags from each level are combined together. There flags like
++requires_preauth which are set systematically by the KDB diver, as
+well as -allow_tix which is set based on the value of "nsAccountLock".
+This commit also adds the implicit -allow_svr ticket flag for user
+principals to protect users against Kerberoast-type attacks. None of
+these flags are stored in the LDAP database, they are hard-coded in the
+KDB driver.
+
+In addition to these "virtual" ticket flags, flags from both global and
+principal ticket policies are applied (if these policies exist).
+
+Principal ticket policies are not supported for hosts and services, but
+this is only an HTTP API limitation. The "krbTicketPolicyAux" object
+class is supported for all account types. This is required for ticket
+flags like +ok_to_auth_as_delegate. Such flags can be set using "ipa
+host-mod" and "ipa serivce-mod", or using kadmin's "modprinc".
+
+It is possible to ignore flags from the global ticket policy or default
+flags like -allow_svr for a user principal by setting the
+"final_user_tkt_flags" string attribute to "true" in kadmin. In this
+case, any ticket flag can be configured in the principal ticket policy,
+except requires_preauth and allow_tix.
+
+When in IPA setup mode (using the "ipa-setup-override-restrictions" KDB
+argument), all the system described above is disabled and ticket flags
+are written in the principal ticket policy as they are provided. This is
+required to initialize the Kerberos LDAP container during IPA server
+installation.
+
+This fixes CVE-2024-3183
+
+Signed-off-by: Julien Rische <jrische@redhat.com>
+---
+ daemons/ipa-kdb/ipa_kdb.h            |  43 ++++
+ daemons/ipa-kdb/ipa_kdb_principals.c | 352 +++++++++++++++++++++++----
+ util/ipa_krb5.c                      |  18 ++
+ util/ipa_krb5.h                      |   5 +
+ 4 files changed, 365 insertions(+), 53 deletions(-)
+
+diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
+index d187d969f..e7da25875 100644
+--- a/daemons/ipa-kdb/ipa_kdb.h
++++ b/daemons/ipa-kdb/ipa_kdb.h
+@@ -82,6 +82,34 @@
+ #define IPA_KRB_AUTHZ_DATA_ATTR "ipaKrbAuthzData"
+ #define IPA_USER_AUTH_TYPE "ipaUserAuthType"
+ 
++/* Virtual managed ticket flags like "-allow_tix", are always controlled by the
++ * "nsAccountLock" attribute, such flags should never be set in the database.
++ * The following expression combine all of them, and is used to filter them
++ * out. */
++#define IPA_KDB_TKTFLAGS_VIRTUAL_MANAGED_ALL          (KRB5_KDB_DISALLOW_ALL_TIX)
++
++/* Virtual static ticket flags are hard-coded in the KDB driver. */
++/*   Virtual static mandatory flags are set systematically and implicitly for all
++ *   principals. They are filtered out from database ticket flags updates.
++ *   (However, "KRB5_KDB_REQUIRES_PRE_AUTH" can still be unset by the
++ *   "KDC:Disable Default Preauth for SPNs" global setting) */
++#define IPA_KDB_TKTFLAGS_VIRTUAL_STATIC_MANDATORY     (KRB5_KDB_REQUIRES_PRE_AUTH)
++/*   Virtual static default ticket flags are implicitly set for user and non-user
++ *   (SPN) principals, and not stored in the database.
++ *   (Except if the "IPA_KDB_STRATTR_FINAL_TKTFLAGS" string attribute is "true"
++ *   the principal) */
++/*     Virtual static default user ticket flags are set for users only. The
++ *     "-allow_svr" flag is set to protect them from CVE-2024-3183. */
++#define IPA_KDB_TKTFLAGS_VIRTUAL_STATIC_DEFAULTS_USER (KRB5_KDB_DISALLOW_SVR)
++#define IPA_KDB_TKTFLAGS_VIRTUAL_STATIC_DEFAULTS_SPN  (0)
++
++/* If this string attribute is set to "true", then only the virtual managed and
++ * virtual static mandatory ticket flags are applied and filtered out from
++ * database read and write operations for the concerned user principal.
++ * Configurable principal ticket flags are applied, but not the configurable
++ * global ticket policy flags. */
++#define IPA_KDB_STRATTR_FINAL_USER_TKTFLAGS "final_user_tkt_flags"
++
+ struct ipadb_mspac;
+ 
+ enum ipadb_user_auth {
+@@ -141,6 +169,21 @@ struct ipadb_e_data {
+     bool has_tktpolaux;
+ };
+ 
++inline static krb5_error_code
++ipadb_get_edata(krb5_db_entry *entry, struct ipadb_e_data **ied)
++{
++    struct ipadb_e_data *in_ied;
++
++    in_ied = (struct ipadb_e_data *)entry->e_data;
++    if (!in_ied || in_ied->magic != IPA_E_DATA_MAGIC)
++        return EINVAL;
++
++    if (ied)
++        *ied = in_ied;
++
++    return 0;
++}
++
+ struct ipadb_context *ipadb_get_context(krb5_context kcontext);
+ int ipadb_get_connection(struct ipadb_context *ipactx);
+ 
+diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
+index e1e86a610..2e522aa39 100644
+--- a/daemons/ipa-kdb/ipa_kdb_principals.c
++++ b/daemons/ipa-kdb/ipa_kdb_principals.c
+@@ -592,9 +592,12 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
+                                  "krbTicketFlags", &result);
+     if (ret == 0) {
+         entry->attributes = result;
+-    } else {
+-        *polmask |= TKTFLAGS_BIT;
+     }
++    /* Since principal, global policy, and virtual ticket flags are combined,
++     * they must always be resolved, except if we are in IPA setup mode (because
++     * ticket policies and virtual ticket flags are irrelevant in this case). */
++    if (!ipactx->override_restrictions)
++        *polmask |= TKTFLAGS_BIT;
+ 
+     ret = ipadb_ldap_attr_to_int(lcontext, lentry,
+                                  "krbMaxTicketLife", &result);
+@@ -788,7 +791,11 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
+         goto done;
+     }
+     if (ret == 0) {
+-        ied->ipa_user = true;
++        if (1 == krb5_princ_size(kcontext, entry->princ)) {
++            /* A principal must be a POSIX account AND have only one element to
++             * be considered a user (this is to filter out CIFS principals). */
++            ied->ipa_user = true;
++        }
+     }
+ 
+     /* check if it has the krbTicketPolicyAux objectclass */
+@@ -1075,23 +1082,150 @@ krb5_error_code ipadb_find_principal(krb5_context kcontext,
+     return 0;
+ }
+ 
+-static krb5_flags maybe_require_preauth(struct ipadb_context *ipactx,
+-                                        krb5_db_entry *entry)
++static krb5_error_code
++are_final_tktflags(struct ipadb_context *ipactx, krb5_db_entry *entry,
++                   bool *final_tktflags)
+ {
+-    const struct ipadb_global_config *config;
++    krb5_error_code kerr;
+     struct ipadb_e_data *ied;
++    char *str = NULL;
++    bool in_final_tktflags = false;
+ 
+-    config = ipadb_get_global_config(ipactx);
+-    if (config && config->disable_preauth_for_spns) {
+-        ied = (struct ipadb_e_data *)entry->e_data;
+-        if (ied && ied->ipa_user != true) {
+-            /* not a user, assume SPN */
+-            return 0;
+-        }
++    kerr = ipadb_get_edata(entry, &ied);
++    if (kerr)
++        goto end;
++
++    if (!ied->ipa_user) {
++        kerr = 0;
++        goto end;
++    }
++
++    kerr = krb5_dbe_get_string(ipactx->kcontext, entry,
++                               IPA_KDB_STRATTR_FINAL_USER_TKTFLAGS, &str);
++    if (kerr)
++        goto end;
++
++    in_final_tktflags = str && ipa_krb5_parse_bool(str);
++
++end:
++    if (final_tktflags)
++        *final_tktflags = in_final_tktflags;
++
++    krb5_dbe_free_string(ipactx->kcontext, str);
++    return kerr;
++}
++
++static krb5_error_code
++add_virtual_static_tktflags(struct ipadb_context *ipactx, krb5_db_entry *entry,
++                            krb5_flags *tktflags)
++{
++    krb5_error_code kerr;
++    krb5_flags vsflg;
++    bool final_tktflags;
++    const struct ipadb_global_config *gcfg;
++    struct ipadb_e_data *ied;
++
++    vsflg = IPA_KDB_TKTFLAGS_VIRTUAL_STATIC_MANDATORY;
++
++    kerr = ipadb_get_edata(entry, &ied);
++    if (kerr)
++        goto end;
++
++    kerr = are_final_tktflags(ipactx, entry, &final_tktflags);
++    if (kerr)
++        goto end;
++
++    /* In practice, principal ticket flags cannot be final for SPNs. */
++    if (!final_tktflags)
++        vsflg |= ied->ipa_user ? IPA_KDB_TKTFLAGS_VIRTUAL_STATIC_DEFAULTS_USER
++                               : IPA_KDB_TKTFLAGS_VIRTUAL_STATIC_DEFAULTS_SPN;
++
++    if (!ied->ipa_user) {
++        gcfg = ipadb_get_global_config(ipactx);
++        if (gcfg && gcfg->disable_preauth_for_spns)
++            vsflg &= ~KRB5_KDB_REQUIRES_PRE_AUTH;
+     }
+ 
+-    /* By default require preauth for all principals */
+-    return KRB5_KDB_REQUIRES_PRE_AUTH;
++    if (tktflags)
++        *tktflags |= vsflg;
++
++end:
++    return kerr;
++}
++
++static krb5_error_code
++get_virtual_static_tktflags_mask(struct ipadb_context *ipactx,
++                                 krb5_db_entry *entry, krb5_flags *mask)
++{
++    krb5_error_code kerr;
++    krb5_flags flags = IPA_KDB_TKTFLAGS_VIRTUAL_MANAGED_ALL;
++
++    kerr = add_virtual_static_tktflags(ipactx, entry, &flags);
++    if (kerr)
++        goto end;
++
++    if (mask)
++        *mask = ~flags;
++
++    kerr = 0;
++
++end:
++    return kerr;
++}
++
++/* Add ticket flags from the global ticket policy if it exists, otherwise
++ * succeed. If the global ticket policy is set, the "exists" parameter is set to
++ * true. */
++static krb5_error_code
++add_global_ticket_policy_flags(struct ipadb_context *ipactx,
++                               bool *gtpol_exists, krb5_flags *tktflags)
++{
++    krb5_error_code kerr;
++    char *policy_dn;
++    char *tktflags_attr[] = { "krbticketflags", NULL };
++    LDAPMessage *res = NULL, *first;
++    int ec, ldap_tktflags;
++    bool in_gtpol_exists = false;
++
++    ec = asprintf(&policy_dn, "cn=%s,cn=kerberos,%s", ipactx->realm,
++                  ipactx->base);
++    if (-1 == ec) {
++        kerr = ENOMEM;
++        goto end;
++    }
++
++    kerr = ipadb_simple_search(ipactx, policy_dn, LDAP_SCOPE_BASE,
++                               "(objectclass=krbticketpolicyaux)",
++                               tktflags_attr, &res);
++    if (kerr) {
++        if (KRB5_KDB_NOENTRY == kerr)
++            kerr = 0;
++        goto end;
++    }
++
++    first = ldap_first_entry(ipactx->lcontext, res);
++    if (!first) {
++        kerr = 0;
++        goto end;
++    }
++
++    in_gtpol_exists = true;
++
++    ec = ipadb_ldap_attr_to_int(ipactx->lcontext, first, "krbticketflags",
++                                &ldap_tktflags);
++    if (0 == ec && tktflags) {
++        *tktflags |= (krb5_flags)ldap_tktflags;
++    }
++
++    kerr = 0;
++
++end:
++    if (gtpol_exists)
++        *gtpol_exists = in_gtpol_exists;
++
++    ldap_msgfree(res);
++    free(policy_dn);
++    return kerr;
+ }
+ 
+ static krb5_error_code ipadb_fetch_tktpolicy(krb5_context kcontext,
+@@ -1104,6 +1238,7 @@ static krb5_error_code ipadb_fetch_tktpolicy(krb5_context kcontext,
+     char *policy_dn = NULL;
+     LDAPMessage *res = NULL;
+     LDAPMessage *first;
++    bool final_tktflags, has_local_tktpolicy = true;
+     int result;
+     int ret;
+ 
+@@ -1112,12 +1247,18 @@ static krb5_error_code ipadb_fetch_tktpolicy(krb5_context kcontext,
+         return KRB5_KDB_DBNOTINITED;
+     }
+ 
++    kerr = are_final_tktflags(ipactx, entry, &final_tktflags);
++    if (kerr)
++        goto done;
++
+     ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
+                                  "krbticketpolicyreference", &policy_dn);
+     switch (ret) {
+     case 0:
+         break;
+     case ENOENT:
++        /* If no principal ticket policy, fallback to the global one. */
++        has_local_tktpolicy = false;
+         ret = asprintf(&policy_dn, "cn=%s,cn=kerberos,%s",
+                                    ipactx->realm, ipactx->base);
+         if (ret == -1) {
+@@ -1159,12 +1300,13 @@ static krb5_error_code ipadb_fetch_tktpolicy(krb5_context kcontext,
+                 }
+             }
+             if (polmask & TKTFLAGS_BIT) {
+-                ret = ipadb_ldap_attr_to_int(ipactx->lcontext, first,
+-                                             "krbticketflags", &result);
+-                if (ret == 0) {
+-                    entry->attributes |= result;
+-                } else {
+-                    entry->attributes |= maybe_require_preauth(ipactx, entry);
++                /* If global ticket policy is being applied, set flags only if
++                 * user principal ticket flags are not final. */
++                if (has_local_tktpolicy || !final_tktflags) {
++                    ret = ipadb_ldap_attr_to_int(ipactx->lcontext, first,
++                                                 "krbticketflags", &result);
++                    if (ret == 0)
++                        entry->attributes |= result;
+                 }
+             }
+         }
+@@ -1179,13 +1321,27 @@ static krb5_error_code ipadb_fetch_tktpolicy(krb5_context kcontext,
+         if (polmask & MAXRENEWABLEAGE_BIT) {
+             entry->max_renewable_life = 604800;
+         }
+-        if (polmask & TKTFLAGS_BIT) {
+-            entry->attributes |= maybe_require_preauth(ipactx, entry);
+-        }
+ 
+         kerr = 0;
+     }
+ 
++    if (polmask & TKTFLAGS_BIT) {
++        /* If the principal ticket flags were applied, then flags from the
++         * global ticket policy has to be applied atop of them if user principal
++         * ticket flags are not final. */
++        if (has_local_tktpolicy && !final_tktflags) {
++            kerr = add_global_ticket_policy_flags(ipactx, NULL,
++                                                  &entry->attributes);
++            if (kerr)
++            goto done;
++        }
++
++        /* Virtual static ticket flags are set regardless of database content */
++        kerr = add_virtual_static_tktflags(ipactx, entry, &entry->attributes);
++        if (kerr)
++            goto done;
++    }
++
+ done:
+     ldap_msgfree(res);
+     free(policy_dn);
+@@ -1512,6 +1668,36 @@ static void ipadb_mods_free_tip(struct ipadb_mods *imods)
+     imods->tip--;
+ }
+ 
++/* Use LDAP REPLACE operation to remove an attribute.
++ * Contrary to the DELETE operation, it will not fail if the attribute does not
++ * exist. */
++static krb5_error_code
++ipadb_ldap_replace_remove(struct ipadb_mods *imods, char *attribute)
++{
++    krb5_error_code kerr;
++    LDAPMod *m = NULL;
++
++    kerr = ipadb_mods_new(imods, &m);
++    if (kerr)
++        return kerr;
++
++    m->mod_op = LDAP_MOD_REPLACE;
++    m->mod_type = strdup(attribute);
++    if (!m->mod_type) {
++        kerr = ENOMEM;
++        goto end;
++    }
++
++    m->mod_values = NULL;
++
++    kerr = 0;
++
++end:
++    if (kerr)
++        ipadb_mods_free_tip(imods);
++    return kerr;
++}
++
+ static krb5_error_code ipadb_get_ldap_mod_str(struct ipadb_mods *imods,
+                                               char *attribute, char *value,
+                                               int mod_op)
+@@ -1923,6 +2109,93 @@ static krb5_error_code ipadb_get_ldap_mod_auth_ind(krb5_context kcontext,
+     return ret;
+ }
+ 
++static krb5_error_code
++update_tktflags(krb5_context kcontext, struct ipadb_mods *imods,
++                krb5_db_entry *entry, int mod_op)
++{
++    krb5_error_code kerr;
++    struct ipadb_context *ipactx;
++    struct ipadb_e_data *ied;
++    bool final_tktflags;
++    krb5_flags tktflags_mask;
++    int tktflags;
++
++    ipactx = ipadb_get_context(kcontext);
++    if (!ipactx) {
++        kerr = KRB5_KDB_DBNOTINITED;
++        goto end;
++    }
++
++    if (ipactx->override_restrictions) {
++        /* In IPA setup mode, IPA edata might not be available. In this mode,
++         * ticket flags are written as they are provided. */
++        tktflags = (int)entry->attributes;
++    } else {
++        kerr = ipadb_get_edata(entry, &ied);
++        if (kerr)
++            goto end;
++
++        kerr = get_virtual_static_tktflags_mask(ipactx, entry, &tktflags_mask);
++        if (kerr)
++            goto end;
++
++        kerr = are_final_tktflags(ipactx, entry, &final_tktflags);
++        if (kerr)
++            goto end;
++
++        /* Flags from the global ticket policy are filtered out only if the user
++         * principal flags are not final. */
++        if (!final_tktflags) {
++            krb5_flags gbl_tktflags = 0;
++
++            kerr = add_global_ticket_policy_flags(ipactx, NULL, &gbl_tktflags);
++            if (kerr)
++                goto end;
++
++            tktflags_mask &= ~gbl_tktflags;
++        }
++
++        tktflags = (int)(entry->attributes & tktflags_mask);
++
++        if (LDAP_MOD_REPLACE == mod_op && ied && !ied->has_tktpolaux) {
++            if (0 == tktflags) {
++                /* No point initializing principal ticket policy if there are no
++                 * flags left after filtering out virtual and global ticket
++                 * policy ones. */
++                kerr = 0;
++                goto end;
++            }
++
++            /* if the object does not have the krbTicketPolicyAux class
++             * we need to add it or this will fail, only for modifications.
++             * We always add this objectclass by default when doing an add
++             * from scratch. */
++            kerr = ipadb_get_ldap_mod_str(imods, "objectclass",
++                                          "krbTicketPolicyAux", LDAP_MOD_ADD);
++            if (kerr)
++                goto end;
++        }
++    }
++
++    if (tktflags != 0) {
++        kerr = ipadb_get_ldap_mod_int(imods, "krbTicketFlags", tktflags,
++                                      mod_op);
++        if (kerr)
++            goto end;
++    } else if (LDAP_MOD_REPLACE == mod_op) {
++        /* If the principal is not being created, and there are no custom ticket
++         * flags to be set, remove the "krbTicketFlags" attribute. */
++        kerr = ipadb_ldap_replace_remove(imods, "krbTicketFlags");
++        if (kerr)
++            goto end;
++    }
++
++    kerr = 0;
++
++end:
++    return kerr;
++}
++
+ static krb5_error_code ipadb_entry_to_mods(krb5_context kcontext,
+                                            struct ipadb_mods *imods,
+                                            krb5_db_entry *entry,
+@@ -1998,36 +2271,9 @@ static krb5_error_code ipadb_entry_to_mods(krb5_context kcontext,
+ 
+     /* KADM5_ATTRIBUTES */
+     if (entry->mask & KMASK_ATTRIBUTES) {
+-        /* if the object does not have the krbTicketPolicyAux class
+-         * we need to add it or this will fail, only for modifications.
+-         * We always add this objectclass by default when doing an add
+-         * from scratch. */
+-        if ((mod_op == LDAP_MOD_REPLACE) && entry->e_data) {
+-            struct ipadb_e_data *ied;
+-
+-            ied = (struct ipadb_e_data *)entry->e_data;
+-            if (ied->magic != IPA_E_DATA_MAGIC) {
+-                kerr = EINVAL;
+-                goto done;
+-            }
+-
+-            if (!ied->has_tktpolaux) {
+-                kerr = ipadb_get_ldap_mod_str(imods, "objectclass",
+-                                              "krbTicketPolicyAux",
+-                                              LDAP_MOD_ADD);
+-                if (kerr) {
+-                    goto done;
+-                }
+-            }
+-        }
+-
+-        kerr = ipadb_get_ldap_mod_int(imods,
+-                                      "krbTicketFlags",
+-                                      (int)entry->attributes,
+-                                      mod_op);
+-        if (kerr) {
++        kerr = update_tktflags(kcontext, imods, entry, mod_op);
++        if (kerr)
+             goto done;
+-        }
+     }
+ 
+     /* KADM5_MAX_LIFE */
+diff --git a/util/ipa_krb5.c b/util/ipa_krb5.c
+index 1ba6d25ee..2e663c506 100644
+--- a/util/ipa_krb5.c
++++ b/util/ipa_krb5.c
+@@ -38,6 +38,12 @@ const char *ipapwd_password_max_len_errmsg = \
+     TOSTR(IPAPWD_PASSWORD_MAX_LEN) \
+     " chars)!";
+ 
++/* Case-insensitive string values to by parsed as boolean true */
++static const char *const conf_yes[] = {
++    "y", "yes", "true", "t", "1", "on",
++    NULL,
++};
++
+ /* Salt types */
+ #define KRB5P_SALT_SIZE 16
+ 
+@@ -1237,3 +1243,15 @@ done:
+     }
+     return ret;
+ }
++
++bool ipa_krb5_parse_bool(const char *str)
++{
++    const char *const *p;
++
++    for (p = conf_yes; *p; p++) {
++        if (!strcasecmp(*p, str))
++            return true;
++    }
++
++    return false;
++}
+diff --git a/util/ipa_krb5.h b/util/ipa_krb5.h
+index 8392a85b6..ba371449e 100644
+--- a/util/ipa_krb5.h
++++ b/util/ipa_krb5.h
+@@ -4,6 +4,7 @@
+ #include <krb5/krb5.h>
+ #include <kdb.h>
+ #include <syslog.h>
++#include <stdbool.h>
+ 
+ struct krb_key_salt {
+     krb5_enctype enctype;
+@@ -86,3 +87,7 @@ int create_keys(krb5_context krbctx,
+                 char **err_msg);
+ 
+ int ipa_kstuples_to_string(krb5_key_salt_tuple *kst, int n_kst, char **str);
++
++/* Implement boolean string parsing function from MIT krb5:
++ * src/lib/krb5/krb/libdef_parse.c:_krb5_conf_boolean() */
++bool ipa_krb5_parse_bool(const char *str);
+-- 
+2.44.0
+
diff --git a/SOURCES/ipa-centos-branding.patch b/SOURCES/ipa-centos-branding.patch
deleted file mode 100644
index 673cd2f..0000000
--- a/SOURCES/ipa-centos-branding.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 99efecaf87dc1fc9517efaff441a6a7ce46444eb Mon Sep 17 00:00:00 2001
-From: Jim Perrin <jperrin@centos.org>
-Date: Wed, 11 Mar 2015 10:37:03 -0500
-Subject: [PATCH] update for new ntp server method
-
----
- ipaplatform/base/paths.py        | 1 +
- ipaserver/install/ntpinstance.py | 2 ++
- 2 files changed, 3 insertions(+)
-
-diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
-index af50262..5090062 100644
---- a/ipaplatform/base/paths.py
-+++ b/ipaplatform/base/paths.py
-@@ -99,6 +99,7 @@ class BasePathNamespace(object):
-     PKI_TOMCAT_ALIAS_DIR = "/etc/pki/pki-tomcat/alias/"
-     PKI_TOMCAT_PASSWORD_CONF = "/etc/pki/pki-tomcat/password.conf"
-     ETC_REDHAT_RELEASE = "/etc/redhat-release"
-+    ETC_CENTOS_RELEASE = "/etc/centos-release"
-     RESOLV_CONF = "/etc/resolv.conf"
-     SAMBA_KEYTAB = "/etc/samba/samba.keytab"
-     SMB_CONF = "/etc/samba/smb.conf"
-diff --git a/ipaserver/install/ntpinstance.py b/ipaserver/install/ntpinstance.py
-index c653525..4b0578b 100644
---- a/ipaserver/install/ntpinstance.py
-+++ b/ipaserver/install/ntpinstance.py
-@@ -44,6 +44,8 @@ class NTPInstance(service.Service):
-         os = ""
-         if ipautil.file_exists(paths.ETC_FEDORA_RELEASE):
-             os = "fedora"
-+        elif ipautil.file_exists(paths.ETC_CENTOS_RELEASE):
-+            os = "centos"
-         elif ipautil.file_exists(paths.ETC_REDHAT_RELEASE):
-             os = "rhel"
- 
--- 
-1.8.3.1
-
diff --git a/SPECS/ipa.spec b/SPECS/ipa.spec
index 937c6e3..325059e 100644
--- a/SPECS/ipa.spec
+++ b/SPECS/ipa.spec
@@ -104,7 +104,7 @@
 
 Name:           ipa
 Version:        %{IPA_VERSION}
-Release:        5%{?dist}.16
+Release:        5%{?dist}.17
 Summary:        The Identity, Policy and Audit system
 
 Group:          System Environment/Base
@@ -112,9 +112,9 @@ License:        GPLv3+
 URL:            http://www.freeipa.org/
 Source0:        https://releases.pagure.org/freeipa/freeipa-%{version}.tar.gz
 # RHEL spec file only: START: Change branding to IPA and Identity Management
-#Source1:        header-logo.png
-#Source2:        login-screen-background.jpg
-#Source4:        product-name.png
+Source1:        header-logo.png
+Source2:        login-screen-background.jpg
+Source4:        product-name.png
 # RHEL spec file only: END: Change branding to IPA and Identity Management
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
@@ -162,6 +162,7 @@ Patch0040:      0040-ipaserver-deepcopy-objectclasses-list-from-IPA-confi.patch
 Patch0041:      0041-Fix-memory-leak-in-the-OTP-last-token-plugin.patch
 Patch0042:      0042-Check-the-HTTP-Referer-header-on-all-requests.patch
 Patch0043:      0043-Integration-tests-for-verifying-Referer-header-in-th.patch
+Patch0044:      0044-kdb-apply-combinatorial-logic-for-ticket-flags.patch
 Patch1001:      1001-Change-branding-to-IPA-and-Identity-Management.patch
 Patch1002:      1002-Package-copy-schema-to-ca.py.patch
 Patch1003:      1003-Revert-Increased-mod_wsgi-socket-timeout.patch
@@ -418,10 +419,7 @@ Requires: oddjob
 Requires: gssproxy >= 0.7.0-2
 # 1.15.2: FindByNameAndCertificate (https://pagure.io/SSSD/sssd/issue/3050)
 Requires: sssd-dbus >= 1.15.2
-
-%if 0%{?centos} == 0
 Requires: system-logos >= 70.7.0
-%endif
 
 Provides: %{alt_name}-server = %{version}
 Conflicts: %{alt_name}-server
@@ -978,9 +976,9 @@ cp -r %{_builddir}/freeipa-%{version} %{_builddir}/freeipa-%{version}-python3
 # with_python3
 
 # RHEL spec file only: START: Change branding to IPA and Identity Management
-#cp %SOURCE1 install/ui/images/header-logo.png
-#cp %SOURCE2 install/ui/images/login-screen-background.jpg
-#cp %SOURCE4 install/ui/images/product-name.png
+cp %SOURCE1 install/ui/images/header-logo.png
+cp %SOURCE2 install/ui/images/login-screen-background.jpg
+cp %SOURCE4 install/ui/images/product-name.png
 # RHEL spec file only: END: Change branding to IPA and Identity Management
 
 
@@ -1004,8 +1002,7 @@ find \
 %configure --with-vendor-suffix=-%{release} \
            %{enable_server_option} \
            %{with_ipatests_option} \
-           %{linter_options} \
-           --with-ipaplatform=rhel
+           %{linter_options}
 
 %make_build
 
@@ -1026,8 +1023,7 @@ find \
 %configure --with-vendor-suffix=-%{release} \
            %{enable_server_option} \
            %{with_ipatests_option} \
-           %{linter_options} \
-          --with-ipaplatform=rhel
+           %{linter_options}
 popd
 %endif
 # with_python3
@@ -1114,11 +1110,9 @@ ln -s %{_bindir}/ipa-test-task-%{python2_version} %{buildroot}%{_bindir}/ipa-tes
 # remove files which are useful only for make uninstall
 find %{buildroot} -wholename '*/site-packages/*/install_files.txt' -exec rm {} \;
 
-%if 0%{?centos} == 0
 # RHEL spec file only: START: Replace login-screen-logo.png with a symlink
 ln -sf %{_datadir}/pixmaps/fedora-gdm-logo.png %{buildroot}%{_usr}/share/ipa/ui/images/login-screen-logo.png
 # RHEL spec file only: END: Replace login-screen-logo.png with a symlink
-%endif
 
 %find_lang %{gettext_domain}
 
@@ -1775,8 +1769,8 @@ fi
 
 
 %changelog
-* Wed Jan 10 2024 CentOS Sources <bugs@centos.org> - 4.6.8-5.el7.centos.16
-- Roll in CentOS Branding
+* Tue Jun 04 2024 Julien Rische <jrische@redhat.com> - 4.6.8-5.el7_9.17
+- Resolves: RHEL-29926 ipa: user can obtain a hash of the passwords of all domain users and perform offline brute force
 
 * Tue Nov 21 2023 Florence Blanc-Renaud <frenaud@redhat.com> - 4.6.8-5.el7_9.16
 - Resolves: RHEL-12570 ipa: Invalid CSRF protection