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:
parent
3979c73861
commit
9b3c30c71b
2
.gitignore
vendored
2
.gitignore
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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, ¬okens)) {
|
||||
+ /* 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
41
freeipa.spec
41
freeipa.spec
@ -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
|
||||
|
4
sources
4
sources
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user