ipa-4.12.2-1

- Resolves: RHEL-54546 Covscan issues: Resource Leak
- Resolves: RHEL-49602 misleading warning for missing ipa-selinux-nfast package on luna hsm h/w
- Resolves: RHEL-40359 With unreachable AD, ipa trust returns an internal error

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
This commit is contained in:
Florence Blanc-Renaud 2024-08-22 07:53:57 +02:00
parent 3979c73861
commit 9b3c30c71b
35 changed files with 11 additions and 4250 deletions

2
.gitignore vendored
View File

@ -124,3 +124,5 @@
/freeipa-4.11.0.tar.gz.asc
/freeipa-4.12.0.tar.gz
/freeipa-4.12.0.tar.gz.asc
/freeipa-4.12.2.tar.gz
/freeipa-4.12.2.tar.gz.asc

View File

@ -1,379 +0,0 @@
From 811694c2a5fd0da37c6454a23bc101488ee6fb88 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Tue, 19 Mar 2024 12:24:40 +0100
Subject: [PATCH] kdb: fix vulnerability in GCD rules handling
The initial implementation of MS-SFU by MIT Kerberos was missing a
condition for granting the "forwardable" flag on S4U2Self tickets.
Fixing this mistake required adding special case for the
check_allowed_to_delegate() function: if the target service argument is
NULL, then it means the KDC is probing for general constrained
delegation rules, not actually checking a specific S4U2Proxy request.
In commit e86807b5, the behavior of ipadb_match_acl() was modified to
match the changes from upstream MIT Kerberos a441fbe3. However, a
mistake resulted in this mechanism to apply in cases where target
service argument is set AND unset. This results in S4U2Proxy requests to
be accepted regardless of the fact there is a matching service
delegation rule or not.
This vulnerability does not affect services having RBCD (resource-based
constrained delegation) rules.
This fixes CVE-2024-2698
Signed-off-by: Julien Rische <jrische@redhat.com>
---
daemons/ipa-kdb/README.s4u2proxy.txt | 19 ++-
daemons/ipa-kdb/ipa_kdb_delegation.c | 191 +++++++++++++++------------
doc/designs/rbcd.md | 18 +++
3 files changed, 136 insertions(+), 92 deletions(-)
diff --git a/daemons/ipa-kdb/README.s4u2proxy.txt b/daemons/ipa-kdb/README.s4u2proxy.txt
index 254fcc4d1..ab34aff36 100644
--- a/daemons/ipa-kdb/README.s4u2proxy.txt
+++ b/daemons/ipa-kdb/README.s4u2proxy.txt
@@ -12,9 +12,7 @@ much more easily managed.
The grouping mechanism has been built so that lookup is highly optimized
and is basically reduced to a single search that uses the derefernce
-control. Speed is very important in this case because KDC operations
-time out very quickly and unless we add a caching layer in ipa-kdb we
-must keep the number of searches down to avoid client timeouts.
+control.
The grouping mechanism is very simple a groupOfPrincipals object is
introduced, this Auxiliary class have a single optional attribute called
@@ -112,8 +110,7 @@ kinit -kt /etc/httpd/conf/ipa.keytab HTTP/ipaserver.example.com
kvno -U admin HTTP/ipaserver.example.com
# Perform S4U2Proxy
-kvno -k /etc/httpd/conf/ipa.keytab -U admin -P HTTP/ipaserver.example.com
-ldap/ipaserver.example.com
+kvno -U admin -P ldap/ipaserver.example.com
If this works it means you successfully impersonated the admin user with
@@ -125,6 +122,18 @@ modprinc -ok_to_auth_as_delegate HTTP/ipaserver.example.com
Simo.
+If IPA is compiled with krb5 1.20 and newer (KDB DAL >= 9), then the
+behavior of S4U2Self changes: S4U2Self TGS-REQs produce forwardable
+tickets for all requesters, except if the requester principal is set as
+the proxy (impersonating service) in at least one `servicedelegation`
+rule. In this case, even if the rule has no target, the KDC will
+response to S4U2Self requests with a non-forwardable ticket. Hence,
+granting the `ok_to_auth_as_delegate` permission to the proxy service
+remains the only way for this service to obtain the evidence ticket
+required for general constrained delegation requests if this ticket is
+not provided by the client.
+
+
[1]
Note that here I use the term proxy in a different way than it is used in
the krb interfaces. It may seem a bit confusing but I think people will
diff --git a/daemons/ipa-kdb/ipa_kdb_delegation.c b/daemons/ipa-kdb/ipa_kdb_delegation.c
index ce5409d2b..fbeeaaa84 100644
--- a/daemons/ipa-kdb/ipa_kdb_delegation.c
+++ b/daemons/ipa-kdb/ipa_kdb_delegation.c
@@ -99,120 +99,110 @@ static bool ipadb_match_member(char *princ, LDAPDerefRes *dres)
return false;
}
-static krb5_error_code ipadb_match_acl(krb5_context kcontext,
- LDAPMessage *results,
- krb5_const_principal client,
- krb5_const_principal target)
+#if KRB5_KDB_DAL_MAJOR_VERSION >= 9
+static krb5_error_code
+ipadb_has_acl(krb5_context kcontext, LDAPMessage *ldap_acl, bool *res)
{
struct ipadb_context *ipactx;
- krb5_error_code kerr;
- LDAPMessage *lentry;
- LDAPDerefRes *deref_results;
- LDAPDerefRes *dres;
- char *client_princ = NULL;
- char *target_princ = NULL;
- bool client_missing;
- bool client_found;
- bool target_found;
- bool is_constraint_delegation = false;
- size_t nrules = 0;
- int ret;
+ bool in_res = false;
+ krb5_error_code kerr = 0;
ipactx = ipadb_get_context(kcontext);
- if (!ipactx) {
+ if (!ipactx)
return KRB5_KDB_DBNOTINITED;
- }
- if ((client != NULL) && (target != NULL)) {
- kerr = krb5_unparse_name(kcontext, client, &client_princ);
- if (kerr != 0) {
- goto done;
- }
- kerr = krb5_unparse_name(kcontext, target, &target_princ);
- if (kerr != 0) {
- goto done;
- }
- } else {
- is_constraint_delegation = true;
+ switch (ldap_count_entries(ipactx->lcontext, ldap_acl)) {
+ case 0:
+ break;
+ case -1:
+ kerr = EINVAL;
+ goto end;
+ default:
+ in_res = true;
+ goto end;
}
- lentry = ldap_first_entry(ipactx->lcontext, results);
- if (!lentry) {
- kerr = ENOENT;
- goto done;
- }
+end:
+ if (res)
+ *res = in_res;
+
+ return kerr;
+}
+#endif
+
+static krb5_error_code
+ipadb_match_acl(krb5_context kcontext, LDAPMessage *ldap_acl,
+ krb5_const_principal client, krb5_const_principal target)
+{
+ struct ipadb_context *ipactx;
+ LDAPMessage *rule;
+ LDAPDerefRes *acis, *aci;
+ char *client_princ = NULL, *target_princ= NULL;
+ bool client_missing, client_found, target_found;
+ int lerr;
+ krb5_error_code kerr;
+
+ ipactx = ipadb_get_context(kcontext);
+ if (!ipactx)
+ return KRB5_KDB_DBNOTINITED;
+
+ kerr = krb5_unparse_name(kcontext, client, &client_princ);
+ if (kerr)
+ goto end;
+
+ kerr = krb5_unparse_name(kcontext, target, &target_princ);
+ if (kerr)
+ goto end;
/* the default is that we fail */
- kerr = ENOENT;
+ kerr = KRB5KDC_ERR_BADOPTION;
- while (lentry) {
+ for (rule = ldap_first_entry(ipactx->lcontext, ldap_acl);
+ rule;
+ rule = ldap_next_entry(ipactx->lcontext, rule))
+ {
/* both client and target must be found in the same ACI */
client_missing = true;
client_found = false;
target_found = false;
- ret = ipadb_ldap_deref_results(ipactx->lcontext, lentry,
- &deref_results);
- switch (ret) {
+ lerr = ipadb_ldap_deref_results(ipactx->lcontext, rule, &acis);
+ switch (lerr) {
case 0:
- for (dres = deref_results; dres; dres = dres->next) {
- nrules++;
- if (is_constraint_delegation) {
- /*
- Microsoft revised the S4U2Proxy rules for forwardable
- tickets. All S4U2Proxy operations require forwardable
- evidence tickets, but S4U2Self should issue a
- forwardable ticket if the requesting service has no
- ok-to-auth-as-delegate bit but also no constrained
- delegation privileges for traditional S4U2Proxy.
- Implement these rules, extending the
- check_allowed_to_delegate() DAL method so that the KDC
- can ask if a principal has any delegation privileges.
-
- Since target principal is NULL and client principal is
- NULL in this case, we simply calculate number of rules associated
- with the server principal to decide whether to deny forwardable bit
- */
- continue;
- }
- if (client_found == false &&
- strcasecmp(dres->derefAttr, "ipaAllowToImpersonate") == 0) {
+ for (aci = acis; aci; aci = aci->next) {
+ if (!client_found &&
+ 0 == strcasecmp(aci->derefAttr, "ipaAllowToImpersonate"))
+ {
/* NOTE: client_missing is used to signal that the
* attribute was completely missing. This signals that
* ANY client is allowed to be impersonated.
* This logic is valid only for clients, not for targets */
client_missing = false;
- client_found = ipadb_match_member(client_princ, dres);
+ client_found = ipadb_match_member(client_princ, aci);
}
- if (target_found == false &&
- strcasecmp(dres->derefAttr, "ipaAllowedTarget") == 0) {
- target_found = ipadb_match_member(target_princ, dres);
+ if (!target_found &&
+ 0 == strcasecmp(aci->derefAttr, "ipaAllowedTarget"))
+ {
+ target_found = ipadb_match_member(target_princ, aci);
}
}
- ldap_derefresponse_free(deref_results);
+ ldap_derefresponse_free(acis);
break;
case ENOENT:
break;
default:
- kerr = ret;
- goto done;
+ kerr = lerr;
+ goto end;
}
- if ((client_found == true || client_missing == true) &&
- target_found == true) {
+ if ((client_found || client_missing) && target_found) {
kerr = 0;
- goto done;
+ goto end;
}
-
- lentry = ldap_next_entry(ipactx->lcontext, lentry);
- }
-
- if (nrules > 0) {
- kerr = 0;
}
-done:
+end:
krb5_free_unparsed_name(kcontext, client_princ);
krb5_free_unparsed_name(kcontext, target_princ);
return kerr;
@@ -231,7 +221,7 @@ krb5_error_code ipadb_check_allowed_to_delegate(krb5_context kcontext,
char *srv_principal = NULL;
krb5_db_entry *proxy_entry = NULL;
struct ipadb_e_data *ied_server, *ied_proxy;
- LDAPMessage *res = NULL;
+ LDAPMessage *ldap_gcd_acl = NULL;
if (proxy != NULL) {
/* Handle the case where server == proxy, this is allowed in S4U */
@@ -269,27 +259,54 @@ krb5_error_code ipadb_check_allowed_to_delegate(krb5_context kcontext,
goto done;
}
- kerr = ipadb_get_delegation_acl(kcontext, srv_principal, &res);
+ /* Load general constrained delegation rules */
+ kerr = ipadb_get_delegation_acl(kcontext, srv_principal, &ldap_gcd_acl);
if (kerr) {
goto done;
}
- kerr = ipadb_match_acl(kcontext, res, client, proxy);
- if (kerr) {
- goto done;
+#if KRB5_KDB_DAL_MAJOR_VERSION >= 9
+ /*
+ * Microsoft revised the S4U2Proxy rules for forwardable tickets. All
+ * S4U2Proxy operations require forwardable evidence tickets, but
+ * S4U2Self should issue a forwardable ticket if the requesting service
+ * has no ok-to-auth-as-delegate bit but also no constrained delegation
+ * privileges for traditional S4U2Proxy. Implement these rules,
+ * extending the check_allowed_to_delegate() DAL method so that the KDC
+ * can ask if a principal has any delegation privileges.
+ *
+ * If target service principal is NULL, and the impersonating service has
+ * at least one GCD rule, then succeed.
+ */
+ if (!proxy) {
+ bool has_gcd_rules;
+
+ kerr = ipadb_has_acl(kcontext, ldap_gcd_acl, &has_gcd_rules);
+ if (!kerr)
+ kerr = has_gcd_rules ? 0 : KRB5KDC_ERR_BADOPTION;
+ } else if (client) {
+#else
+ if (client && proxy) {
+#endif
+ kerr = ipadb_match_acl(kcontext, ldap_gcd_acl, client, proxy);
+ } else {
+ /* client and/or proxy is missing */
+ kerr = KRB5KDC_ERR_BADOPTION;
}
+ if (kerr)
+ goto done;
done:
if (kerr) {
-#if KRB5_KDB_DAL_MAJOR_VERSION < 9
- kerr = KRB5KDC_ERR_POLICY;
-#else
+#if KRB5_KDB_DAL_MAJOR_VERSION >= 9
kerr = KRB5KDC_ERR_BADOPTION;
+#else
+ kerr = KRB5KDC_ERR_POLICY;
#endif
}
ipadb_free_principal(kcontext, proxy_entry);
krb5_free_unparsed_name(kcontext, srv_principal);
- ldap_msgfree(res);
+ ldap_msgfree(ldap_gcd_acl);
return kerr;
}
diff --git a/doc/designs/rbcd.md b/doc/designs/rbcd.md
index c3665ed8f..fa41c57ee 100644
--- a/doc/designs/rbcd.md
+++ b/doc/designs/rbcd.md
@@ -173,6 +173,7 @@ any user. However, to make it usable for S4U2Proxy (constrained delegation),
the service ticket must be forwardable. In such case the Kerberos service would
be able to impersonate user and requires an explicit administrative permission.
+
IPA API provides a way to record this permission in both host and service
command families. The following commands have option
`--ok-to-auth-as-delegate=BOOL`:
@@ -183,6 +184,23 @@ command families. The following commands have option
This flag is equivalent to MS-SFU's `TrustedToAuthenticationForDelegation`
boolean setting.
+The behavior of FreeIPA regarding S4U2Self-granted tickets differs depending of
+the krb5 version that was used to compile:
+
+* **krb5 1.20+**: KDC will always respond to S4U2Self TGS-REQ with forwardable
+ tickets, except if the requester principal is set as impersonator service in
+ at least one general constrained delegation rule (even if the rule has no
+ target set)
+* **krb5 1.19-**: KDC will respond to all S4U2Self TGS-REQs with non-forwardable
+ tickets
+
+In both cases, granting the `ok-to-auth-as-delegate` permission to a principal
+will override this default behavior and allow it to obtain forwardable tickets
+to itself. In practice, it means the `ok-to-auth-as-delegate` permission is
+required if you want to grant a service the special privilege to impersonate
+any user against services configured as targets in a general constrained
+delegation rule.
+
### General constrained delegation design
General constrained delegation uses two objects: a rule and a target.
--
2.45.1

View File

@ -1,615 +0,0 @@
From 3bc4cf5e2946a46f3040648bc2254112a6379bf7 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 | 353 +++++++++++++++++++++++----
util/ipa_krb5.c | 18 ++
util/ipa_krb5.h | 4 +
4 files changed, 365 insertions(+), 53 deletions(-)
diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
index 8459ab8e0..58a0339fc 100644
--- a/daemons/ipa-kdb/ipa_kdb.h
+++ b/daemons/ipa-kdb/ipa_kdb.h
@@ -94,6 +94,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;
struct dom_sid;
@@ -187,6 +215,21 @@ struct ipadb_e_data {
struct dom_sid *sid;
};
+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 16a15748f..6a2684986 100644
--- a/daemons/ipa-kdb/ipa_kdb_principals.c
+++ b/daemons/ipa-kdb/ipa_kdb_principals.c
@@ -765,9 +765,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);
@@ -971,7 +974,12 @@ 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;
+ }
+
ret = ipadb_ldap_attr_to_str(lcontext, lentry,
"uid", &uidstring);
if (ret != 0 && ret != ENOENT) {
@@ -1339,23 +1347,150 @@ done:
return ret;
}
-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;
+ }
+
+ 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;
}
- /* By default require preauth for all principals */
- return KRB5_KDB_REQUIRES_PRE_AUTH;
+ 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,
@@ -1368,6 +1503,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;
@@ -1376,12 +1512,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) {
@@ -1425,12 +1567,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;
}
}
@@ -1454,13 +1597,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);
@@ -2048,6 +2205,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)
@@ -2464,6 +2651,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,
@@ -2539,36 +2813,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 7d2ebae98..d0280940a 100644
--- a/util/ipa_krb5.h
+++ b/util/ipa_krb5.h
@@ -174,3 +174,7 @@ static inline bool
krb5_ts_after(krb5_timestamp a, krb5_timestamp b) {
return (uint32_t)a > (uint32_t)b;
}
+
+/* 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.45.1

View File

@ -1,79 +0,0 @@
From ebccaac3cf8a5688739d76426924469d5b4df6b1 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Mon, 10 Jun 2024 14:54:41 -0400
Subject: [PATCH] Add iparepltopoconf objectclass to topology permissions
The domain and ca objects were unreadable which caused
the conneciton lines between nodes in the UI to not be
visible.
Also add a manual ACI to allow reading the min/max
domain level.
Fixes: https://pagure.io/freeipa/issue/9594
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
---
ACI.txt | 8 ++++----
install/updates/40-replication.update | 11 +++++++++++
ipaserver/plugins/topology.py | 2 +-
3 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/ACI.txt b/ACI.txt
index 13b0a64bde6b29503b048630f1c718e5e30759b2..50c8824d43cd6d3ca9a381b5d34425cb0197508c 100644
--- a/ACI.txt
+++ b/ACI.txt
@@ -375,13 +375,13 @@ aci: (targetattr = "cmdcategory || cn || createtimestamp || description || entry
dn: dc=ipa,dc=example
aci: (targetattr = "cn || createtimestamp || description || entryusn || modifytimestamp || objectclass || ou || sudocommand || sudohost || sudonotafter || sudonotbefore || sudooption || sudoorder || sudorunas || sudorunasgroup || sudorunasuser || sudouser")(target = "ldap:///ou=sudoers,dc=ipa,dc=example")(version 3.0;acl "permission:System: Read Sudoers compat tree";allow (compare,read,search) userdn = "ldap:///anyone";)
dn: cn=topology,cn=ipa,cn=etc,dc=ipa,dc=example
-aci: (targetfilter = "(objectclass=iparepltoposegment)")(version 3.0;acl "permission:System: Add Topology Segments";allow (add) groupdn = "ldap:///cn=System: Add Topology Segments,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+aci: (targetfilter = "(|(objectclass=iparepltopoconf)(objectclass=iparepltoposegment))")(version 3.0;acl "permission:System: Add Topology Segments";allow (add) groupdn = "ldap:///cn=System: Add Topology Segments,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=topology,cn=ipa,cn=etc,dc=ipa,dc=example
-aci: (targetattr = "iparepltoposegmentdirection || iparepltoposegmentleftnode || iparepltoposegmentrightnode || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal")(targetfilter = "(objectclass=iparepltoposegment)")(version 3.0;acl "permission:System: Modify Topology Segments";allow (write) groupdn = "ldap:///cn=System: Modify Topology Segments,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+aci: (targetattr = "iparepltoposegmentdirection || iparepltoposegmentleftnode || iparepltoposegmentrightnode || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal")(targetfilter = "(|(objectclass=iparepltopoconf)(objectclass=iparepltoposegment))")(version 3.0;acl "permission:System: Modify Topology Segments";allow (write) groupdn = "ldap:///cn=System: Modify Topology Segments,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=topology,cn=ipa,cn=etc,dc=ipa,dc=example
-aci: (targetattr = "cn || createtimestamp || entryusn || iparepltopoconfroot || iparepltoposegmentdirection || iparepltoposegmentleftnode || iparepltoposegmentrightnode || iparepltoposegmentstatus || modifytimestamp || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal || objectclass")(targetfilter = "(objectclass=iparepltoposegment)")(version 3.0;acl "permission:System: Read Topology Segments";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Topology Segments,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+aci: (targetattr = "cn || createtimestamp || entryusn || iparepltopoconfroot || iparepltoposegmentdirection || iparepltoposegmentleftnode || iparepltoposegmentrightnode || iparepltoposegmentstatus || modifytimestamp || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal || objectclass")(targetfilter = "(|(objectclass=iparepltopoconf)(objectclass=iparepltoposegment))")(version 3.0;acl "permission:System: Read Topology Segments";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Topology Segments,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=topology,cn=ipa,cn=etc,dc=ipa,dc=example
-aci: (targetfilter = "(objectclass=iparepltoposegment)")(version 3.0;acl "permission:System: Remove Topology Segments";allow (delete) groupdn = "ldap:///cn=System: Remove Topology Segments,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+aci: (targetfilter = "(|(objectclass=iparepltopoconf)(objectclass=iparepltoposegment))")(version 3.0;acl "permission:System: Remove Topology Segments";allow (delete) groupdn = "ldap:///cn=System: Remove Topology Segments,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=trusts,dc=ipa,dc=example
aci: (targetattr = "cn || createtimestamp || entryusn || ipantadditionalsuffixes || ipantflatname || ipantsecurityidentifier || ipantsidblacklistincoming || ipantsidblacklistoutgoing || ipanttrustdirection || ipanttrusteddomainsid || ipanttrustpartner || modifytimestamp || objectclass")(version 3.0;acl "permission:System: Read Trust Information";allow (compare,read,search) userdn = "ldap:///all";)
dn: cn=trusts,dc=ipa,dc=example
diff --git a/install/updates/40-replication.update b/install/updates/40-replication.update
index 06b6613ed4c9ede935f879ee46ed5e7d5a0935ba..6dc38e36d96b4e019eb35f9d0367bfc7a202af98 100644
--- a/install/updates/40-replication.update
+++ b/install/updates/40-replication.update
@@ -28,3 +28,14 @@ default:member: cn=Replication Administrators,cn=privileges,cn=pbac,$SUFFIX
dn: cn=Posix IDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
remove:aci: (targetattr=cn || dnaMaxValue || dnaNextRange || dnaNextValue || dnaThreshold || dnaType || objectclass)(version 3.0;acl "permission:Read DNA Range";allow (read, search, compare) groupdn = "ldap:///cn=Read DNA Range,cn=permissions,cn=pbac,$SUFFIX";)
add:aci: (targetattr = "cn || dnaMaxValue || dnaNextRange || dnaNextValue || dnaThreshold || dnaType || objectclass")(version 3.0;acl "permission:Read DNA Range";allow (read, search, compare) groupdn = "ldap:///cn=Read DNA Range,cn=permissions,cn=pbac,$SUFFIX";)
+
+dn: cn=Read domain level,cn=permissions,cn=pbac,$SUFFIX
+default:objectClass: top
+default:objectClass: groupofnames
+default:objectClass: ipapermission
+default:cn: Read domain level
+default:ipapermissiontype: SYSTEM
+default:member: cn=Replication Administrators,cn=privileges,cn=pbac,$SUFFIX
+
+dn: cn=masters,cn=ipa,cn=etc,$SUFFIX
+add:aci: (targetattr = "ipamaxdomainlevel || ipamindomainlevel")(version 3.0;acl "permission:Read domain level";allow (read, search, compare) groupdn = "ldap:///cn=Read domain level,cn=permissions,cn=pbac,$SUFFIX";)
diff --git a/ipaserver/plugins/topology.py b/ipaserver/plugins/topology.py
index be0cf3d705267af66e20fb990b2fed72b61d2c49..1401fe259226c12abe42a5670d3ce1812c27cc05 100644
--- a/ipaserver/plugins/topology.py
+++ b/ipaserver/plugins/topology.py
@@ -104,7 +104,7 @@ class topologysegment(LDAPObject):
object_name = _('segment')
object_name_plural = _('segments')
object_class = ['iparepltoposegment']
- permission_filter_objectclasses = ['iparepltoposegment']
+ permission_filter_objectclasses = ['iparepltoposegment', 'iparepltopoconf']
default_attributes = [
'cn',
'ipaReplTopoSegmentdirection', 'ipaReplTopoSegmentrightNode',
--
2.45.2

View File

@ -1,35 +0,0 @@
From 9de053ef02db8cb63e14edc64ac22ec2d3d7bbc9 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Mon, 17 Jun 2024 17:01:33 +0200
Subject: [PATCH] ipa-otptoken-import: open the key file in binary mode
ipa-otptoken-import provides an option (-k KEYFILE) to import
an encrypted PSKC file but this option does not work with python3
in RHEL8 and above, because the key should be passed in binary
format to the cryptography functions instead of string format.
Open the keyfile in binary mode to pass the expected format.
Fixes: https://pagure.io/freeipa/issue/9609
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipaserver/install/ipa_otptoken_import.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipaserver/install/ipa_otptoken_import.py b/ipaserver/install/ipa_otptoken_import.py
index dbaeacdf6885d3238f2d0294e24a5adad5a5c38d..d3f3d3cfa84e4a4bf57383e0ba543f4543e25c92 100644
--- a/ipaserver/install/ipa_otptoken_import.py
+++ b/ipaserver/install/ipa_otptoken_import.py
@@ -539,7 +539,7 @@ class OTPTokenImport(admintool.AdminTool):
# Load the keyfile.
keyfile = self.safe_options.keyfile
- with open(keyfile) as f:
+ with open(keyfile, "rb") as f:
self.doc.setKey(f.read())
def run(self):
--
2.45.2

View File

@ -1,39 +0,0 @@
From 09e66dc936cf2d99bcc44d60d6851aafa9ede46a Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 19 Jun 2024 15:38:36 +0200
Subject: [PATCH] spec file: do not create /etc/ssh/ssh_config.orig if
unchanged
The upgrade removes the line
HostKeyAlgorithms ssh-rsa,ssh-dss
if present in /etc/ssh/ssh_config and creates a backup in
/etc/ssh/ssh_config.orig, even if no change was applied.
Create the backup file only if the file was changed.
Fixes: https://pagure.io/freeipa/issue/9610
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
---
freeipa.spec.in | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 6803de752bc122bf6e1eafd610d399cde994cad5..1e1a0c04728972c6c53beb47dafb25d7898ab0ea 100755
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -1320,7 +1320,9 @@ if [ $1 -gt 1 ] ; then
chmod 0600 /var/log/ipaupgrade.log
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config"
if [ -f "$SSH_CLIENT_SYSTEM_CONF" ]; then
- sed -E --in-place=.orig 's/^(HostKeyAlgorithms ssh-rsa,ssh-dss)$/# disabled by ipa-client update\n# \1/' "$SSH_CLIENT_SYSTEM_CONF"
+ if grep -E -q '^HostKeyAlgorithms ssh-rsa,ssh-dss' $SSH_CLIENT_SYSTEM_CONF 2>/dev/null; then
+ sed -E --in-place=.orig 's/^(HostKeyAlgorithms ssh-rsa,ssh-dss)$/# disabled by ipa-client update\n# \1/' "$SSH_CLIENT_SYSTEM_CONF"
+ fi
# https://pagure.io/freeipa/issue/9536
# replace sss_ssh_knownhostsproxy with sss_ssh_knownhosts
if [ -f '/usr/bin/sss_ssh_knownhosts' ]; then
--
2.45.2

View File

@ -1,69 +0,0 @@
From 4d51446bd3cd9ab222f9978f8f5def1f3a37fa0e Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Thu, 20 Jun 2024 08:13:27 +0200
Subject: [PATCH] ipatests: add test for ticket 9610
Test scenario:
- ensure there is no /etc/ssh/ssh_config.orig file
- force ipa-client package reinstallation
- ensure no backup file is created in /etc/ssh/ssh_config.orig
Related: https://pagure.io/freeipa/issue/9610
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
---
ipatests/pytest_ipa/integration/tasks.py | 15 +++++++++++++++
ipatests/test_integration/test_upgrade.py | 14 ++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py
index 6665f361e0880a149ecca8c6f7c3fe1feb1f42d0..9d6b5f67a311a28c335801d59e0ff0f0c7faccdd 100755
--- a/ipatests/pytest_ipa/integration/tasks.py
+++ b/ipatests/pytest_ipa/integration/tasks.py
@@ -2550,6 +2550,21 @@ def install_packages(host, pkgs):
host.run_command(install_cmd + pkgs)
+def reinstall_packages(host, pkgs):
+ """Install packages on a remote host.
+ :param host: the host where the installation takes place
+ :param pkgs: packages to install, provided as a list of strings
+ """
+ platform = get_platform(host)
+ if platform in {'rhel', 'fedora'}:
+ install_cmd = ['/usr/bin/dnf', 'reinstall', '-y']
+ elif platform in {'debian', 'ubuntu'}:
+ install_cmd = ['apt-get', '--reinstall', 'install', '-y']
+ else:
+ raise ValueError('install_packages: unknown platform %s' % platform)
+ host.run_command(install_cmd + pkgs)
+
+
def download_packages(host, pkgs):
"""Download packages on a remote host.
:param host: the host where the download takes place
diff --git a/ipatests/test_integration/test_upgrade.py b/ipatests/test_integration/test_upgrade.py
index 182e3b5da3c758cc10913ad4eed119b0983fcc23..011de939e92790734d63da2f85be1c25349116a8 100644
--- a/ipatests/test_integration/test_upgrade.py
+++ b/ipatests/test_integration/test_upgrade.py
@@ -477,3 +477,17 @@ class TestUpgrade(IntegrationTest):
self.master.run_command(['ipa-server-upgrade'])
assert self.master.transport.file_exists(
paths.SYSTEMD_PKI_TOMCAT_IPA_CONF)
+
+ def test_ssh_config(self):
+ """Test that pkg upgrade does not create /etc/ssh/ssh_config.orig
+
+ Test for ticket 9610
+ The upgrade of ipa-client package should not create a backup file
+ /etc/ssh/ssh_config.orig if no change is applied.
+ """
+ # Ensure there is no backup file before the test
+ self.master.run_command(["rm", "-f", paths.SSH_CONFIG + ".orig"])
+ # Force client package reinstallation to trigger %post scriptlet
+ tasks.reinstall_packages(self.master, ['*ipa-client'])
+ assert not self.master.transport.file_exists(
+ paths.SSH_CONFIG + ".orig")
--
2.45.2

View File

@ -1,41 +0,0 @@
From c8e3fdeb0015f9c52c64816d6cd39279c5d3ad5a Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Thu, 20 Jun 2024 08:36:04 +0200
Subject: [PATCH] PKINIT certificate: fix renewal on hidden replica
The renewal of PKINIT cert on hidden replica is failing because
of a test ensuring that the KDC service is either enabled or
configured. The test needs to be extended and allow hidden, too.
Fixes: https://pagure.io/freeipa/issue/9611
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipaserver/plugins/cert.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
index df415c375189a54ceb0a00670f9c15e2f154a94e..6249c6d6f24acdca4fc3e9dd989f58344192b567 100644
--- a/ipaserver/plugins/cert.py
+++ b/ipaserver/plugins/cert.py
@@ -55,7 +55,7 @@ from ipapython.dn import DN
from ipapython.ipautil import datetime_from_utctimestamp
from ipaserver.plugins.service import normalize_principal, validate_realm
from ipaserver.masters import (
- ENABLED_SERVICE, CONFIGURED_SERVICE, is_service_enabled
+ ENABLED_SERVICE, CONFIGURED_SERVICE, HIDDEN_SERVICE, is_service_enabled
)
try:
@@ -300,7 +300,7 @@ def caacl_check(principal, ca, profile_id):
def ca_kdc_check(api_instance, hostname):
master_dn = api_instance.Object.server.get_dn(unicode(hostname))
kdc_dn = DN(('cn', 'KDC'), master_dn)
- wanted = {ENABLED_SERVICE, CONFIGURED_SERVICE}
+ wanted = {ENABLED_SERVICE, CONFIGURED_SERVICE, HIDDEN_SERVICE}
try:
kdc_entry = api_instance.Backend.ldap2.get_entry(
kdc_dn, ['ipaConfigString'])
--
2.45.2

View File

@ -1,54 +0,0 @@
From 467ec04f93a29fd31ba037cef348c09547541fe7 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Mon, 24 Jun 2024 09:18:54 +0200
Subject: [PATCH] ipatests: add test for PKINIT renewal on hidden replica
Test scenario: on a hidden replica, force the renewal of
PKINIT cert by calling getcert resubmit.
Related: https://pagure.io/freeipa/issue/9611
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
.../test_integration/test_replica_promotion.py | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py
index b71f2d5d7e1517ab73d79b62477a3377839b0b7a..7ef44c571c8a4106577d27f4712f661be873dacc 100644
--- a/ipatests/test_integration/test_replica_promotion.py
+++ b/ipatests/test_integration/test_replica_promotion.py
@@ -26,6 +26,7 @@ from ipalib.constants import (
)
from ipaplatform.paths import paths
from ipapython import certdb
+from ipatests.test_integration.test_cert import get_certmonger_fs_id
from ipatests.test_integration.test_dns_locations import (
resolve_records_from_server, IPA_DEFAULT_MASTER_SRV_REC
)
@@ -1241,6 +1242,23 @@ class TestHiddenReplicaPromotion(IntegrationTest):
'ipa-crlgen-manage', 'status'])
assert "CRL generation: enabled" in result.stdout_text
+ def test_hidden_replica_renew_pkinit_cert(self):
+ """Renew the PKINIT cert on a hidden replica.
+
+ Test for https://pagure.io/freeipa/issue/9611
+ """
+ # Get Request ID
+ cmd = ['getcert', 'list', '-f', paths.KDC_CERT]
+ result = self.replicas[0].run_command(cmd)
+ req_id = get_certmonger_fs_id(result.stdout_text)
+
+ self.replicas[0].run_command([
+ 'getcert', 'resubmit', '-f', paths.KDC_CERT
+ ])
+ tasks.wait_for_certmonger_status(
+ self.replicas[0], ('MONITORING'), req_id, timeout=600
+ )
+
class TestHiddenReplicaKRA(IntegrationTest):
"""Test KRA & hidden replica features.
--
2.45.2

View File

@ -1,917 +0,0 @@
From 90b22ff888cc55132c78024d08ffcf0ce8021cea Mon Sep 17 00:00:00 2001
From: Sudhir Menon <sumenon@redhat.com>
Date: Tue, 25 Jun 2024 11:00:28 +0530
Subject: [PATCH] ipatests: Tests for ipa-ipa migration tool
This patch includes tests for ipa-ipa migration
tool
Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Mark Reynolds <mreynolds@redhat.com>
---
ipaplatform/base/paths.py | 1 +
.../test_ipa_ipa_migration.py | 879 ++++++++++++++++++
2 files changed, 880 insertions(+)
create mode 100644 ipatests/test_integration/test_ipa_ipa_migration.py
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
index 2b0fc6b5aa954a1018f602605eb0cdcebcee0592..b339d2202f440e0277d50073060f4a3b55e312fe 100644
--- a/ipaplatform/base/paths.py
+++ b/ipaplatform/base/paths.py
@@ -425,6 +425,7 @@ class BasePathNamespace:
IPA_CUSTODIA_HANDLER = "/usr/libexec/ipa/custodia"
IPA_CUSTODIA_CHECK = "/usr/libexec/ipa/ipa-custodia-check"
IPA_GETKEYTAB = '/usr/sbin/ipa-getkeytab'
+ IPA_MIGRATE_LOG = '/var/log/ipa-migrate.log'
EXTERNAL_SCHEMA_DIR = '/usr/share/ipa/schema.d'
GSSPROXY_CONF = '/etc/gssproxy/10-ipa.conf'
KRB5CC_HTTPD = '/tmp/krb5cc-httpd'
diff --git a/ipatests/test_integration/test_ipa_ipa_migration.py b/ipatests/test_integration/test_ipa_ipa_migration.py
new file mode 100644
index 0000000000000000000000000000000000000000..7e2d4a34216f6cf168f15dda10ce10538a3c3cb9
--- /dev/null
+++ b/ipatests/test_integration/test_ipa_ipa_migration.py
@@ -0,0 +1,879 @@
+# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
+#
+
+"""
+Tests to verify ipa-migrate tool.
+"""
+
+from __future__ import absolute_import
+from ipatests.test_integration.base import IntegrationTest
+from ipatests.pytest_ipa.integration import tasks
+from ipaplatform.paths import paths
+
+import pytest
+import textwrap
+
+
+def prepare_ipa_server(master):
+ """
+ Setup remote IPA server environment
+ """
+ # Setup IPA users
+ for i in range(1, 5):
+ master.run_command(
+ [
+ "ipa",
+ "user-add",
+ "testuser%d" % i,
+ "--first",
+ "Test",
+ "--last",
+ "User%d" % i,
+ ]
+ )
+
+ # Setup IPA group
+ master.run_command(["ipa", "group-add", "testgroup"])
+
+ # Add respective members to each group
+ master.run_command(
+ ["ipa", "group-add-member", "testgroup", "--users=testuser1"]
+ )
+
+ # Adding stage user
+ master.run_command(
+ [
+ "ipa",
+ "stageuser-add",
+ "--first=Tim",
+ "--last=User",
+ "--password",
+ "tuser1",
+ ]
+ )
+
+ # Add Custom idrange
+ master.run_command(
+ [
+ "ipa",
+ "idrange-add",
+ "testrange",
+ "--base-id=10000",
+ "--range-size=10000",
+ "--rid-base=300000",
+ "--secondary-rid-base=400000",
+ ]
+ )
+
+ # Add Automount locations and maps
+ master.run_command(["ipa", "automountlocation-add", "baltimore"])
+ master.run_command(["ipa", "automountmap-add", "baltimore", "auto.share"])
+ master.run_command(
+ [
+ "ipa",
+ "automountmap-add-indirect",
+ "baltimore",
+ "--parentmap=auto.share",
+ "--mount=sub auto.man",
+ ]
+ )
+ master.run_command(
+ [
+ "ipa",
+ "automountkey-add",
+ "baltimore",
+ "auto.master",
+ "--key=/share",
+ "--info=auto.share",
+ ]
+ )
+
+ # Run ipa-adtrust-install
+ master.run_command(["dnf", "install", "-y", "ipa-server-trust-ad"])
+ master.run_command(
+ [
+ "ipa-adtrust-install",
+ "-a",
+ master.config.admin_password,
+ "--add-sids",
+ "-U",
+ ]
+ )
+
+ # Generate subids for users
+ master.run_command(["ipa", "subid-generate", "--owner=testuser1"])
+ master.run_command(["ipa", "subid-generate", "--owner=admin"])
+
+ # Add Sudo rules
+ master.run_command(["ipa", "sudorule-add", "readfiles"])
+ master.run_command(["ipa", "sudocmd-add", "/usr/bin/less"])
+ master.run_command(
+ [
+ "ipa",
+ "sudorule-add-allow-command",
+ "readfiles",
+ "--sudocmds",
+ "/usr/bin/less",
+ ]
+ )
+ master.run_command(
+ [
+ "ipa",
+ "sudorule-add-host",
+ "readfiles",
+ "--hosts",
+ "server.example.com",
+ ]
+ )
+ master.run_command(
+ ["ipa", "sudorule-add-user", "readfiles", "--users", "testuser1"]
+ )
+
+ # Add Custom CA
+ master.run_command(
+ [
+ "ipa",
+ "ca-add",
+ "puppet",
+ "--desc",
+ '"Puppet"',
+ "--subject",
+ "CN=Puppet CA,O=TESTRELM.TEST",
+ ]
+ )
+
+ # Add ipa roles and add privileges to the role
+ master.run_command(
+ ["ipa", "role-add", "--desc=Junior-level admin", "junioradmin"]
+ )
+ master.run_command(
+ [
+ "ipa",
+ "role-add-privilege",
+ "--privileges=User Administrators",
+ "junioradmin",
+ ]
+ )
+
+ # Add permission
+ master.run_command(
+ [
+ "ipa",
+ "permission-add",
+ "--type=user",
+ "--permissions=add",
+ "Add Users",
+ ]
+ )
+
+ # Add otp token for testuser1
+ master.run_command(
+ [
+ "ipa",
+ "otptoken-add",
+ "--type=totp",
+ "--owner=testuser1",
+ '--desc="My soft token',
+ ]
+ )
+
+ # Add a netgroup and user to the netgroup
+ master.run_command(
+ ["ipa", "netgroup-add", '--desc="NFS admins"', "admins"]
+ )
+ master.run_command(
+ ["ipa", "netgroup-add-member", "--users=testuser2", "admins"]
+ )
+
+ # Set krbpolicy policy
+ master.run_command(
+ ["ipa", "krbtpolicy-mod", "--maxlife=99999", "--maxrenew=99999"]
+ )
+ master.run_command(["ipa", "krbtpolicy-mod", "admin", "--maxlife=9600"])
+
+ # Add IPA location
+ master.run_command(
+ ["ipa", "location-add", "location", "--description", "My location"]
+ )
+
+ # Add idviews and overrides
+ master.run_command(["ipa", "idview-add", "idview1"])
+ master.run_command(["ipa", "idoverrideuser-add", "idview1", "testuser1"])
+ master.run_command(
+ [
+ "ipa",
+ "idoverrideuser-mod",
+ "idview1",
+ "testuser1",
+ "--shell=/bin/sh",
+ ]
+ )
+
+ # Add DNSzone
+ master.run_command(
+ [
+ "ipa",
+ "dnszone-add",
+ "example.test",
+ "--admin-email=admin@example.test",
+ ]
+ )
+ master.run_command(
+ ["ipa", "dnszone-mod", "example.test", "--dynamic-update=TRUE"]
+ )
+
+ # Add hbac rule
+ master.run_command(["ipa", "hbacrule-add", "--usercat=all", "test1"])
+ master.run_command(
+ ["ipa", "hbacrule-add", "--hostcat=all", "testuser_sshd"]
+ )
+ master.run_command(
+ ["ipa", "hbacrule-add-user", "--users=testuser1", "testuser_sshd"]
+ )
+ master.run_command(
+ ["ipa", "hbacrule-add-service", "--hbacsvcs=sshd", "testuser_sshd"]
+ )
+
+ # Vault addition
+ master.run_command(
+ [
+ "ipa",
+ "vault-add",
+ "--password",
+ "vault1234",
+ "--type",
+ "symmetric",
+ ]
+ )
+
+ # Add Selinuxusermap
+ master.run_command(
+ [
+ "ipa",
+ "selinuxusermap-add",
+ "--usercat=all",
+ "--selinuxuser=xguest_u:s0",
+ "test1",
+ ]
+ )
+
+ # Modify passkeyconfig
+ master.run_command(
+ ["ipa", "passkeyconfig-mod", "--require-user-verification=FALSE"]
+ )
+
+
+def run_migrate(
+ host, mode, remote_host, bind_dn=None, bind_pwd=None, extra_args=None
+):
+ """
+ ipa-migrate tool command
+ """
+ cmd = ["ipa-migrate"]
+ if mode:
+ cmd.append(mode)
+ if remote_host:
+ cmd.append(remote_host)
+ if bind_dn:
+ cmd.append("-D")
+ cmd.append(bind_dn)
+ if bind_pwd:
+ cmd.append("-w")
+ cmd.append(bind_pwd)
+ if extra_args:
+ for arg in extra_args:
+ cmd.append(arg)
+ result = host.run_command(cmd, raiseonerr=False)
+ return result
+
+
+class TestIPAMigrateScenario1(IntegrationTest):
+ """
+ Tier-1 tests for ipa-migrate tool with DNS enabled on
+ local and remote server
+ """
+
+ num_replicas = 1
+ num_clients = 1
+ topology = "line"
+
+ @classmethod
+ def install(cls, mh):
+ tasks.install_master(cls.master, setup_dns=True, setup_kra=True)
+ prepare_ipa_server(cls.master)
+ tasks.install_client(cls.master, cls.clients[0], nameservers=None)
+
+ def test_remote_server(self):
+ """
+ This test installs IPA server instead of replica on
+ system under test with the same realm and domain name.
+ """
+ tasks.install_master(self.replicas[0], setup_dns=True, setup_kra=True)
+
+ def test_ipa_migrate_without_kinit_as_admin(self):
+ """
+ This test checks that ipa-migrate tool displays
+ error when kerberos ticket is missing for admin
+ """
+ self.replicas[0].run_command(["kdestroy", "-A"])
+ KINIT_ERR_MSG = "ipa: ERROR: Did not receive Kerberos credentials\n"
+ result = run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=['-x'],
+ )
+ assert result.returncode == 1
+ assert KINIT_ERR_MSG in result.stderr_text
+ tasks.kinit_admin(self.replicas[0])
+
+ def test_ipa_migrate_log_file_is_created(self):
+ """
+ This test checks that ipa-migrate.log file is created when ipa-migrate
+ tool is run
+ """
+ run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=['-x'],
+ )
+ assert self.replicas[0].transport.file_exists(paths.IPA_MIGRATE_LOG)
+
+ def test_ipa_migrate_with_incorrect_bind_pwd(self):
+ """
+ This test checks that ipa-migrate tool fails with incorrect
+ bind password
+ """
+ ERR_MSG = (
+ "IPA to IPA migration starting ...\n"
+ "Failed to bind to remote server: Insufficient access: "
+ "Invalid credentials\n"
+ )
+ result = run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ "incorrect_bind_pwd",
+ extra_args=['-x'],
+ )
+ assert result.returncode == 1
+ assert ERR_MSG in result.stderr_text
+
+ def test_ipa_migrate_with_incorrect_bind_dn(self):
+ """
+ This test checks that ipa-migrate tool fails with incorrect
+ bind dn
+ """
+ ERR_MSG = (
+ "IPA to IPA migration starting ...\n"
+ "Failed to bind to remote server: Insufficient access: "
+ "Invalid credentials\n"
+ )
+ result = run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Dir Manager",
+ self.master.config.admin_password,
+ extra_args=['-x'],
+ )
+ assert result.returncode == 1
+ assert ERR_MSG in result.stderr_text
+
+ def test_ipa_migrate_with_invalid_host(self):
+ """
+ This test checks that ipa-migrate tools fails with
+ invalid host
+ """
+ hostname = "server.invalid.host"
+ ERR_MSG = (
+ "IPA to IPA migration starting ...\n"
+ "Failed to bind to remote server: cannot connect to "
+ "'ldap://"
+ "{}': \n".format(hostname)
+ )
+ result = run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ "server.invalid.host",
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=['-x'],
+ )
+ assert result.returncode == 1
+ assert ERR_MSG in result.stderr_text
+
+ def test_dry_run_record_output_ldif(self):
+ """
+ This testcase run ipa-migrate tool with the
+ -o option which captures the output to ldif file
+ """
+ ldif_file = "/tmp/test.ldif"
+ param = ['-x', '-o', ldif_file]
+ run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=param,
+ )
+ assert self.replicas[0].transport.file_exists("/tmp/test.ldif")
+
+ @pytest.fixture()
+ def empty_log_file(self):
+ """
+ This fixture empties the log file before ipa-migrate tool
+ is run since the log is appended everytime the tool is run.
+ """
+ self.replicas[0].run_command(
+ ["truncate", "-s", "0", paths.IPA_MIGRATE_LOG]
+ )
+ yield
+
+ def test_ipa_sigden_plugin_fail_error(self, empty_log_file):
+ """
+ This testcase checks that sidgen plugin fail error is
+ not seen during migrate prod-mode
+ """
+ SIDGEN_ERR_MSG = "SIDGEN task failed: \n"
+ run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=['-x'],
+ )
+ error_msg = self.replicas[0].get_file_contents(
+ paths.IPA_MIGRATE_LOG, encoding="utf-8"
+ )
+ assert SIDGEN_ERR_MSG not in error_msg
+
+ def test_ipa_migrate_stage_mode_dry_run(self, empty_log_file):
+ """
+ Test ipa-migrate stage mode with dry-run option
+ """
+ tasks.kinit_admin(self.master)
+ tasks.kinit_admin(self.replicas[0])
+ IPA_MIGRATE_STAGE_DRY_RUN_LOG = "--dryrun=True\n"
+ IPA_SERVER_UPRGADE_LOG = "Skipping ipa-server-upgrade in dryrun mode.\n"
+ IPA_SKIP_SIDGEN_LOG = "Skipping SIDGEN task in dryrun mode."
+ result = run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=['-x'],
+ )
+ install_msg = self.replicas[0].get_file_contents(
+ paths.IPA_MIGRATE_LOG, encoding="utf-8"
+ )
+ assert result.returncode == 0
+ assert IPA_MIGRATE_STAGE_DRY_RUN_LOG in install_msg
+ assert IPA_SERVER_UPRGADE_LOG in install_msg
+ assert IPA_SKIP_SIDGEN_LOG in install_msg
+
+ def test_ipa_migrate_prod_mode_dry_run(self, empty_log_file):
+ """
+ Test ipa-migrate prod mode with dry run option
+ """
+ tasks.kinit_admin(self.master)
+ tasks.kinit_admin(self.replicas[0])
+ IPA_MIGRATE_PROD_DRY_RUN_LOG = "--dryrun=True\n"
+ IPA_SERVER_UPRGADE_LOG = (
+ "Skipping ipa-server-upgrade in dryrun mode.\n"
+ )
+ IPA_SIDGEN_LOG = "Skipping SIDGEN task in dryrun mode.\n"
+ result = run_migrate(
+ self.replicas[0],
+ "prod-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=['-x'],
+ )
+ install_msg = self.replicas[0].get_file_contents(
+ paths.IPA_MIGRATE_LOG, encoding="utf-8"
+ )
+ assert result.returncode == 0
+ assert IPA_MIGRATE_PROD_DRY_RUN_LOG in install_msg
+ assert IPA_SERVER_UPRGADE_LOG in install_msg
+ assert IPA_SIDGEN_LOG in install_msg
+
+ def test_ipa_migrate_with_skip_schema_option_dry_run(self, empty_log_file):
+ """
+ This test checks that ipa-migrate tool works
+ with -S(schema) options in stage mode
+ """
+ param = ['-x', '-S']
+ tasks.kinit_admin(self.master)
+ tasks.kinit_admin(self.replicas[0])
+ SKIP_SCHEMA_MSG_LOG = "Schema Migration " \
+ "(migrated 0 definitions)\n"
+ run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=param,
+ )
+ install_msg = self.replicas[0].get_file_contents(
+ paths.IPA_MIGRATE_LOG, encoding="utf-8"
+ )
+ assert SKIP_SCHEMA_MSG_LOG in install_msg
+
+ def test_ipa_migrate_with_skip_config_option_dry_run(self, empty_log_file):
+ """
+ This test checks that ipa-migrate tool works
+ with -C(config) options in stage mode
+ """
+ SKIP_MIGRATION_CONFIG_LOG = "DS Configuration Migration " \
+ "(migrated 0 entries)\n"
+ param = ['-x', '-C']
+ tasks.kinit_admin(self.master)
+ tasks.kinit_admin(self.replicas[0])
+
+ run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=param,
+ )
+ install_msg = self.replicas[0].get_file_contents(
+ paths.IPA_MIGRATE_LOG, encoding="utf-8"
+ )
+ assert SKIP_MIGRATION_CONFIG_LOG in install_msg
+
+ def test_ipa_migrate_reset_range(self, empty_log_file):
+ """
+ This test checks the reset range option -r
+ along with prod-mode, since stage-mode this is done
+ automatically.
+ """
+ param = ['-r', '-n']
+ tasks.kinit_admin(self.master)
+ tasks.kinit_admin(self.replicas[0])
+ RESET_RANGE_LOG = "--reset-range=True\n"
+ run_migrate(
+ self.replicas[0],
+ "prod-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=param,
+ )
+ install_msg = self.replicas[0].get_file_contents(
+ paths.IPA_MIGRATE_LOG, encoding="utf-8"
+ )
+ assert RESET_RANGE_LOG in install_msg
+
+ def test_ipa_migrate_stage_mode_dry_override_schema(self, empty_log_file):
+ """
+ This test checks that -O option (override schema) works
+ in dry mode
+ """
+ param = ['-x', '-O', '-n']
+ tasks.kinit_admin(self.master)
+ tasks.kinit_admin(self.replicas[0])
+ SCHEMA_OVERRIDE_LOG = "--schema-overwrite=True\n"
+ run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=param,
+ )
+ install_msg = self.replicas[0].get_file_contents(
+ paths.IPA_MIGRATE_LOG, encoding="utf-8"
+ )
+ assert SCHEMA_OVERRIDE_LOG in install_msg
+
+ @pytest.mark.xfail(
+ reason="https://issues.redhat.com/browse/RHEL-45463", strict=True
+ )
+ def test_ipa_migrate_stage_mode(self, empty_log_file):
+ """
+ This test checks that ipa-migrate is successful
+ in dry run mode
+ """
+ tasks.kinit_admin(self.master)
+ tasks.kinit_admin(self.replicas[0])
+ MIGRATION_SCHEMA_LOG_MSG = "Migrating schema ...\n"
+ MIGRATION_CONFIG_LOG_MSG = "Migrating configuration ...\n"
+ IPA_UPGRADE_LOG_MSG = (
+ "Running ipa-server-upgrade ... (this make take a while)\n"
+ )
+ SIDGEN_TASK_LOG_MSG = "Running SIDGEN task ...\n"
+ MIGRATION_COMPLETE_LOG_MSG = "Migration complete!\n"
+ result = run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=['-n'],
+ )
+ install_msg = self.replicas[0].get_file_contents(
+ paths.IPA_MIGRATE_LOG, encoding="utf-8"
+ )
+ assert result.returncode == 0
+ assert MIGRATION_SCHEMA_LOG_MSG in install_msg
+ assert MIGRATION_CONFIG_LOG_MSG in install_msg
+ assert IPA_UPGRADE_LOG_MSG in install_msg
+ assert SIDGEN_TASK_LOG_MSG in install_msg
+ assert MIGRATION_COMPLETE_LOG_MSG in install_msg
+
+ def test_ipa_migrate_prod_mode(self, empty_log_file):
+ """
+ This test checks that ipa-migrate is successful
+ in prod run mode
+ """
+ tasks.kinit_admin(self.master)
+ tasks.kinit_admin(self.replicas[0])
+ MIGRATION_SCHEMA_LOG_MSG = "Migrating schema ...\n"
+ MIGRATION_DATABASE_LOG_MSG = (
+ "Migrating database ... (this make take a while)\n"
+ )
+ IPA_UPGRADE_LOG_MSG = (
+ "Running ipa-server-upgrade ... (this make take a while)\n"
+ )
+ SIDGEN_TASK_LOG_MSG = "Running SIDGEN task ...\n"
+ result = run_migrate(
+ self.replicas[0],
+ "prod-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=['-n'],
+ )
+ install_msg = self.replicas[0].get_file_contents(
+ paths.IPA_MIGRATE_LOG, encoding="utf-8"
+ )
+ assert result.returncode == 0
+ assert MIGRATION_SCHEMA_LOG_MSG in install_msg
+ assert MIGRATION_DATABASE_LOG_MSG in install_msg
+ assert IPA_UPGRADE_LOG_MSG in install_msg
+ assert SIDGEN_TASK_LOG_MSG in install_msg
+
+ def test_ipa_migrate_with_bind_pwd_file_option(self, empty_log_file):
+ """
+ This testcase checks that ipa-migrate tool
+ works with valid bind_pwd specified in a file using '-j'
+ option
+ """
+ DEBUG_MSG = "--bind-pw-file=/tmp/pwd.txt\n"
+ bind_pwd_file = "/tmp/pwd.txt"
+ bind_pwd_file_content = self.master.config.admin_password
+ self.replicas[0].put_file_contents(
+ bind_pwd_file, bind_pwd_file_content
+ )
+ param = ['-j', bind_pwd_file, '-x']
+ result = run_migrate(
+ host=self.replicas[0],
+ mode="stage-mode",
+ remote_host=self.master.hostname,
+ bind_dn="cn=Directory Manager",
+ bind_pwd=None,
+ extra_args=param,
+ )
+ install_msg = self.replicas[0].get_file_contents(
+ paths.IPA_MIGRATE_LOG, encoding="utf-8"
+ )
+ assert DEBUG_MSG in install_msg
+ assert result.returncode == 0
+
+ def test_ipa_migrate_using_db_ldif(self):
+ """
+ This test checks that ipa-migrate tool
+ works with db ldif file using -C option
+ """
+ DB_LDIF_LOG = "--db-ldif=/tmp/dse.ldif\n"
+ tasks.kinit_admin(self.master)
+ tasks.kinit_admin(self.replicas[0])
+ ldif_file_path = "/tmp/dse.ldif"
+ param = ["-f", ldif_file_path, "-n", "-x"]
+ realm_name = self.master.domain.realm
+ base_dn = str(self.master.domain.basedn)
+ dse_ldif = textwrap.dedent(
+ f"""
+ dn: cn={realm_name},cn=kerberos,{base_dn}
+ cn: {realm_name}
+ objectClass: top
+ objectClass: krbrealmcontainer
+ """
+ ).format(
+ realm_name=self.master.domain.realm,
+ base_dn=str(self.master.domain.basedn),
+ )
+ self.replicas[0].put_file_contents(ldif_file_path, dse_ldif)
+ result = run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=param,
+ )
+ install_msg = self.replicas[0].get_file_contents(
+ paths.IPA_MIGRATE_LOG, encoding="utf-8"
+ )
+ assert result.returncode == 0
+ assert DB_LDIF_LOG in install_msg
+
+ def test_ipa_migrate_using_invalid_dbldif_file(self):
+ """
+ This testcase checks that proper error msg is
+ displayed when invalid ldif file without realm is used
+ as input to schema config option -f
+ """
+ ERR_MSG = (
+ "IPA to IPA migration starting ...\n"
+ "Unable to find realm from remote LDIF\n"
+ )
+ tasks.kinit_admin(self.master)
+ tasks.kinit_admin(self.replicas[0])
+ base_dn = str(self.master.domain.basedn)
+ ldif_file = "/tmp/ldif_file"
+ param = ["-f", ldif_file, "-n", "-x"]
+ dse_ldif = textwrap.dedent(
+ """
+ version: 1
+ dn: cn=schema,{}
+
+ """
+ ).format(base_dn)
+ self.replicas[0].put_file_contents(ldif_file, dse_ldif)
+ result = run_migrate(
+ self.replicas[0],
+ "prod-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=param,
+ )
+ assert result.returncode == 2
+ assert ERR_MSG in result.stderr_text
+
+ def test_ipa_migrate_subtree_option(self):
+ """
+ This testcase checks the subtree option
+ -s along with the ipa-migrate command
+ """
+ base_dn = str(self.master.domain.basedn)
+ subtree = 'cn=security,{}'.format(base_dn)
+ params = ['-s', subtree, '-n', '-x']
+ base_dn = str(self.master.domain.basedn)
+ CUSTOM_SUBTREE_LOG = (
+ "Add db entry 'cn=security,{} - custom'"
+ ).format(base_dn)
+ dse_ldif = textwrap.dedent(
+ """
+ dn: cn=security,{base_dn}
+ changetype: add
+ objectClass:top
+ objectClass: nscontainer
+ """
+ ).format(base_dn=base_dn)
+ tasks.ldapmodify_dm(self.master, dse_ldif)
+ result = run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=params,
+ )
+ assert result.returncode == 0
+ install_msg = self.replicas[0].get_file_contents(
+ paths.IPA_MIGRATE_LOG, encoding="utf-8"
+ )
+ assert CUSTOM_SUBTREE_LOG in install_msg
+
+ @pytest.fixture()
+ def modify_dns_zone(self):
+ zone_name = 'ipatest.test'
+ self.master.run_command(
+ ["ipa", "dnszone-add", zone_name, "--force"]
+ )
+ yield
+ self.replicas[0].run_command(
+ ["ipa", "dnszone-del", zone_name]
+ )
+
+ def test_ipa_migrate_dns_option(self, modify_dns_zone):
+ """
+ This testcase checks that when migrate dns option
+ -B is used the dns entry is migrated to the
+ local host.
+ """
+ zone_name = "ipatest.test."
+ base_dn = str(self.master.domain.basedn)
+ DNS_LOG1 = "--migrate-dns=True\n"
+ DNS_LOG2 = (
+ "DEBUG Added entry: idnsname={},cn=dns,{}\n"
+ ).format(zone_name, base_dn)
+ DNS_LOG3 = (
+ "DEBUG Added entry: idnsname=_kerberos,"
+ "idnsname={},cn=dns,{}\n"
+ ).format(zone_name, base_dn)
+ params = ["-B", "-n"]
+ run_migrate(
+ self.replicas[0],
+ "prod-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=params,
+ )
+ result = self.replicas[0].run_command(["ipa", "dnszone-find"])
+ assert "Zone name: ipatest.test." in result.stdout_text
+ install_msg = self.replicas[0].get_file_contents(
+ paths.IPA_MIGRATE_LOG, encoding="utf-8"
+ )
+ assert DNS_LOG1 in install_msg
+ assert DNS_LOG2 in install_msg
+ assert DNS_LOG3 in install_msg
+
+ @pytest.mark.xfail(reason="https://issues.redhat.com/browse/RHEL-46003",
+ strict=True)
+ def test_ipa_migrate_version_option(self):
+ """
+ This testcase checks the version of
+ the ipa-migrate tool using -v option
+ """
+ CONSOLE_LOG = (
+ "ipa-migrate: error: the following arguments are "
+ "required: mode, hostname"
+ )
+ result = self.master.run_command(["ipa-migrate", "-V"])
+ assert result.returncode == 0
+ assert CONSOLE_LOG not in result.stderr_text
+
+ def test_ipa_migrate_with_log_file_option(self):
+ """
+ This testcase checks that log file is created
+ with -l option
+ """
+ custom_log_file = "/tmp/test.log"
+ params = ['-x', '-n', '-l', custom_log_file]
+ run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=params,
+ )
+ assert self.replicas[0].transport.file_exists(custom_log_file)
--
2.45.2

View File

@ -1,104 +0,0 @@
From a8e75bbb77e15e3a42adb2d30933cf9e1edd2f0b Mon Sep 17 00:00:00 2001
From: Thomas Woerner <twoerner@redhat.com>
Date: Tue, 11 Jun 2024 10:50:51 +0200
Subject: [PATCH] ipa_sidgen: Allow sidgen_task to continue after finding
issues
find_sid_for_ldap_entry could fail in several ways if a Posix ID can not
be converted to an unused SID. This could happen for example for ducplicate
IDs or user/group out of range.
This change enables ipa_sidgen_task to continue in the error case to try
to convert the entries without errors. The error messages have been
extended to additionally show the DN string for the bad entries.
Fixes: https://pagure.io/freeipa/issue/9618
Signed-off-by: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
.../ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_common.c | 11 ++++++-----
.../ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_task.c | 11 ++++++++---
2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_common.c b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_common.c
index cb763ebf8c733e50483c23856a248eb536c796f1..13f4de5416606df1911f14f60ab1af1a8ba0184b 100644
--- a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_common.c
+++ b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_common.c
@@ -491,7 +491,7 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry,
}
if (uid_number >= UINT32_MAX || gid_number >= UINT32_MAX) {
- LOG_FATAL("ID value too large.\n");
+ LOG_FATAL("ID value too large on entry [%s].\n", dn_str);
ret = LDAP_CONSTRAINT_VIOLATION;
goto done;
}
@@ -508,7 +508,7 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry,
&has_posix_group,
&has_ipa_id_object);
if (ret != 0) {
- LOG_FATAL("Cannot determine objectclasses.\n");
+ LOG_FATAL("Cannot determine objectclasses on entry [%s].\n", dn_str);
goto done;
}
@@ -522,15 +522,16 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry,
id = (uid_number != 0) ? uid_number : gid_number;
objectclass_to_add = NULL;
} else {
- LOG_FATAL("Inconsistent objectclasses and attributes, nothing to do.\n");
+ LOG_FATAL("Inconsistent objectclasses and attributes on entry "
+ "[%s], nothing to do.\n", dn_str);
ret = 0;
goto done;
}
ret = find_sid_for_id(id, plugin_id, base_dn, dom_sid, ranges, &sid);
if (ret != 0) {
- LOG_FATAL("Cannot convert Posix ID [%lu] into an unused SID.\n",
- (unsigned long) id);
+ LOG_FATAL("Cannot convert Posix ID [%lu] into an unused SID on "
+ "entry [%s].\n", (unsigned long) id, dn_str);
goto done;
}
diff --git a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_task.c b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_task.c
index 007b1c945d0e37c4061f6a33cfdd667c45118c99..67979cb9fb0b5560009643c84be7eb07d767d77f 100644
--- a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_task.c
+++ b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_task.c
@@ -89,7 +89,7 @@ static void free_pblock(void *arg)
static int do_work(struct worker_ctx *worker_ctx)
{
Slapi_PBlock *pb;
- int ret;
+ int ret, failures = 0;
size_t c;
char *filter = NULL;
char *attrs[] = { OBJECTCLASS, UID_NUMBER, GID_NUMBER, NULL };
@@ -151,8 +151,7 @@ static int do_work(struct worker_ctx *worker_ctx)
worker_ctx->base_dn, worker_ctx->dom_sid,
worker_ctx->ranges);
if (ret != 0) {
- LOG_FATAL("Cannot add SID to existing entry.\n");
- goto done;
+ failures++;
}
if (worker_ctx->delay != 0) {
@@ -162,6 +161,12 @@ static int do_work(struct worker_ctx *worker_ctx)
}
};
+ ret = failures;
+ if (ret > 0) {
+ LOG_FATAL("Finished with %d failures, please check the log.\n",
+ failures);
+ }
+
done:
slapi_ch_free_string(&filter);
pthread_cleanup_pop(1);
--
2.45.2

View File

@ -1,45 +0,0 @@
From 4521fe5f9125c74b4ad6e4e51f8c66c009079281 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Thu, 13 Jun 2024 10:39:54 +0200
Subject: [PATCH] ipatests: mark test_ca_show_error_handling as xfail
With PKI 11.5.0, the test
test_cert.py::TestCAShowErrorHandling::test_ca_show_error_handling
is failing with an exception and a different error message.
Mark as xfail until PKI provides a fix
Related: https://pagure.io/freeipa/issue/9606
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
---
ipatests/test_integration/test_cert.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/ipatests/test_integration/test_cert.py b/ipatests/test_integration/test_cert.py
index 4dd1254a2d16420bb70686f9715497dfb9048ecf..91598b655a8cd6ff92c1a0cf2166c6548a7af758 100644
--- a/ipatests/test_integration/test_cert.py
+++ b/ipatests/test_integration/test_cert.py
@@ -25,6 +25,7 @@ from pkg_resources import parse_version
from ipatests.pytest_ipa.integration import tasks
from ipatests.test_integration.base import IntegrationTest
+from ipatests.util import xfail_context
DEFAULT_RA_AGENT_SUBMITTED_VAL = '19700101000000'
@@ -555,7 +556,11 @@ class TestCAShowErrorHandling(IntegrationTest):
)
error_msg = 'ipa: ERROR: The certificate for ' \
'{} is not available on this server.'.format(lwca)
- assert error_msg in result.stderr_text
+ bad_version = (tasks.get_pki_version(self.master)
+ >= tasks.parse_version('11.5.0'))
+ with xfail_context(bad_version,
+ reason="https://pagure.io/freeipa/issue/9606"):
+ assert error_msg in result.stderr_text
def test_certmonger_empty_cert_not_segfault(self):
"""Test empty cert request doesn't force certmonger to segfault
--
2.45.2

View File

@ -1,47 +0,0 @@
From efa57193630f244185b3f295ed0de17c6d08f75a Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Mon, 8 Jul 2024 10:49:49 -0400
Subject: [PATCH] ipa-migrate - remove -V option
The versioning in ipa-migrate was removed, but the "-V" option to display the version was not removed.
Fixes: https://pagure.io/freeipa/issue/9620
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
install/tools/man/ipa-migrate.1 | 3 ---
ipaserver/install/ipa_migrate.py | 3 ---
2 files changed, 6 deletions(-)
diff --git a/install/tools/man/ipa-migrate.1 b/install/tools/man/ipa-migrate.1
index 78881d1f8a9ea91d7824e5f8b13f50aecf5ebd16..2d9d2c650a4c44a2f397d1c2ccb42fb95eea2bae 100644
--- a/install/tools/man/ipa-migrate.1
+++ b/install/tools/man/ipa-migrate.1
@@ -67,9 +67,6 @@ Reset the ID range for migrated users/groups. In "stage-mode" this is done autom
\fB\-F\fR, \fB\-\-force\fR
Ignore any errors and continue to proceed with migration effort.
.TP
-\fB\-V\fR, \fB\-\-version\fR
-Display the version of the migration tool.
-.TP
\fB\-q\fR, \fB\-\-quiet\fR
Only log errors during the migration process.
.TP
diff --git a/ipaserver/install/ipa_migrate.py b/ipaserver/install/ipa_migrate.py
index 58351af604b8d6f4ac31432a425718a4d45e0178..6be8d9ba23b36779bf6296df757c1aca551968c0 100644
--- a/ipaserver/install/ipa_migrate.py
+++ b/ipaserver/install/ipa_migrate.py
@@ -389,9 +389,6 @@ class IPAMigrate():
parser.add_argument('-F', '--force',
help='Ignore errors and continue with migration',
action='store_true', default=False)
- parser.add_argument('-V', '--version',
- help='Display verison of the migration tool',
- action='store_true', default=False)
parser.add_argument('-q', '--quiet',
help='Only display errors during the migration',
action='store_true', default=False)
--
2.45.2

View File

@ -1,37 +0,0 @@
From 1b278de4ab9c5e00fb48dc2de1ea31d9bdfc94bc Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Tue, 9 Jul 2024 14:35:25 -0400
Subject: [PATCH] Fix syntax error in the selinux-luna %postun script
It was missing a trailing fi.
This bad syntax was preventing cleanup of the
{free}ipa-selinux-luna SELinux module:
Running scriptlet: freeipa-selinux-luna-4.12.0.dev202402211727+git0ee 34/44
/var/tmp/rpm-tmp.qoCDFi: line 16: syntax error: unexpected end of file
warning: %postun(freeipa-selinux-luna-4.12.0.dev202402211727+git0eeecdcec-0.fc37.noarch) scriptlet failed, exit status
Fixes: https://pagure.io/freeipa/issue/9629
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
freeipa.spec.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 1e1a0c04728972c6c53beb47dafb25d7898ab0ea..b3b19cf8881db97307836513ff2263dc4fe4ca03 100755
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -1367,6 +1367,7 @@ fi
%postun selinux-luna
if [ $1 -eq 0 ]; then
%selinux_modules_uninstall -s %{selinuxtype} %{modulename}-luna
+fi
%posttrans selinux
%selinux_relabel_post -s %{selinuxtype}
--
2.45.2

View File

@ -1,231 +0,0 @@
From 7ab1bcb2d364c26024db4ec99c707ebefffcd3e7 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Fri, 5 Jul 2024 15:00:59 -0400
Subject: [PATCH] Re-organize HSM validation to be more consistent/less
duplication
hsm_validator() was more or less bolted in place late in the
development cycle in in order to catch some of the more common
problems: bad token name, bad password, etc.
There was a fair bit of duplication and had the side-effect of not
reading in the token password from the --token-password-file option
in some cases.
This patch also re-adds a lost feature where an exception is raised if
both the --token-password and --token-password-file options are passed
in.
This also needs to be enforced on initial server, replica and when
called by ipa-kra-install. Given that each has a unique subject of
options some duplication remains.
Fixes: https://pagure.io/freeipa/issue/9603
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
ipaserver/install/ca.py | 72 +++++++++++++++--------------
ipaserver/install/kra.py | 56 ++++++++++++++++++++--
ipaserver/install/server/install.py | 2 +
3 files changed, 93 insertions(+), 37 deletions(-)
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index dc4b47056f0e327d120ab6dad238deae3c26bbcd..b8155d9965712dbce4076e9d73d6712135309ce2 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -193,6 +193,8 @@ def hsm_validator(token_name, token_library, token_password):
if not token_name:
logger.debug("No token name, assuming not an HSM install")
return
+ if not token_password:
+ raise ValueError("No token password provided")
val, pki_version = hsm_version()
if val is False:
raise ValueError(
@@ -361,17 +363,16 @@ def install_check(standalone, replica_config, options):
host_name = options.host_name
if replica_config is None:
- if options.token_name:
- try:
- hsm_validator(
- options.token_name, options.token_library_path,
- options.token_password)
- except ValueError as e:
- raise ScriptError(str(e))
options._subject_base = options.subject_base
options._ca_subject = options.ca_subject
options._random_serial_numbers = options.random_serial_numbers
token_name = options.token_name
+ token_library_path = options.token_library_path
+ if "setup_ca" in options.__dict__:
+ setup_ca = options.setup_ca
+ else:
+ # We got here through ipa-ca-install
+ setup_ca = True
else:
# during replica install, this gets invoked before local DS is
# available, so use the remote api.
@@ -399,33 +400,36 @@ def install_check(standalone, replica_config, options):
if replica_config.setup_ca and token_name:
if not options.token_library_path:
options.token_library_path = token_library_path
- if (
- not options.token_password_file
- and not options.token_password
- ):
- if options.unattended:
- raise ScriptError("HSM token password required")
- token_password = installutils.read_password(
- f"HSM token '{token_name}'", confirm=False
- )
- if token_password is None:
- raise ScriptError("HSM token password required")
- else:
- options.token_password = token_password
-
- if options.token_password_file:
- with open(options.token_password_file, "r") as fd:
- options.token_password = fd.readline().strip()
- try:
- hsm_validator(
- token_name,
- options.token_library_path
- if options.token_library_path
- else token_library_path,
- options.token_password,
- )
- except ValueError as e:
- raise ScriptError(str(e))
+ setup_ca = replica_config.setup_ca
+
+ if setup_ca and token_name:
+ if (options.token_password_file and options.token_password):
+ raise ScriptError(
+ "token-password and token-password-file are mutually exclusive"
+ )
+ if options.token_password_file:
+ with open(options.token_password_file, "r") as fd:
+ options.token_password = fd.readline().strip()
+ if (
+ not options.token_password_file
+ and not options.token_password
+ ):
+ if options.unattended:
+ raise ScriptError("HSM token password required")
+ token_password = installutils.read_password(
+ f"HSM token '{token_name}'", confirm=False
+ )
+ if token_password is None:
+ raise ScriptError("HSM token password required")
+ else:
+ options.token_password = token_password
+
+ try:
+ hsm_validator(
+ token_name, token_library_path,
+ options.token_password)
+ except ValueError as e:
+ raise ScriptError(str(e))
if replica_config is not None and not replica_config.setup_ca:
return
diff --git a/ipaserver/install/kra.py b/ipaserver/install/kra.py
index 2c5b47590c26e37818f055cfd218c85d74e9b46c..dc3bc7c204394187bb7a5c4cc1b863a2091bdc49 100644
--- a/ipaserver/install/kra.py
+++ b/ipaserver/install/kra.py
@@ -16,10 +16,12 @@ from ipalib.kinit import kinit_keytab
from ipaplatform import services
from ipaplatform.paths import paths
from ipapython import ipautil
+from ipapython.admintool import ScriptError
from ipapython.install.core import group
from ipaserver.install import ca, cainstance
from ipaserver.install import krainstance
from ipaserver.install import dsinstance
+from ipaserver.install import installutils
from ipaserver.install import service as _service
from . import dogtag
@@ -58,13 +60,61 @@ def install_check(api, replica_config, options):
"KRA can not be installed when 'ca_host' is overriden in "
"IPA configuration file.")
+ # There are three scenarios for installing a KRA
+ # 1. At install time of the initial server
+ # 2. Using ipa-kra-install
+ # 3. At install time of a replica
+ #
+ # These tests are done in reverse order. If we are doing a
+ # replica install we can check the remote CA.
+ #
+ # If we are running ipa-kra-install then there must be a CA
+ # use that.
+ #
+ # If initial install we either have the token options or we don't.
+
+ cai = cainstance.CAInstance()
+ if replica_config is not None:
+ (token_name, token_library_path) = ca.lookup_hsm_configuration(api)
+ elif cai.is_configured() and cai.hsm_enabled:
+ (token_name, token_library_path) = ca.lookup_hsm_configuration(api)
+ elif 'token_name' in options.__dict__:
+ token_name = options.token_name
+ token_library_path = options.token_library_path
+ else:
+ token_name = None
+
+ if replica_config is not None:
+ if (
+ token_name
+ and options.token_password_file
+ and options.token_password
+ ):
+ raise ScriptError(
+ "token-password and token-password-file are mutually exclusive"
+ )
+
if options.token_password_file:
with open(options.token_password_file, "r") as fd:
options.token_password = fd.readline().strip()
- if replica_config is not None:
- (token_name, token_library) = ca.lookup_hsm_configuration(api)
- ca.hsm_validator(token_name, token_library, options.token_password)
+ if (
+ token_name
+ and not options.token_password_file
+ and not options.token_password
+ ):
+ if options.unattended:
+ raise ScriptError("HSM token password required")
+ token_password = installutils.read_password(
+ f"HSM token '{token_name}'", confirm=False
+ )
+ if token_password is None:
+ raise ScriptError("HSM token password required")
+ else:
+ options.token_password = token_password
+
+ if token_name:
+ ca.hsm_validator(token_name, token_library_path, options.token_password)
def install(api, replica_config, options, custodia):
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index 1b18873363cece5e187a7c772acfcbc6c565ee97..47db1314239906a10bb77e5fc0d4c1eddc02e2da 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -663,6 +663,8 @@ def install_check(installer):
options.token_name is not None
)
):
+ if options.unattended:
+ raise ScriptError("HSM token password required")
token_password = read_password(
f"HSM token '{options.token_name}'" , confirm=False)
if token_password is None:
--
2.45.2

View File

@ -1,192 +0,0 @@
From 4ea1ad6acae910574a524403bc82c80d24b525d6 Mon Sep 17 00:00:00 2001
From: Mohammad Rizwan <myusuf@redhat.com>
Date: Thu, 13 Jun 2024 14:07:57 +0530
Subject: [PATCH] ipatests: tests related to --token-password-file
Test automation added around the --token-password-file
option for server/replica/kra install.
Related: https://pagure.io/freeipa/issue/9603
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
ipatests/test_integration/test_hsm.py | 85 ++++++++++++++++++++++++---
1 file changed, 77 insertions(+), 8 deletions(-)
diff --git a/ipatests/test_integration/test_hsm.py b/ipatests/test_integration/test_hsm.py
index b49af12492f7dce4bd41836b220d75d9fc99b5c2..3a33c3bda6d072aa16e361b04ac2d668902bb0e9 100644
--- a/ipatests/test_integration/test_hsm.py
+++ b/ipatests/test_integration/test_hsm.py
@@ -163,6 +163,7 @@ class BaseHSMTest(IntegrationTest):
master_extra_args = []
token_password = None
token_name = None
+ token_password_file = '/tmp/token_password'
random_serial = False
@classmethod
@@ -191,7 +192,7 @@ class BaseHSMTest(IntegrationTest):
delete_hsm_token([cls.master] + cls.replicas, cls.token_name)
@classmethod
- def sync_tokens(cls, source):
+ def sync_tokens(cls, source, token_name=None):
"""Synchronize non-networked HSM tokens between machines
source: source host for the token data
"""
@@ -207,7 +208,8 @@ class BaseHSMTest(IntegrationTest):
for host in [cls.master] + cls.replicas:
if host == source:
continue
- copy_token_files(source, [host], cls.token_name)
+ copy_token_files(source, [host],
+ token_name if token_name else cls.token_name)
class TestHSMInstall(BaseHSMTest):
@@ -218,6 +220,10 @@ class TestHSMInstall(BaseHSMTest):
def test_hsm_install_replica0_ca_less_install(self):
check_version(self.master)
+
+ self.master.put_file_contents(
+ self.token_password_file, self.token_password
+ )
tasks.install_replica(
self.master, self.replicas[0], setup_ca=False,
setup_dns=True,
@@ -307,6 +313,50 @@ class TestHSMInstall(BaseHSMTest):
assert returncode == 0
assert output == "No issues found."
+ def test_hsm_install_server_password_file(self):
+ check_version(self.master)
+ # cleanup before fresh install with password file
+ for client in self.clients:
+ tasks.uninstall_client(client)
+
+ for replica in self.replicas:
+ tasks.uninstall_master(replica)
+
+ tasks.uninstall_master(self.master)
+
+ delete_hsm_token([self.master] + self.replicas, self.token_name)
+ self.token_name, self.token_password = get_hsm_token(self.master)
+ self.master.put_file_contents(self.token_password_file,
+ self.token_password)
+ self.replicas[0].put_file_contents(self.token_password_file,
+ self.token_password)
+
+ tasks.install_master(
+ self.master, setup_dns=self.master_with_dns,
+ setup_kra=self.master_with_kra,
+ setup_adtrust=self.master_with_ad,
+ extra_args=(
+ '--token-name', self.token_name,
+ '--token-library-path', hsm_lib_path,
+ '--token-password-file', self.token_password_file
+ )
+ )
+ self.sync_tokens(self.master, token_name=self.token_name)
+
+ def test_hsm_install_replica0_password_file(self):
+ check_version(self.master)
+ tasks.install_replica(
+ self.master, self.replicas[0], setup_ca=True,
+ extra_args=('--token-password-file', self.token_password_file,)
+ )
+
+ def test_hsm_install_replica0_kra_password_file(self):
+ check_version(self.master)
+ tasks.install_kra(
+ self.replicas[0],
+ extra_args=('--token-password-file', self.token_password_file,)
+ )
+
class TestHSMInstallADTrustBase(BaseHSMTest):
"""
@@ -321,7 +371,7 @@ class TestHSMInstallADTrustBase(BaseHSMTest):
check_version(self.master)
tasks.install_replica(
self.master, self.replicas[0], setup_ca=True,
- setup_adtrust=True, setup_kra=True, setup_dns=True,
+ setup_adtrust=False, setup_kra=True, setup_dns=True,
nameservers='master' if self.master_with_dns else None,
extra_args=('--token-password', self.token_password,)
)
@@ -356,7 +406,8 @@ class TestHSMcertRenewal(BaseHSMTest):
'auditSigningCert cert-pki-ca': 'caauditSigningCert'
}
CA_TRACKING_REQS.update(KRA_TRACKING_REQS)
- self.master.put_file_contents('/tmp/token_passwd', self.token_password)
+ self.master.put_file_contents(self.token_password_file,
+ self.token_password)
for nickname in CA_TRACKING_REQS:
cert = tasks.certutil_fetch_cert(
self.master,
@@ -772,6 +823,7 @@ class TestHSMcertFixReplica(BaseHSMTest):
class TestHSMNegative(IntegrationTest):
master_with_dns = False
+ token_password_file = '/tmp/token_password'
@classmethod
def install(cls, mh):
@@ -792,7 +844,6 @@ class TestHSMNegative(IntegrationTest):
'--token-password', self.token_password
)
)
- # assert 'error message non existing token name' in result.stderr_text
assert result.returncode != 0
# wrong token password
@@ -804,7 +855,6 @@ class TestHSMNegative(IntegrationTest):
'--token-password', 'token_passwd'
)
)
- # assert 'error message wrong passwd' in result.stderr_text
assert result.returncode != 0
# wrong token lib
@@ -816,7 +866,6 @@ class TestHSMNegative(IntegrationTest):
'--token-password', self.token_password
)
)
- # assert 'error message non existing token lib' in result.stderr_text
assert result.returncode != 0
def test_hsm_negative_special_char_token_name(self):
@@ -842,7 +891,27 @@ class TestHSMNegative(IntegrationTest):
'--token-password', token_passwd
)
)
- # assert 'error message non existing token lib' in result.stderr_text
+ assert result.returncode != 0
+
+ def test_hsm_negative_token_password_and_file(self):
+ """Test token-password and token-password-file at same time
+
+ Test if command fails when --token-password and --token-password-file
+ provided at the same time results into command failure.
+ """
+ check_version(self.master)
+ self.master.put_file_contents(
+ self.token_password_file, self.token_password
+ )
+ result = tasks.install_master(
+ self.master, raiseonerr=False,
+ extra_args=(
+ '--token-name', self.token_name,
+ '--token-library-path', hsm_lib_path,
+ '--token-password', self.token_password,
+ '--token-password-file', self.token_password_file
+ )
+ )
assert result.returncode != 0
--
2.45.2

View File

@ -1,36 +0,0 @@
From 6c53a22a2cacf7807df11e51492d1a2c42aeeda1 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Tue, 18 Jun 2024 11:16:07 -0400
Subject: [PATCH] Include token password options in ipa-kra-install man page
Related: https://pagure.io/freeipa/issue/9603
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
install/tools/man/ipa-kra-install.1 | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/install/tools/man/ipa-kra-install.1 b/install/tools/man/ipa-kra-install.1
index 5476a4e717584cd7c6f823e3c3cb4e4948f14875..955085bf7162863a0567356417a0886e733c0b42 100644
--- a/install/tools/man/ipa-kra-install.1
+++ b/install/tools/man/ipa-kra-install.1
@@ -54,6 +54,15 @@ Log to the given file
.TP
\fB\-\-pki\-config\-override\fR=\fIFILE\fR
File containing overrides for KRA installation.
+.SS "HSM OPTIONS"
+The token name and library path are retrieved from the existing
+installation.
+.TP
+\fB\-\-token\-password\fR=\fITOKEN_PASSWORD\fR
+The PKCS#11 token password for the HSM.
+.TP
+\fB\-\-token\-password\-file\fR=\fITOKEN_PASSWORD_FILE\fR
+The full path to a file containing the PKCS#11 token password.
.SH "EXIT STATUS"
0 if the command was successful
--
2.45.2

View File

@ -1,86 +0,0 @@
From eeade50933cb2251b43ee34c642bcae69a216655 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Mon, 8 Jul 2024 10:20:47 -0400
Subject: [PATCH] ipa-migrate - starttls does not work
We were previousily taking the provided ca cert and creating a temporary
file from it. This was incorrect and caused the secure connection to
fail. Instead just use the file path provided.
Fixes: https://pagure.io/freeipa/issue/9619
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
install/tools/man/ipa-migrate.1 | 2 +-
ipaserver/install/ipa_migrate.py | 25 +++++++++++++++++--------
2 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/install/tools/man/ipa-migrate.1 b/install/tools/man/ipa-migrate.1
index 2d9d2c650a4c44a2f397d1c2ccb42fb95eea2bae..47ae47ea4afa3a5a6fe25dd9bbd14c27ab5f1fdb 100644
--- a/install/tools/man/ipa-migrate.1
+++ b/install/tools/man/ipa-migrate.1
@@ -25,7 +25,7 @@ network interruptions)
In this mode everything will be migrated including the current user SIDs and
DNA ranges
.TP
-\fBstage\-mod\fR
+\fBstage\-mode\fR
In this mode, SIDs & DNA ranges are not migrated, and DNA attributes are reset
.SH "COMMANDS"
diff --git a/ipaserver/install/ipa_migrate.py b/ipaserver/install/ipa_migrate.py
index 6be8d9ba23b36779bf6296df757c1aca551968c0..0e19b98b5be532c513876e165561f0af176baa27 100644
--- a/ipaserver/install/ipa_migrate.py
+++ b/ipaserver/install/ipa_migrate.py
@@ -27,7 +27,6 @@ from ipalib.x509 import IPACertificate
from ipaplatform.paths import paths
from ipapython.dn import DN
from ipapython.ipaldap import LDAPClient, LDAPEntry, realm_to_ldapi_uri
-from ipapython.ipautil import write_tmp_file
from ipapython.ipa_log_manager import standard_logging_setup
from ipaserver.install.ipa_migrate_constants import (
DS_CONFIG, DB_OBJECTS, DS_INDEXES, BIND_DN, LOG_FILE_NAME,
@@ -758,13 +757,19 @@ class IPAMigrate():
insecure_bind = False
if self.args.cacertfile is not None:
- # Store CA cert into file
- tmp_ca_cert_f = write_tmp_file(self.args.cacertfile)
- cacert = tmp_ca_cert_f.name
-
# Start TLS connection (START_TLS)
- ds_conn = LDAPClient(ldapuri, cacert=cacert, start_tls=True)
- tmp_ca_cert_f.close()
+ try:
+ ds_conn = LDAPClient(ldapuri, cacert=self.args.cacertfile,
+ start_tls=True)
+ except (
+ ldap.LDAPError,
+ errors.NetworkError,
+ errors.DatabaseError,
+ IOError
+ ) as e:
+ self.handle_error(
+ f"Failed to connect to remote server: {str(e)}"
+ )
else:
# LDAP (insecure)
ds_conn = LDAPClient(ldapuri)
@@ -773,7 +778,11 @@ class IPAMigrate():
try:
ds_conn.simple_bind(DN(self.args.bind_dn), self.bindpw,
insecure_bind=insecure_bind)
- except (errors.NetworkError, errors.ACIError) as e:
+ except (
+ errors.NetworkError,
+ errors.ACIError,
+ errors.DatabaseError
+ ) as e:
self.handle_error(f"Failed to bind to remote server: {str(e)}")
# All set, stash the remote connection
--
2.45.2

View File

@ -1,232 +0,0 @@
From 051d61fdc301f2768ac78c45e93a5f9eeff8aa28 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Tue, 25 Jun 2024 14:27:24 +0300
Subject: [PATCH] ipa-pwd-extop: differentiate OTP requirements in LDAP binds
For users who has no OTP tokens defined (yet), a missing token should
not be seen as a failure. This is needed to allow a basic password
change.
The logic around enforcement of OTP over LDAP bind is the following:
----------------------------------------------------------------------
- when LDAP OTP control is requested by the LDAP client, OTP is
explicitly required
- when EnforceLDAPOTP is set in the IPA configuration, OTP is implicitly
required, regardless of the state of LDAP client
In either case, only users with 'user-auth-type: otp' are allowed to
authenticate.
If these users have no OTP token associated yet, they will be allowed to
authenticate with their password. This is to allow initial password
change and adding an OTP token.
----------------------------------------------------------------------
Implement test that simulates lifecycle for new user who get to change
their password before adding an OTP token.
Related: https://pagure.io/freeipa/issue/5169
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
.../ipa-slapi-plugins/ipa-pwd-extop/prepost.c | 39 ++++++++++----
ipatests/test_integration/test_otp.py | 52 ++++++++++++++++---
2 files changed, 76 insertions(+), 15 deletions(-)
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
index cc170fc4b81f8ecad88f4ff4401b5651c43aaf55..c967e2cfffbd920280639f3188783ec150523b47 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
@@ -1212,13 +1212,20 @@ done:
* value at the end. This leaves only the password in creds for later
* validation.
*/
+typedef enum {
+ OTP_IS_NOT_REQUIRED = 0,
+ OTP_IS_REQUIRED_EXPLICITLY,
+ OTP_IS_REQUIRED_IMPLICITLY
+} otp_req_enum;
static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
- struct berval *creds, bool otpreq)
+ struct berval *creds, otp_req_enum otpreq,
+ bool *notokens)
{
uint32_t auth_types;
/* Get the configured authentication types. */
auth_types = otp_config_auth_types(otp_config, entry);
+ *notokens = false;
/*
* IMPORTANT SECTION!
@@ -1248,7 +1255,11 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
/* With no tokens, succeed if tokens aren't required. */
if (tokens[0] == NULL) {
otp_token_free_array(tokens);
- return !otpreq;
+ *notokens = true;
+ if (otpreq != OTP_IS_NOT_REQUIRED)
+ /* DENY: OTP is required, either explicitly or implicitly */
+ return false;
+ return true;
}
if (otp_token_validate_berval(tokens, creds, NULL)) {
@@ -1259,7 +1270,8 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
otp_token_free_array(tokens);
}
- return (auth_types & OTP_CONFIG_AUTH_TYPE_PASSWORD) && !otpreq;
+ return (auth_types & OTP_CONFIG_AUTH_TYPE_PASSWORD) &&
+ (otpreq == OTP_IS_NOT_REQUIRED);
}
static int ipapwd_authenticate(const char *dn, Slapi_Entry *entry,
@@ -1452,6 +1464,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
struct tm expire_tm;
int rc = LDAP_INVALID_CREDENTIALS;
char *errMesg = NULL;
+ bool notokens = false;
/* get BIND parameters */
ret |= slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &target_sdn);
@@ -1510,8 +1523,9 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
/* Try to do OTP first. */
syncreq = otpctrl_present(pb, OTP_SYNC_REQUEST_OID);
- otpreq = otpctrl_present(pb, OTP_REQUIRED_OID);
- if (!syncreq && !otpreq) {
+ otpreq = otpctrl_present(pb, OTP_REQUIRED_OID) ?
+ OTP_IS_REQUIRED_EXPLICITLY : OTP_IS_NOT_REQUIRED;
+ if (!syncreq && (otpreq == OTP_IS_NOT_REQUIRED)) {
ret = ipapwd_gen_checks(pb, &errMesg, &krbcfg, IPAPWD_CHECK_ONLY_CONFIG);
if (ret != 0) {
LOG_FATAL("ipapwd_gen_checks failed!?\n");
@@ -1520,11 +1534,17 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
return 0;
}
if (krbcfg->enforce_ldap_otp) {
- otpreq = true;
+ otpreq = OTP_IS_REQUIRED_IMPLICITLY;
}
}
- if (!syncreq && !ipapwd_pre_bind_otp(dn, entry, credentials, otpreq))
- goto invalid_creds;
+ if (!syncreq && !ipapwd_pre_bind_otp(dn, entry,
+ credentials, otpreq, &notokens)) {
+ /* We got here because ipapwd_pre_bind_otp() returned false,
+ * it means that either token verification failed or
+ * a rule for empty tokens failed current policy. */
+ if (!(notokens || (otpreq == OTP_IS_NOT_REQUIRED)))
+ goto invalid_creds;
+ }
/* Ensure that there is a password. */
if (credentials->bv_len == 0) {
@@ -1561,7 +1581,8 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
* for access log to notice multi-factor authentication has happened
* https://www.port389.org/docs/389ds/design/mfa-operation-note-design.html
*/
- if (!syncreq && otpreq) {
+ if (!syncreq &&
+ ((otpreq != OTP_IS_NOT_REQUIRED) && !notokens)) {
slapi_pblock_set_flag_operation_notes(pb, SLAPI_OP_NOTE_MFA_AUTH);
}
#endif
diff --git a/ipatests/test_integration/test_otp.py b/ipatests/test_integration/test_otp.py
index d2dfca4cbf8c60955e888b6f92bd88a2608bb265..350371bfe1e4c1cc6dcc89f6584f813fcb0d32a0 100644
--- a/ipatests/test_integration/test_otp.py
+++ b/ipatests/test_integration/test_otp.py
@@ -458,41 +458,81 @@ class TestOTPToken(IntegrationTest):
master = self.master
basedn = master.domain.basedn
USER1 = 'user-forced-otp'
+ TMP_PASSWORD = 'Secret1234509'
binddn = DN(f"uid={USER1},cn=users,cn=accounts,{basedn}")
- tasks.create_active_user(master, USER1, PASSWORD)
tasks.kinit_admin(master)
+ master.run_command(['ipa', 'pwpolicy-mod', '--minlife', '0'])
+ tasks.user_add(master, USER1, password=TMP_PASSWORD)
# Enforce use of OTP token for this user
master.run_command(['ipa', 'user-mod', USER1,
'--user-auth-type=otp'])
try:
+ # Change initial password through the IPA endpoint
+ url = f'https://{master.hostname}/ipa/session/change_password'
+ master.run_command(['curl', '-d', f'user={USER1}',
+ '-d', f'old_password={TMP_PASSWORD}',
+ '-d', f'new_password={PASSWORD}',
+ '--referer', f'https://{master.hostname}/ipa',
+ url])
conn = master.ldap_connect()
# First, attempt authenticating with a password but without LDAP
# control to enforce OTP presence and without server-side
# enforcement of the OTP presence check.
conn.simple_bind(binddn, f"{PASSWORD}")
- # Add an OTP token now
- otpuid, totp = add_otptoken(master, USER1, otptype="totp")
# Next, enforce Password+OTP for a user with OTP token
master.run_command(['ipa', 'config-mod', '--addattr',
'ipaconfigstring=EnforceLDAPOTP'])
+ # Try to bind without OTP because there is no OTP token yet,
+ # the operation should succeed because OTP enforcement is implicit
+ # and there is no token yet, so it is allowed.
+ conn.simple_bind(binddn, f"{PASSWORD}")
+ conn.unbind()
+ # Add an OTP token now
+ otpuid, totp = add_otptoken(master, USER1, otptype="totp")
# Next, authenticate with Password+OTP and with the LDAP control
# this operation should succeed
otpvalue = totp.generate(int(time.time())).decode("ascii")
+ conn = master.ldap_connect()
conn.simple_bind(binddn, f"{PASSWORD}{otpvalue}",
client_controls=[
BooleanControl(
controlType="2.16.840.1.113730.3.8.10.7",
booleanValue=True)])
- # Remove token
- del_otptoken(self.master, otpuid)
+ conn.unbind()
+ # Sleep to make sure we are going to use a different token value
+ time.sleep(45)
+ # Use OTP token again, without LDAP control, should succeed
+ # because OTP enforcement is implicit
+ otpvalue = totp.generate(int(time.time())).decode("ascii")
+ conn = master.ldap_connect()
+ conn.simple_bind(binddn, f"{PASSWORD}{otpvalue}")
+ conn.unbind()
# Now, try to authenticate without otp and without control
- # this operation should fail
+ # this operation should fail because we have OTP token associated
+ # with the user account
try:
+ conn = master.ldap_connect()
conn.simple_bind(binddn, f"{PASSWORD}")
+ conn.unbind()
except errors.ACIError:
pass
+ # Sleep to make sure we are going to use a different token value
+ time.sleep(45)
+ # Use OTP token again, without LDAP control, should succeed
+ # because OTP enforcement is implicit
+ otpvalue = totp.generate(int(time.time())).decode("ascii")
+ # Finally, change password again, now that otp is present
+ master.run_command(['curl', '-d', f'user={USER1}',
+ '-d', f'old_password={PASSWORD}',
+ '-d', f'new_password={TMP_PASSWORD}0',
+ '-d', f'otp={otpvalue}',
+ '--referer', f'https://{master.hostname}/ipa',
+ url])
+ # Remove token
+ del_otptoken(self.master, otpuid)
master.run_command(['ipa', 'config-mod', '--delattr',
'ipaconfigstring=EnforceLDAPOTP'])
finally:
+ master.run_command(['ipa', 'pwpolicy-mod', '--minlife', '1'])
master.run_command(['ipa', 'user-del', USER1])
--
2.45.2

View File

@ -1,74 +0,0 @@
From 8b703150a47bf509f37856bdc27cfa99e85e5e6b Mon Sep 17 00:00:00 2001
From: Anuja More <amore@redhat.com>
Date: Mon, 24 Jun 2024 13:48:24 +0530
Subject: [PATCH] ipatests: Test replica installation using AD admin.
Test to verify that replica connection check is not failing when
the AD administrator Administrator@AD.EXAMPLE.COM is
used for the deployment or promotion of a replica
Related: https://pagure.io/freeipa/issue/9542
Signed-off-by: Anuja More <amore@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
.../test_replica_promotion.py | 46 +++++++++++++++++++
1 files changed, 46 insertions(+)
diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py
index 7ef44c571c8a4106577d27f4712f661be873dacc..c754cef88cb275987f5afdaad43f2ea07e3b7476 100644
--- a/ipatests/test_integration/test_replica_promotion.py
+++ b/ipatests/test_integration/test_replica_promotion.py
@@ -1318,3 +1318,49 @@ class TestHiddenReplicaKRA(IntegrationTest):
self.replicas[0].hostname, '--state=hidden'
])
assert result.returncode == 0
+
+
+class TestReplicaConn(IntegrationTest):
+ num_replicas = 1
+ num_ad_domains = 1
+
+ @classmethod
+ def install(cls, mh):
+ cls.replica = cls.replicas[0]
+ cls.ad = cls.ads[0]
+ ad_domain = cls.ad.domain.name
+ cls.ad_admin = 'Administrator@{}'.format(ad_domain.upper())
+ cls.adview = 'Default Trust View'
+ tasks.install_master(cls.master, setup_adtrust=True)
+ tasks.configure_dns_for_trust(cls.master, cls.ad)
+ tasks.establish_trust_with_ad(cls.master, cls.ad.domain.name)
+ tasks.install_client(cls.master, cls.replica)
+
+ def test_replica_conncheck_ad_admin(self):
+ """
+ Test to verify that replica installation is not failing for
+ replica connection check when AD administrator
+ Administrator@AD.EXAMPLE.COM is used for the deployment
+ or promotion of a replica.
+
+ Related : https://pagure.io/freeipa/issue/9542
+ """
+ self.master.run_command(
+ ['ipa', 'idoverrideuser-add', self.adview, self.ad_admin]
+ )
+ self.master.run_command(
+ ["ipa", "group-add-member", "admins", "--idoverrideusers",
+ self.ad_admin]
+ )
+ tasks.clear_sssd_cache(self.master)
+
+ self.replica.run_command(
+ ["ipa-replica-install", "--setup-ca", "-U", "--ip-address",
+ self.replica.ip, "--realm", self.replica.domain.realm,
+ "--domain", self.replica.domain.name,
+ "--principal={0}".format(self.ad_admin),
+ "--password", self.master.config.ad_admin_password]
+ )
+ logs = self.replica.get_file_contents(paths.IPAREPLICA_CONNCHECK_LOG)
+ error = "not allowed to perform server connection check"
+ assert error.encode() not in logs
--
2.45.2

View File

@ -1,46 +0,0 @@
From 85a853ba93c1d23d5bad13a1ae2bee802dc90131 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Mon, 8 Jul 2024 11:25:53 -0400
Subject: [PATCH] Issue 9621 - ipa-migrate - should not update mapped
attributes in managed entries
We should not migrate mmapped attributes (uidNumber, gidNumber) from
managed entries
We should also not migrate DNA ranges in staging mode
Fixes: https://pagure.io/freeipa/issue/9621
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipaserver/install/ipa_migrate.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/ipaserver/install/ipa_migrate.py b/ipaserver/install/ipa_migrate.py
index 0e19b98b5be532c513876e165561f0af176baa27..20f59f84db21022b66c0aa1ffd696d99aef85a44 100644
--- a/ipaserver/install/ipa_migrate.py
+++ b/ipaserver/install/ipa_migrate.py
@@ -1322,6 +1322,9 @@ class IPAMigrate():
self.args.reset_range
or self.mode == "stage-mode"
) and attr.lower() in DNA_REGEN_ATTRS:
+ # Skip dna attributes from managed entries
+ if 'mepManagedBy' in local_entry:
+ break
# Ok, set the magic regen value
local_entry[attr] = [DNA_REGEN_VAL]
self.log_debug("Resetting the DNA range for: "
@@ -1816,6 +1819,9 @@ class IPAMigrate():
# processing the entries
for entry in remote_dse:
for dse_item in DS_CONFIG.items():
+ if dse_item[0] == "dna" and self.mode == "stage-mode":
+ # Do not migrate DNA ranges in staging mode
+ continue
dse = dse_item[1]
for dn in dse['dn']:
if DN(dn) == DN(entry['dn']):
--
2.45.2

View File

@ -1,50 +0,0 @@
From de940802bb6631fbbc97afd11869d87cba18f47f Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 17 Jul 2024 18:32:37 +0200
Subject: [PATCH] ipatests: remove xfail for test_ipa_migrate_version_option
The test test_ipa_ipa_migration.py::TestIPAMigrateScenario1::
test_ipa_migrate_version_option is now passing, issue has been fixed.
The -V option has been removed.
Related: https://pagure.io/freeipa/issue/9620
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Sudhir Menon <sumenon@redhat.com>
---
ipatests/test_integration/test_ipa_ipa_migration.py | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/ipatests/test_integration/test_ipa_ipa_migration.py b/ipatests/test_integration/test_ipa_ipa_migration.py
index 7e2d4a34216f6cf168f15dda10ce10538a3c3cb9..9aa8a9f32071f122ebb247ba8a1aff041e4fd49a 100644
--- a/ipatests/test_integration/test_ipa_ipa_migration.py
+++ b/ipatests/test_integration/test_ipa_ipa_migration.py
@@ -846,20 +846,18 @@ class TestIPAMigrateScenario1(IntegrationTest):
assert DNS_LOG2 in install_msg
assert DNS_LOG3 in install_msg
- @pytest.mark.xfail(reason="https://issues.redhat.com/browse/RHEL-46003",
- strict=True)
def test_ipa_migrate_version_option(self):
"""
- This testcase checks the version of
- the ipa-migrate tool using -v option
+ The -V option has been removed.
"""
CONSOLE_LOG = (
"ipa-migrate: error: the following arguments are "
"required: mode, hostname"
)
- result = self.master.run_command(["ipa-migrate", "-V"])
- assert result.returncode == 0
- assert CONSOLE_LOG not in result.stderr_text
+ result = self.master.run_command(["ipa-migrate", "-V"],
+ raiseonerr=False)
+ assert result.returncode == 2
+ assert CONSOLE_LOG in result.stderr_text
def test_ipa_migrate_with_log_file_option(self):
"""
--
2.45.2

View File

@ -1,33 +0,0 @@
From 6eb6a929308c2916df9aed2da9ee6ef9d98e2438 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 17 Jul 2024 18:36:24 +0200
Subject: [PATCH] ipatests: remove xfail for test_ipa_migrate_stage_mode
The test test_ipa_ipa_migration.py::TestIPAMigrateScenario1
::test_ipa_migrate_stage_mode is now passing, the issue has been fixed.
Related: https://pagure.io/freeipa/issue/9621
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Sudhir Menon <sumenon@redhat.com>
---
ipatests/test_integration/test_ipa_ipa_migration.py | 3 ---
1 file changed, 3 deletions(-)
diff --git a/ipatests/test_integration/test_ipa_ipa_migration.py b/ipatests/test_integration/test_ipa_ipa_migration.py
index 9aa8a9f32071f122ebb247ba8a1aff041e4fd49a..a516941047315e07407b8063a7010526d384ab3b 100644
--- a/ipatests/test_integration/test_ipa_ipa_migration.py
+++ b/ipatests/test_integration/test_ipa_ipa_migration.py
@@ -600,9 +600,6 @@ class TestIPAMigrateScenario1(IntegrationTest):
)
assert SCHEMA_OVERRIDE_LOG in install_msg
- @pytest.mark.xfail(
- reason="https://issues.redhat.com/browse/RHEL-45463", strict=True
- )
def test_ipa_migrate_stage_mode(self, empty_log_file):
"""
This test checks that ipa-migrate is successful
--
2.45.2

View File

@ -1,26 +0,0 @@
From d1a485a435ea9dba7587d1998451a09d3aa4077b Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Wed, 17 Jul 2024 15:45:06 +0200
Subject: [PATCH] Unconditionally add MS-PAC to global config on update
Fixes: https://pagure.io/freeipa/issue/9632
Signed-off-by: Julien Rische <jrische@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
install/updates/60-trusts.update | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/install/updates/60-trusts.update b/install/updates/60-trusts.update
index 56e392044a2fae97ab2f26d8afcffa6a872d41c8..b2fdccae74accf934c9f9e7d83fe63459c1e48b4 100644
--- a/install/updates/60-trusts.update
+++ b/install/updates/60-trusts.update
@@ -54,4 +54,4 @@ add:aci: (target="ldap:///krbprincipalname=cifs/($$dn),cn=services,cn=accounts,$
# Add the default PAC type to configuration
dn: cn=ipaConfig,cn=etc,$SUFFIX
-addifnew: ipaKrbAuthzData: MS-PAC
+add: ipaKrbAuthzData: MS-PAC
--
2.45.2

View File

@ -1,26 +0,0 @@
From 9f88188204e443dd5d1d22ebe65b947452558f66 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Wed, 17 Jul 2024 15:47:33 +0200
Subject: [PATCH] Remove RC4 and 3DES default encryption types on update
Fixes: https://pagure.io/freeipa/issue/9633
Signed-off-by: Julien Rische <jrische@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
install/updates/50-krbenctypes.update | 2 ++
1 file changed, 2 insertions(+)
diff --git a/install/updates/50-krbenctypes.update b/install/updates/50-krbenctypes.update
index 1058a92d8f5a4971e9ecab52506981b8e470ff77..1bf2bf33a6566586639767771dff501d91a03508 100644
--- a/install/updates/50-krbenctypes.update
+++ b/install/updates/50-krbenctypes.update
@@ -7,3 +7,5 @@ add: krbSupportedEncSaltTypes: aes128-sha2:normal
add: krbSupportedEncSaltTypes: aes128-sha2:special
add: krbSupportedEncSaltTypes: aes256-sha2:normal
add: krbSupportedEncSaltTypes: aes256-sha2:special
+remove: krbDefaultEncSaltTypes: des3-hmac-sha1:special
+remove: krbDefaultEncSaltTypes: arcfour-hmac:special
--
2.45.2

View File

@ -1,33 +0,0 @@
From fdd471d55c73503456683b1dea55769700730b16 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Thu, 18 Jul 2024 13:40:28 -0400
Subject: [PATCH] Fix a copy/paste issue when detecting the HSM SELinux
subpackage
I made a mistake when trying to detect which HSM is being used
to ensure that the appropriate SELinux subpackage is installed.
Fixes: https://pagure.io/freeipa/issue/9636
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
ipaserver/install/ca.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index b8155d9965712dbce4076e9d73d6712135309ce2..e57dc47587fa0e0a6dbbe7511784af065560d782 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -265,7 +265,7 @@ def hsm_validator(token_name, token_library, token_password):
if 'nfast' in token_library:
module = 'ipa-selinux-nfast'
elif 'luna' in token_library:
- module = 'ipa-selinux-nfast'
+ module = 'ipa-selinux-luna'
else:
module = None
if module:
--
2.45.2

View File

@ -1,36 +0,0 @@
From 0e4fbc3b0d15fd219d831b0b49f5312894448206 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Mon, 29 Jul 2024 09:58:30 -0400
Subject: [PATCH] ipa-migrate - properly handle invalid certificates
A ValueError is raised when an invalid certificate is used, so the tool
should handle this properly and not produce a stack trace.
Fixes: https://pagure.io/freeipa/issue/9642
Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipaserver/install/ipa_migrate.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/ipaserver/install/ipa_migrate.py b/ipaserver/install/ipa_migrate.py
index 20f59f84db21022b66c0aa1ffd696d99aef85a44..e21937401b3463335d8297b41a403405071d3795 100644
--- a/ipaserver/install/ipa_migrate.py
+++ b/ipaserver/install/ipa_migrate.py
@@ -761,6 +761,12 @@ class IPAMigrate():
try:
ds_conn = LDAPClient(ldapuri, cacert=self.args.cacertfile,
start_tls=True)
+ except ValueError:
+ # Most likely invalid certificate
+ self.handle_error(
+ "Failed to connect to remote server: "
+ "CA certificate is invalid"
+ )
except (
ldap.LDAPError,
errors.NetworkError,
--
2.45.2

View File

@ -1,73 +0,0 @@
From f03a96a7b914eb5130552cea626fd28e26b2108d Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Mon, 15 Jul 2024 10:21:28 -0400
Subject: [PATCH] ipatests: Fix usage of token_password_file
There were a few hardcoded places where it was set to
/tmp/token_passwd instead of using the class variable.
Don't rely on previous running tests installing the token
password file so they can be run individually.
Fixes: https://pagure.io/freeipa/issue/9603
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
ipatests/test_integration/test_hsm.py | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/ipatests/test_integration/test_hsm.py b/ipatests/test_integration/test_hsm.py
index 3a33c3bda6d072aa16e361b04ac2d668902bb0e9..64305460a5150dfc28a4ab378ac72cd38987184c 100644
--- a/ipatests/test_integration/test_hsm.py
+++ b/ipatests/test_integration/test_hsm.py
@@ -173,6 +173,9 @@ class BaseHSMTest(IntegrationTest):
cls.master.run_command(['usermod', 'pkiuser', '-a', '-G', 'ods'])
cls.token_name, cls.token_password = get_hsm_token(cls.master)
+ cls.master.put_file_contents(
+ cls.token_password_file, cls.token_password
+ )
tasks.install_master(
cls.master, setup_dns=cls.master_with_dns,
setup_kra=cls.master_with_kra,
@@ -220,10 +223,6 @@ class TestHSMInstall(BaseHSMTest):
def test_hsm_install_replica0_ca_less_install(self):
check_version(self.master)
-
- self.master.put_file_contents(
- self.token_password_file, self.token_password
- )
tasks.install_replica(
self.master, self.replicas[0], setup_ca=False,
setup_dns=True,
@@ -412,7 +411,7 @@ class TestHSMcertRenewal(BaseHSMTest):
cert = tasks.certutil_fetch_cert(
self.master,
paths.PKI_TOMCAT_ALIAS_DIR,
- '/tmp/token_passwd',
+ self.token_password_file,
nickname,
token_name=self.token_name,
)
@@ -428,13 +427,14 @@ class TestHSMcertRenewal(BaseHSMTest):
status = tasks.wait_for_request(self.master, request_id[0], 120)
assert status == "MONITORING"
- args = ['-L', '-h', self.token_name, '-f', '/tmp/token_passwd']
+ args = ['-L', '-h', self.token_name, '-f',
+ self.token_password_file,]
tasks.run_certutil(self.master, args, paths.PKI_TOMCAT_ALIAS_DIR)
cert = tasks.certutil_fetch_cert(
self.master,
paths.PKI_TOMCAT_ALIAS_DIR,
- '/tmp/token_passwd',
+ self.token_password_file,
nickname,
token_name=self.token_name,
)
--
2.45.2

View File

@ -1,175 +0,0 @@
From 38b83c2b9329b8b16096d63e83f186c91d578ce8 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Wed, 10 Jul 2024 16:14:46 -0400
Subject: [PATCH] Run HSM validation as pkiuser to verify token permissions
Run all commands as pkiuser when validating that the HSM token
is available, that the token library path is correct and that
the password can read keys. This will avoid issues where the
initial validation is ok but the pkiuser is not granted read
access to some part of the token. This is very possible
when using softhsm2.
Fixes: https://pagure.io/freeipa/issue/9626
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
ipaserver/install/ca.py | 20 ++++++++--
ipatests/test_integration/test_hsm.py | 57 +++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 3 deletions(-)
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index e57dc47587fa0e0a6dbbe7511784af065560d782..9ff91b9cc42673138eee6fa8e0eb46b323be8b1d 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -18,6 +18,7 @@ import six
from ipalib.constants import IPA_CA_CN
from ipalib.install import certstore
from ipalib.install.service import enroll_only, master_install_only, replica_install_only
+from ipaplatform.constants import constants
from ipaserver.install import sysupgrade
from ipapython.install import typing
from ipapython.install.core import group, knob, extend_knob
@@ -208,8 +209,15 @@ def hsm_validator(token_name, token_library, token_password):
raise ValueError(
"Token library path '%s' does not exist" % token_library
)
+ pkiuser = constants.PKI_USER
+ pkigroup = constants.PKI_GROUP
+ if 'libsofthsm' in token_library:
+ import grp
+ group = grp.getgrnam(constants.ODS_GROUP)
+ if str(constants.PKI_USER) in group.gr_mem:
+ pkigroup = constants.ODS_GROUP
with certdb.NSSDatabase() as tempnssdb:
- tempnssdb.create_db()
+ tempnssdb.create_db(user=str(pkiuser), group=str(pkigroup))
# Try adding the token library to the temporary database in
# case it isn't already available. Ignore all errors.
command = [
@@ -223,6 +231,7 @@ def hsm_validator(token_name, token_library, token_password):
# It may fail if p11-kit has already registered the library, that's
# ok.
ipautil.run(command, stdin='\n', cwd=tempnssdb.secdir,
+ runas=pkiuser, suplementary_groups=[pkigroup],
raiseonerr=False)
command = [
@@ -232,7 +241,8 @@ def hsm_validator(token_name, token_library, token_password):
'-force'
]
lines = ipautil.run(
- command, cwd=tempnssdb.secdir, capture_output=True).output
+ command, cwd=tempnssdb.secdir, capture_output=True,
+ runas=pkiuser, suplementary_groups=[pkigroup]).output
found = False
token_line = f'token: {token_name}'
for line in lines.split('\n'):
@@ -241,9 +251,11 @@ def hsm_validator(token_name, token_library, token_password):
break
if not found:
raise ValueError(
- "Token named '%s' was not found" % token_name
+ "Token named '%s' was not found. Check permissions"
+ % token_name
)
pwdfile = ipautil.write_tmp_file(token_password)
+ os.fchown(pwdfile.fileno(), pkiuser.uid, pkigroup.gid)
args = [
paths.CERTUTIL,
"-d", '{}:{}'.format(tempnssdb.dbtype, tempnssdb.secdir),
@@ -252,6 +264,8 @@ def hsm_validator(token_name, token_library, token_password):
"-f", pwdfile.name,
]
result = ipautil.run(args, cwd=tempnssdb.secdir,
+ runas=pkiuser,
+ suplementary_groups=[pkigroup],
capture_error=True, raiseonerr=False)
if result.returncode != 0 and len(result.error_output):
if 'SEC_ERROR_BAD_PASSWORD' in result.error_output:
diff --git a/ipatests/test_integration/test_hsm.py b/ipatests/test_integration/test_hsm.py
index 64305460a5150dfc28a4ab378ac72cd38987184c..974820fc7363b77fd5fdecc7cf0efca412f3af42 100644
--- a/ipatests/test_integration/test_hsm.py
+++ b/ipatests/test_integration/test_hsm.py
@@ -833,6 +833,13 @@ class TestHSMNegative(IntegrationTest):
cls.token_name, cls.token_password = get_hsm_token(cls.master)
+ @classmethod
+ def uninstall(cls, mh):
+ cls.master.run_command(
+ ['softhsm2-util', '--delete-token', '--token', cls.token_name],
+ raiseonerr=False
+ )
+
def test_hsm_negative_wrong_token_details(self):
check_version(self.master)
# wrong token name
@@ -868,6 +875,51 @@ class TestHSMNegative(IntegrationTest):
)
assert result.returncode != 0
+ def test_hsm_negative_bad_token_dir_permissions(self):
+ """Create an unreadable softhsm2 token and install should fail.
+
+ This is most often seen on replicas where the pkiuser is not
+ a member of the ods group.
+ """
+ check_version(self.master)
+ token_name = 'bad_perms'
+ token_passwd = 'Secret123'
+ self.master.run_command(
+ ['softhsm2-util', '--delete-token', '--token', token_name],
+ raiseonerr=False
+ )
+ self.master.run_command(
+ ['usermod', 'pkiuser', '-a', '-G', 'ods']
+ )
+ self.master.run_command(
+ ['softhsm2-util', '--init-token',
+ '--free', '--pin', token_passwd, '--so-pin', token_passwd,
+ '--label', token_name]
+ )
+ self.master.run_command(
+ ['usermod', 'pkiuser', '-r', '-G', 'ods']
+ )
+ result = tasks.install_master(
+ self.master, raiseonerr=False,
+ extra_args=(
+ '--token-name', token_name,
+ '--token-library-path', hsm_lib_path,
+ '--token-password', token_passwd
+ )
+ )
+ self.master.run_command(
+ ['usermod', 'pkiuser', '-a', '-G', 'ods']
+ )
+ self.master.run_command(
+ ['softhsm2-util', '--delete-token', '--token', token_name],
+ raiseonerr=False
+ )
+ assert result.returncode != 0
+ assert (
+ f"Token named '{token_name}' was not found"
+ in result.stderr_text
+ )
+
def test_hsm_negative_special_char_token_name(self):
check_version(self.master)
token_name = 'hsm:token'
@@ -912,6 +964,11 @@ class TestHSMNegative(IntegrationTest):
'--token-password-file', self.token_password_file
)
)
+ self.master.run_command(
+ ['softhsm2-util', '--delete-token', '--token', self.token_name],
+ raiseonerr=False
+ )
+ # assert 'error message non existing token lib' in result.stderr_text
assert result.returncode != 0
--
2.45.2

View File

@ -1,163 +0,0 @@
From aadb8051d4a3172aac3790f47ff4d241a245bab4 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Thu, 18 Jul 2024 12:57:36 +0200
Subject: [PATCH] Replica CA installation: ignore time skew during initial
replication
During a replica CA installation, the initial replication step may fail
if there is too much time skew between the server and replica.
The replica installer already takes care of this for the replication of
the domain suffix but the replica CA installer does not set
nssldapd-ignore-time-skew to on for o=ipaca suffix.
During a replica CA installation, read the initial value of
nssldapd-ignore-time-skew, force it to on, start replication and
revert to the initial value.
Apply the same logic to dsinstance and ipa-replica-manage force-sync.
Fixes: https://pagure.io/freeipa/issue/9635
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
install/share/Makefile.am | 1 -
install/share/replica-prevent-time-skew.ldif | 4 ----
install/tools/ipa-replica-manage.in | 4 ++--
ipaserver/install/cainstance.py | 4 ++++
ipaserver/install/dsinstance.py | 14 ++---------
ipaserver/install/service.py | 25 ++++++++++++++++++++
6 files changed, 33 insertions(+), 19 deletions(-)
delete mode 100644 install/share/replica-prevent-time-skew.ldif
diff --git a/install/share/Makefile.am b/install/share/Makefile.am
index e0fe4b7d1756bd05f060a92ab52f910b4bd3adc8..4029297b76cc2f30dc9eab606e5670667978dd27 100644
--- a/install/share/Makefile.am
+++ b/install/share/Makefile.am
@@ -38,7 +38,6 @@ dist_app_DATA = \
default-trust-view.ldif \
delegation.ldif \
replica-acis.ldif \
- replica-prevent-time-skew.ldif \
ds-nfiles.ldif \
ds-ipa-env.conf.template \
dns.ldif \
diff --git a/install/share/replica-prevent-time-skew.ldif b/install/share/replica-prevent-time-skew.ldif
deleted file mode 100644
index 5d301feddb56347f3b35be89edaae1a7d91e07de..0000000000000000000000000000000000000000
--- a/install/share/replica-prevent-time-skew.ldif
+++ /dev/null
@@ -1,4 +0,0 @@
-dn: cn=config
-changetype: modify
-replace: nsslapd-ignore-time-skew
-nsslapd-ignore-time-skew: $SKEWVALUE
diff --git a/install/tools/ipa-replica-manage.in b/install/tools/ipa-replica-manage.in
index 56145cb8a2249f8c5279d9baec4f34f274990bcf..d6e6ef57c39af70f164d41662227af3dc2535f9c 100644
--- a/install/tools/ipa-replica-manage.in
+++ b/install/tools/ipa-replica-manage.in
@@ -1262,12 +1262,12 @@ def force_sync(realm, thishost, fromhost, dirman_passwd, nolookup=False):
repl.force_sync(repl.conn, fromhost)
else:
ds = dsinstance.DsInstance(realm_name=realm)
- ds.replica_manage_time_skew(prevent=False)
+ ds.replica_ignore_initial_time_skew()
repl = replication.ReplicationManager(realm, fromhost, dirman_passwd)
repl.force_sync(repl.conn, thishost)
agreement = repl.get_replication_agreement(thishost)
repl.wait_for_repl_update(repl.conn, agreement.dn)
- ds.replica_manage_time_skew(prevent=True)
+ ds.replica_revert_time_skew()
def show_DNA_ranges(hostname, master, realm, dirman_passwd, nextrange=False,
nolookup=False):
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index b4b86024899bc6532f1123503cec63be9435f55b..5dac2c0441752e7bb569cde1fc93bc17c3128cdf 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -416,7 +416,11 @@ class CAInstance(DogtagInstance):
if promote:
# Setup Database
self.step("creating certificate server db", self.__create_ds_db)
+ self.step("ignore time skew for initial replication",
+ self.replica_ignore_initial_time_skew)
self.step("setting up initial replication", self.__setup_replication)
+ self.step("revert time skew after initial replication",
+ self.replica_revert_time_skew)
self.step("creating ACIs for admin", self.add_ipaca_aci)
self.step("creating installation admin user", self.setup_admin)
self.step("configuring certificate server instance",
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 88984d0219033717cefd28d6170535b6c859330f..dab58e42661f500e7aca0e8311e93d421567b8c8 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -387,11 +387,11 @@ class DsInstance(service.Service):
# This helps with initial replication or force-sync because
# the receiving side has no valuable changes itself yet.
self.step("ignore time skew for initial replication",
- self.__replica_ignore_initial_time_skew)
+ self.replica_ignore_initial_time_skew)
self.step("setting up initial replication", self.__setup_replica)
self.step("prevent time skew after initial replication",
- self.replica_manage_time_skew)
+ self.replica_revert_time_skew)
self.step("adding sasl mappings to the directory", self.__configure_sasl_mappings)
self.step("updating schema", self.__update_schema)
# See LDIFs for automember configuration during replica install
@@ -997,16 +997,6 @@ class DsInstance(service.Service):
def __add_replication_acis(self):
self._ldap_mod("replica-acis.ldif", self.sub_dict)
- def __replica_ignore_initial_time_skew(self):
- self.replica_manage_time_skew(prevent=False)
-
- def replica_manage_time_skew(self, prevent=True):
- if prevent:
- self.sub_dict['SKEWVALUE'] = 'off'
- else:
- self.sub_dict['SKEWVALUE'] = 'on'
- self._ldap_mod("replica-prevent-time-skew.ldif", self.sub_dict)
-
def __setup_s4u2proxy(self):
def __add_principal(last_cn, principal, self):
diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
index 4c366a184ffdc26aaf7b546af9e4de8b43b7be41..cf0f64ab9794111761adf735bc488269bd1814fc 100644
--- a/ipaserver/install/service.py
+++ b/ipaserver/install/service.py
@@ -862,6 +862,31 @@ class Service:
self.run_getkeytab(self.api.env.ldap_uri, self.keytab, self.principal)
self.set_keytab_owner()
+ def replica_ignore_initial_time_skew(self):
+ """
+ Set nsslapd-ignore-time-skew = on if not already set
+ and store the initial value in order to restore it later.
+
+ The on value allows replica initialization even if there
+ are excessive time skews.
+ """
+ dn = DN(('cn', 'config'))
+ entry_attrs = api.Backend.ldap2.get_entry(dn)
+ self.original_time_skew = entry_attrs['nsslapd-ignore-time-skew'][0]
+ if self.original_time_skew != 'on':
+ entry_attrs['nsslapd-ignore-time-skew'] = 'on'
+ api.Backend.ldap2.update_entry(entry_attrs)
+
+ def replica_revert_time_skew(self):
+ """
+ Revert nsslapd-ignore-time-skew to its previous value.
+ """
+ dn = DN(('cn', 'config'))
+ entry_attrs = api.Backend.ldap2.get_entry(dn)
+ if self.original_time_skew != 'on':
+ entry_attrs['nsslapd-ignore-time-skew'] = self.original_time_skew
+ api.Backend.ldap2.update_entry(entry_attrs)
+
class SimpleServiceInstance(Service):
def create_instance(self, gensvc_name=None, fqdn=None, ldap_suffix=None,
--
2.45.2

View File

@ -1,49 +0,0 @@
From e83d949c7f1734dff70379e360e9bbf626149c61 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Fri, 19 Jul 2024 14:24:15 -0400
Subject: [PATCH] Log errors reported by adtrustinstance.check_inst() using
logger
It previously only printed the issue which made troubleshooting
after the fact difficult. Using logger.error() provides the same
visual functionality but also logs to the server install log.
Fixes: https://pagure.io/freeipa/issue/9637
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipaserver/install/adtrustinstance.py | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py
index 2ff68dfb46371a6118eb67515347eb762a37e1ec..fd5a5a282fa2a222de85c6b29d8d9621b53c95d2 100644
--- a/ipaserver/install/adtrustinstance.py
+++ b/ipaserver/install/adtrustinstance.py
@@ -65,8 +65,8 @@ and re-run ipa-adtrust-instal again afterwards.
def check_inst():
for smbfile in [paths.SMBD, paths.NET]:
if not os.path.exists(smbfile):
- print("%s was not found on this system" % smbfile)
- print("Please install the 'samba' packages and " \
+ logger.error("%s was not found on this system", smbfile)
+ logger.error("Please install the 'samba' packages and "
"start the installation again")
return False
@@ -74,9 +74,10 @@ def check_inst():
# by looking for the file /usr/share/ipa/smb.conf.empty
if not os.path.exists(os.path.join(paths.USR_SHARE_IPA_DIR,
"smb.conf.empty")):
- print("AD Trust requires the '%s' package" %
+ logger.error("AD Trust requires the '%s' package",
constants.IPA_ADTRUST_PACKAGE_NAME)
- print("Please install the package and start the installation again")
+ logger.error(
+ "Please install the package and start the installation again")
return False
#TODO: Add check for needed samba4 libraries
--
2.45.2

View File

@ -1,116 +0,0 @@
From ee96c129a6034d02245a41c58fa3398c12c9ee75 Mon Sep 17 00:00:00 2001
From: Mohammad Rizwan <myusuf@redhat.com>
Date: Thu, 11 Jul 2024 18:14:52 +0530
Subject: [PATCH] ipatests: Verify that SIDgen task continue even if it fails
to assign sid
related: https://pagure.io/freeipa/issue/9618
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipatests/test_integration/test_commands.py | 73 +++++++++++++++++++++-
1 file changed, 71 insertions(+), 2 deletions(-)
diff --git a/ipatests/test_integration/test_commands.py b/ipatests/test_integration/test_commands.py
index f6f1c979a751a300f09358c044fbfb34539d188e..fd34defe5b12f06ed7c16350cb90933ce9bcd72e 100644
--- a/ipatests/test_integration/test_commands.py
+++ b/ipatests/test_integration/test_commands.py
@@ -1267,7 +1267,7 @@ class TestIPACommand(IntegrationTest):
def get_dirsrv_id(self):
serverid = realm_to_serverid(self.master.domain.realm)
- return("dirsrv@%s.service" % serverid)
+ return ("dirsrv@%s.service" % serverid)
def test_ipa_nis_manage_enable(self):
"""
@@ -1769,7 +1769,7 @@ class TestIPACommandWithoutReplica(IntegrationTest):
api.bootstrap_with_global_options(context='server')
api.finalize()
api.Backend.ldap2.connect()
-
+
api.Command["group_add"]("testgroup1", external=True)
api.Command["group_add"]("testgroup2", external=False)
result1 = api.Command["group_show"]("testgroup1", all=True)["result"] # noqa: E501
@@ -1814,6 +1814,75 @@ class TestIPACommandWithoutReplica(IntegrationTest):
'/tmp/reproducer2_code.py'])
assert "missing attribute" not in result.stdout_text
+ def test_sidgen_task_continue_on_error(self):
+ """Verify that SIDgen task continue even if it fails to assign sid
+ scenario:
+ - add a user with no uid (it will be auto-assigned inside
+ the range)
+ - add a user with uid 2000
+ - add a user with no uid (it will be auto-assigned inside
+ the range)
+ - edit the first and 3rd users, remove the objectclass
+ ipaNTUserAttrs and the attribute ipaNTSecurityIdentifier
+ - run the sidgen task
+ - verify that user1 and user3 have a ipaNTSecurityIdentifier
+ - verify that old error message is not seen in dirsrv error log
+ - verify that new error message is seen in dirsrv error log
+
+ related: https://pagure.io/freeipa/issue/9618
+ """
+ test_user1 = 'test_user1'
+ test_user2 = 'test_user2'
+ test_user2000 = 'test_user2000'
+ base_dn = str(self.master.domain.basedn)
+ old_err_msg = 'Cannot add SID to existing entry'
+ new_err_msg = r'Finished with [0-9]+ failures, please check the log'
+
+ tasks.kinit_admin(self.master)
+ tasks.user_add(self.master, test_user1)
+ self.master.run_command(
+ ['ipa', 'user-add', test_user2000,
+ '--first', 'test', '--last', 'user',
+ '--uid', '2000']
+ )
+ tasks.user_add(self.master, test_user2)
+
+ for user in (test_user1, test_user2):
+ entry_ldif = textwrap.dedent("""
+ dn: uid={user},cn=users,cn=accounts,{base_dn}
+ changetype: modify
+ delete: ipaNTSecurityIdentifier
+ -
+ delete: objectclass
+ objectclass: ipaNTUserAttrs
+ """).format(
+ user=user,
+ base_dn=base_dn)
+ tasks.ldapmodify_dm(self.master, entry_ldif)
+
+ # run sidgen task
+ self.master.run_command(
+ ['ipa', 'config-mod', '--add-sids', '--enable-sid']
+ )
+
+ # ensure that sidgen have added the attr removed above
+ for user in (test_user1, test_user2):
+ result = tasks.ldapsearch_dm(
+ self.master,
+ 'uid={user},cn=users,cn=accounts,{base_dn}'.format(
+ user=user, base_dn=base_dn),
+ ['ipaNTSecurityIdentifier']
+ )
+ assert 'ipaNTSecurityIdentifier' in result.stdout_text
+
+ dashed_domain = self.master.domain.realm.replace(".", '-')
+ dirsrv_error_log = self.master.get_file_contents(
+ paths.SLAPD_INSTANCE_ERROR_LOG_TEMPLATE % (dashed_domain),
+ encoding='utf-8'
+ )
+ assert old_err_msg not in dirsrv_error_log
+ assert re.search(new_err_msg, dirsrv_error_log)
+
class TestIPAautomount(IntegrationTest):
@classmethod
--
2.45.2

View File

@ -1,76 +0,0 @@
From 8046023fc46c628c099d84b026ab866f7c6e16d6 Mon Sep 17 00:00:00 2001
From: Sudhir Menon <sumenon@redhat.com>
Date: Thu, 25 Jul 2024 18:32:21 +0530
Subject: [PATCH] ipatests: ipa-migrate tool with -Z option (CACERTFILE)
This patch add tests to check the scenarios associated with
pagure tickets
https://pagure.io/freeipa/issue/9642 - ipa-migrate - properly handle invalid certificates
https://pagure.io/freeipa/issue/9619 - ipa-migrate starttls does not work
Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
.../test_ipa_ipa_migration.py | 48 +++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/ipatests/test_integration/test_ipa_ipa_migration.py b/ipatests/test_integration/test_ipa_ipa_migration.py
index a516941047315e07407b8063a7010526d384ab3b..f697bbfbfc6169309274db689501c99fe148cc70 100644
--- a/ipatests/test_integration/test_ipa_ipa_migration.py
+++ b/ipatests/test_integration/test_ipa_ipa_migration.py
@@ -872,3 +872,51 @@ class TestIPAMigrateScenario1(IntegrationTest):
extra_args=params,
)
assert self.replicas[0].transport.file_exists(custom_log_file)
+
+ def test_ipa_migrate_stage_mode_with_cert(self):
+ """
+ This testcase checks that ipa-migrate command
+ works without the 'ValuerError'
+ when -Z <cert> option is used with valid cert
+ """
+ cert_file = '/tmp/ipa.crt'
+ remote_server_cert = self.master.get_file_contents(
+ paths.IPA_CA_CRT, encoding="utf-8"
+ )
+ self.replicas[0].put_file_contents(cert_file, remote_server_cert)
+ params = ['-x', '-n', '-Z', cert_file]
+ result = run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=params,
+ )
+ assert result.returncode == 0
+
+ def test_ipa_migrate_stage_mode_with_invalid_cert(self):
+ """
+ This test checks ipa-migrate tool throws
+ error when invalid cert is specified with
+ -Z option
+ """
+ cert_file = '/tmp/invaid_cert.crt'
+ invalid_cert = (
+ b'-----BEGIN CERTIFICATE-----\n'
+ b'MIIFazCCDQYJKoZIhvcNAQELBQAw\n'
+ b'-----END CERTIFICATE-----\n'
+ )
+ ERR_MSG = "Failed to connect to remote server: "
+ params = ['-x', '-n', '-Z', cert_file]
+ self.replicas[0].put_file_contents(cert_file, invalid_cert)
+ result = run_migrate(
+ self.replicas[0],
+ "stage-mode",
+ self.master.hostname,
+ "cn=Directory Manager",
+ self.master.config.admin_password,
+ extra_args=params,
+ )
+ assert result.returncode == 1
+ assert ERR_MSG in result.stderr_text
--
2.45.2

View File

@ -211,7 +211,7 @@
# Work-around fact that RPM SPEC parser does not accept
# "Version: @VERSION@" in freeipa.spec.in used for Autoconf string replacement
%define IPA_VERSION 4.12.0
%define IPA_VERSION 4.12.2
# Release candidate version -- uncomment with one percent for RC versions
#%%global rc_version %%nil
%define AT_SIGN @
@ -224,7 +224,7 @@
Name: %{package_name}
Version: %{IPA_VERSION}
Release: 7%{?rc_version:.%rc_version}%{?dist}
Release: 1%{?rc_version:.%rc_version}%{?dist}
Summary: The Identity, Policy and Audit system
License: GPL-3.0-or-later
@ -250,38 +250,6 @@ Patch1002: 1002-Revert-freeipa.spec-depend-on-bind-dnssec-utils.patch
%if 0%{?rhel} == 9
Patch0001: 0001-Revert-Replace-netifaces-with-ifaddr.patch
Patch0002: 0002-Revert-custodia-do-not-use-deprecated-jwcrypto-wrapp.patch
Patch0003: 0003-kdb-fix-vulnerability-in-GCD-rules-handling.patch
Patch0004: 0004-kdb-apply-combinatorial-logic-for-ticket-flags.patch
Patch0005: 0005-Add-iparepltopoconf-objectclass-to-topology-permissi.patch
Patch0006: 0006-ipa-otptoken-import-open-the-key-file-in-binary-mode.patch
Patch0007: 0007-spec-file-do-not-create-etc-ssh-ssh_config.orig-if-u.patch
Patch0008: 0008-ipatests-add-test-for-ticket-9610.patch
Patch0009: 0009-PKINIT-certificate-fix-renewal-on-hidden-replica.patch
Patch0010: 0010-ipatests-add-test-for-PKINIT-renewal-on-hidden-repli.patch
Patch0011: 0011-ipatests-Tests-for-ipa-ipa-migration-tool.patch
Patch0012: 0012-ipa_sidgen-Allow-sidgen_task-to-continue-after-findi.patch
Patch0013: 0013-ipatests-mark-test_ca_show_error_handling-as-xfail.patch
Patch0014: 0014-ipa-migrate-remove-V-option.patch
Patch0015: 0015-Fix-syntax-error-in-the-selinux-luna-postun-script.patch
Patch0016: 0016-Re-organize-HSM-validation-to-be-more-consistent-les.patch
Patch0017: 0017-ipatests-tests-related-to-token-password-file.patch
Patch0018: 0018-Include-token-password-options-in-ipa-kra-install-ma.patch
Patch0019: 0019-ipa-migrate-starttls-does-not-work.patch
Patch0020: 0020-ipa-pwd-extop-differentiate-OTP-requirements-in-LDAP.patch
Patch0021: 0021-ipatests-Test-replica-installation-using-AD-admin.patch
Patch0022: 0022-Issue-9621-ipa-migrate-should-not-update-mapped-attr.patch
Patch0023: 0023-ipatests-remove-xfail-for-test_ipa_migrate_version_o.patch
Patch0024: 0024-ipatests-remove-xfail-for-test_ipa_migrate_stage_mod.patch
Patch0025: 0025-Unconditionally-add-MS-PAC-to-global-config-on-updat.patch
Patch0026: 0026-Remove-RC4-and-3DES-default-encryption-types-on-upda.patch
Patch0027: 0027-Fix-a-copy-paste-issue-when-detecting-the-HSM-SELinu.patch
Patch0028: 0028-ipa-migrate-properly-handle-invalid-certificates.patch
Patch0029: 0029-ipatests-Fix-usage-of-token_password_file.patch
Patch0030: 0030-Run-HSM-validation-as-pkiuser-to-verify-token-permis.patch
Patch0031: 0031-Replica-CA-installation-ignore-time-skew-during-init.patch
Patch0032: 0032-Log-errors-reported-by-adtrustinstance.check_inst-us.patch
Patch0033: 0033-ipatests-Verify-that-SIDgen-task-continue-even-if-it.patch
Patch0034: 0034-ipatests-ipa-migrate-tool-with-Z-option-CACERTFILE.patch
Patch1001: 1001-Change-branding-to-IPA-and-Identity-Management.patch
%endif
%endif
@ -1895,6 +1863,11 @@ fi
%endif
%changelog
* Wed Aug 21 2024 Florence Blanc-Renaud <flo@redhat.com> - 4.12.2-1
- Resolves: RHEL-54546 Covscan issues: Resource Leak
- Resolves: RHEL-49602 misleading warning for missing ipa-selinux-nfast package on luna hsm h/w
- Resolves: RHEL-40359 With unreachable AD, ipa trust returns an internal error
* Thu Aug 8 2024 Florence Blanc-Renaud <flo@redhat.com> - 4.12.0-7
- Resolves: RHEL-53500 adtrustinstance only prints issues in check_inst() and does not log them
- Resolves: RHEL-52306 Unconditionally add MS-PAC to global config

View File

@ -1,2 +1,2 @@
SHA512 (freeipa-4.12.0.tar.gz) = 1e95250a6892e85b4782a1f2451a99d21c90ce82db2be369d9e0e1706575229d4539b20f8dd2b97da0d6f73f4fb59168ab6e05eb2fe185b4bb854f42c1e7fd29
SHA512 (freeipa-4.12.0.tar.gz.asc) = 896170fee005acc3cf46b22053d9f0f0e75f0af31af5c9fbd993674dc26549e479ea3468412ff35f947f7cf42bb7b9bf96f1ead21d754eec92a27b30d731dbe1
SHA512 (freeipa-4.12.2.tar.gz) = 2e1e67dbe73a458db5c59528799649629a1cb462283e4e9a4c56aff46d275782bcb3b0d57de615bbc7020a4350d4d383501e049ac19ed38250896b1e8fd27cb0
SHA512 (freeipa-4.12.2.tar.gz.asc) = 07309bfdafd2ba9b1ced71374df5a84d242a5bf8e806765b4c3374ee2ddea0484f140d615a24b3f73f39a8ac34727d82a066ea399f91654077170519a12e2d27