Compare commits

...

No commits in common. "c8-stream-DL1" and "a9" have entirely different histories.

55 changed files with 6948 additions and 6496 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/freeipa-4.9.12.tar.gz
SOURCES/freeipa-4.10.2.tar.gz

View File

@ -1 +1 @@
ea6c8a209748b4ad8d07da556f705a366b3dd6c1 SOURCES/freeipa-4.9.12.tar.gz
17d580b7dccb1586898aa46c7ecdd2bd2754ee5f SOURCES/freeipa-4.10.2.tar.gz

View File

@ -1,261 +0,0 @@
From f42a106e84c1fd609350da2540289ce945a7ecbd Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Thu, 11 May 2023 10:53:58 +0200
Subject: [PATCH] user or group name: explain the supported format
The commands ipa user-add or ipa group-add validate the
format of the user/group name and display the following
message when it does not conform to the expectations:
invalid 'login': may only include letters, numbers, _, -, . and $
The format is more complex, for instance '1234567' is an invalid
user name but the failure is inconsistent with the error message.
Modify the error message to point to ipa help user/group and add
more details in the help message.
Same change for idoverrideuser and idoverridegroup:
The user/group name must follow these rules:
- cannot contain only numbers
- must start with a letter, a number, _ or .
- may contain letters, numbers, _, ., or -
- may end with a letter, a number, _, ., - or $
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2150217
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
Reviewed-By: Alexander Bokovoy <abbra@users.noreply.github.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipalib/constants.py | 5 +++++
ipaserver/plugins/baseuser.py | 2 +-
ipaserver/plugins/group.py | 10 ++++++++--
ipaserver/plugins/idviews.py | 5 +++--
ipaserver/plugins/stageuser.py | 6 ++++++
ipaserver/plugins/user.py | 6 ++++++
ipatests/test_xmlrpc/test_group_plugin.py | 5 +++--
ipatests/test_xmlrpc/test_stageuser_plugin.py | 3 ++-
ipatests/test_xmlrpc/test_user_plugin.py | 7 ++++---
9 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/ipalib/constants.py b/ipalib/constants.py
index 4b759a573..104419bc2 100644
--- a/ipalib/constants.py
+++ b/ipalib/constants.py
@@ -319,6 +319,11 @@ MAXHOSTFQDNLEN = 253
PATTERN_GROUPUSER_NAME = (
'(?!^[0-9]+$)^[a-zA-Z0-9_.][a-zA-Z0-9_.-]*[a-zA-Z0-9_.$-]?$'
)
+ERRMSG_GROUPUSER_NAME = (
+ 'may only include letters, numbers, _, -, . and $'
+ ', refer to \'ipa help {}\' for complete format '
+ 'description'
+)
# Kerberos Anonymous principal name
ANON_USER = 'WELLKNOWN/ANONYMOUS'
diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py
index 684a65242..bae6c54ff 100644
--- a/ipaserver/plugins/baseuser.py
+++ b/ipaserver/plugins/baseuser.py
@@ -211,7 +211,7 @@ class baseuser(LDAPObject):
takes_params = (
Str('uid',
pattern=constants.PATTERN_GROUPUSER_NAME,
- pattern_errmsg='may only include letters, numbers, _, -, . and $',
+ pattern_errmsg=constants.ERRMSG_GROUPUSER_NAME.format('user'),
maxlength=255,
cli_name='login',
label=_('User login'),
diff --git a/ipaserver/plugins/group.py b/ipaserver/plugins/group.py
index afdad93c1..0333ed622 100644
--- a/ipaserver/plugins/group.py
+++ b/ipaserver/plugins/group.py
@@ -24,7 +24,7 @@ import logging
from ipalib import api
from ipalib import Int, Str, Flag
-from ipalib.constants import PATTERN_GROUPUSER_NAME
+from ipalib.constants import PATTERN_GROUPUSER_NAME, ERRMSG_GROUPUSER_NAME
from ipalib.plugable import Registry
from .baseldap import (
add_external_post_callback,
@@ -70,6 +70,12 @@ converted to non-POSIX groups.
Every group must have a description.
+The group name must follow these rules:
+- cannot contain only numbers
+- must start with a letter, a number, _ or .
+- may contain letters, numbers, _, ., or -
+- may end with a letter, a number, _, ., - or $
+
POSIX groups must have a Group ID (GID) number. Changing a GID is
supported but can have an impact on your file permissions. It is not necessary
to supply a GID when creating a group. IPA will generate one automatically
@@ -330,7 +336,7 @@ class group(LDAPObject):
takes_params = (
Str('cn',
pattern=PATTERN_GROUPUSER_NAME,
- pattern_errmsg='may only include letters, numbers, _, -, . and $',
+ pattern_errmsg=ERRMSG_GROUPUSER_NAME.format('group'),
maxlength=255,
cli_name='group_name',
label=_('Group name'),
diff --git a/ipaserver/plugins/idviews.py b/ipaserver/plugins/idviews.py
index 4f4b3a2f7..6a16884cf 100644
--- a/ipaserver/plugins/idviews.py
+++ b/ipaserver/plugins/idviews.py
@@ -37,6 +37,7 @@ from ipalib.constants import (
IPA_ANCHOR_PREFIX,
SID_ANCHOR_PREFIX,
PATTERN_GROUPUSER_NAME,
+ ERRMSG_GROUPUSER_NAME
)
from ipalib.plugable import Registry
from ipalib.util import (normalize_sshpubkey, validate_sshpubkey,
@@ -1025,7 +1026,7 @@ class idoverrideuser(baseidoverride):
takes_params = baseidoverride.takes_params + (
Str('uid?',
pattern=PATTERN_GROUPUSER_NAME,
- pattern_errmsg='may only include letters, numbers, _, -, . and $',
+ pattern_errmsg=ERRMSG_GROUPUSER_NAME.format('user'),
maxlength=255,
cli_name='login',
label=_('User login'),
@@ -1128,7 +1129,7 @@ class idoverridegroup(baseidoverride):
takes_params = baseidoverride.takes_params + (
Str('cn?',
pattern=PATTERN_GROUPUSER_NAME,
- pattern_errmsg='may only include letters, numbers, _, -, . and $',
+ pattern_errmsg=ERRMSG_GROUPUSER_NAME.format('group'),
maxlength=255,
cli_name='group_name',
label=_('Group name'),
diff --git a/ipaserver/plugins/stageuser.py b/ipaserver/plugins/stageuser.py
index 760dff7ab..51438a83a 100644
--- a/ipaserver/plugins/stageuser.py
+++ b/ipaserver/plugins/stageuser.py
@@ -94,6 +94,12 @@ usernames that start with a digit or usernames that exceed a certain length
may cause problems for some UNIX systems.
Use 'ipa config-mod' to change the username format allowed by IPA tools.
+The user name must follow these rules:
+- cannot contain only numbers
+- must start with a letter, a number, _ or .
+- may contain letters, numbers, _, ., or -
+- may end with a letter, a number, _, ., - or $
+
EXAMPLES:
diff --git a/ipaserver/plugins/user.py b/ipaserver/plugins/user.py
index fa8a67d3d..643b44f14 100644
--- a/ipaserver/plugins/user.py
+++ b/ipaserver/plugins/user.py
@@ -88,6 +88,12 @@ usernames that start with a digit or usernames that exceed a certain length
may cause problems for some UNIX systems.
Use 'ipa config-mod' to change the username format allowed by IPA tools.
+The user name must follow these rules:
+- cannot contain only numbers
+- must start with a letter, a number, _ or .
+- may contain letters, numbers, _, ., or -
+- may end with a letter, a number, _, ., - or $
+
Disabling a user account prevents that user from obtaining new Kerberos
credentials. It does not invalidate any credentials that have already
been issued.
diff --git a/ipatests/test_xmlrpc/test_group_plugin.py b/ipatests/test_xmlrpc/test_group_plugin.py
index f9a0e2cfe..27bc21fbc 100644
--- a/ipatests/test_xmlrpc/test_group_plugin.py
+++ b/ipatests/test_xmlrpc/test_group_plugin.py
@@ -25,6 +25,7 @@ Test the `ipaserver/plugins/group.py` module.
import pytest
from ipalib import errors
+from ipalib.constants import ERRMSG_GROUPUSER_NAME
from ipatests.test_xmlrpc import objectclasses
from ipatests.test_xmlrpc.xmlrpc_test import (
fuzzy_digits, fuzzy_uuid, fuzzy_set_ci,
@@ -169,7 +170,7 @@ class TestGroup(XMLRPC_test):
)
with raises_exact(errors.ValidationError(
name='group_name',
- error=u'may only include letters, numbers, _, -, . and $')):
+ error=ERRMSG_GROUPUSER_NAME.format('group'))):
command()
def test_create_with_name_starting_with_numeric(self):
@@ -188,7 +189,7 @@ class TestGroup(XMLRPC_test):
)
with raises_exact(errors.ValidationError(
name='group_name',
- error=u'may only include letters, numbers, _, -, . and $',
+ error=ERRMSG_GROUPUSER_NAME.format('group'),
)):
testgroup.create()
diff --git a/ipatests/test_xmlrpc/test_stageuser_plugin.py b/ipatests/test_xmlrpc/test_stageuser_plugin.py
index fd146876c..bd877aa94 100644
--- a/ipatests/test_xmlrpc/test_stageuser_plugin.py
+++ b/ipatests/test_xmlrpc/test_stageuser_plugin.py
@@ -12,6 +12,7 @@ import six
from collections import OrderedDict
from ipalib import api, errors
+from ipalib.constants import ERRMSG_GROUPUSER_NAME
from ipaplatform.constants import constants as platformconstants
from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test, raises_exact
@@ -357,7 +358,7 @@ class TestCreateInvalidAttributes(XMLRPC_test):
command = invalid.make_create_command()
with raises_exact(errors.ValidationError(
name='login',
- error=u"may only include letters, numbers, _, -, . and $")):
+ error=ERRMSG_GROUPUSER_NAME.format('user'))):
command()
def test_create_long_uid(self):
diff --git a/ipatests/test_xmlrpc/test_user_plugin.py b/ipatests/test_xmlrpc/test_user_plugin.py
index c156a8793..eadfe6a65 100644
--- a/ipatests/test_xmlrpc/test_user_plugin.py
+++ b/ipatests/test_xmlrpc/test_user_plugin.py
@@ -31,6 +31,7 @@ import ldap
import re
from ipalib import api, errors
+from ipalib.constants import ERRMSG_GROUPUSER_NAME
from ipaplatform.constants import constants as platformconstants
from ipapython import ipautil
from ipatests.test_xmlrpc import objectclasses
@@ -502,7 +503,7 @@ class TestUpdate(XMLRPC_test):
)
with raises_exact(errors.ValidationError(
name='rename',
- error=u'may only include letters, numbers, _, -, . and $')):
+ error=ERRMSG_GROUPUSER_NAME.format('user'))):
command()
def test_add_radius_username(self, user):
@@ -556,7 +557,7 @@ class TestCreate(XMLRPC_test):
command = testuser.make_create_command()
with raises_exact(errors.ValidationError(
name=u'login',
- error=u'may only include letters, numbers, _, -, . and $')):
+ error=ERRMSG_GROUPUSER_NAME.format('user'))):
command()
def test_create_with_too_long_login(self):
@@ -730,7 +731,7 @@ class TestCreate(XMLRPC_test):
)
with raises_exact(errors.ValidationError(
name=u'login',
- error=u'may only include letters, numbers, _, -, . and $',
+ error=ERRMSG_GROUPUSER_NAME.format('user'),
)):
testuser.create()
--
2.40.1

View File

@ -0,0 +1,35 @@
From 4f6ebb5fdf6d2514d4683247e5d1bfc6022a500e Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Tue, 6 Jun 2023 09:04:48 +0200
Subject: [PATCH] webuitests: close notification which hides Add button
The webui test test_service.py::test_service::test_arbitrary_certificates
randomly fails.
The test is creating a new service then navigates to the Service page
and clicks on the Add Certificate button.
The notification area may still be present and hide the button, with
the message "Service successfully added".
Close all notifications before navigating to the Service page.
Fixes: https://pagure.io/freeipa/issue/9389
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
---
ipatests/test_webui/test_service.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/ipatests/test_webui/test_service.py b/ipatests/test_webui/test_service.py
index f1d9a9d624bc587634e03a86050627a648feb26d..e2976d73acd1f574f1164828be9d8e871b737d7f 100644
--- a/ipatests/test_webui/test_service.py
+++ b/ipatests/test_webui/test_service.py
@@ -296,6 +296,7 @@ class test_service(sevice_tasks):
cert_widget_sel = "div.certificate-widget"
self.add_record(ENTITY, data)
+ self.close_notifications()
self.navigate_to_record(pkey)
# check whether certificate section is present
--
2.41.0

View File

@ -1,242 +0,0 @@
From 9fe30f21c987bdccf80ef5f6d645fdc59b393bdb Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Jun 16 2023 19:09:52 +0000
Subject: Revert "Use the OpenSSL certificate parser in cert-find"
This reverts commit 191880bc9f77c3e8a3cecc82e6eea33ab5ad03e4.
The problem isn't with python-cryptography, it is with the
IPACertificate class which does way more work on a certificate
than is necessary in cert-find.
Related: https://pagure.io/freeipa/issue/9331
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
diff --git a/freeipa.spec.in b/freeipa.spec.in
index f3380b4..2b18963 100755
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -390,7 +390,6 @@ BuildRequires: python3-pylint
BuildRequires: python3-pytest-multihost
BuildRequires: python3-pytest-sourceorder
BuildRequires: python3-qrcode-core >= 5.0.0
-BuildRequires: python3-pyOpenSSL
BuildRequires: python3-samba
BuildRequires: python3-six
BuildRequires: python3-sss
@@ -862,7 +861,6 @@ Requires: python3-netifaces >= 0.10.4
Requires: python3-pyasn1 >= 0.3.2-2
Requires: python3-pyasn1-modules >= 0.3.2-2
Requires: python3-pyusb
-Requires: python3-pyOpenSSL
Requires: python3-qrcode-core >= 5.0.0
Requires: python3-requests
Requires: python3-six
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
index cec3d93..88c6b62 100644
--- a/ipaserver/plugins/cert.py
+++ b/ipaserver/plugins/cert.py
@@ -30,7 +30,6 @@ import cryptography.x509
from cryptography.hazmat.primitives import hashes, serialization
from dns import resolver, reversename
import six
-import sys
from ipalib import Command, Str, Int, Flag, StrEnum
from ipalib import api
@@ -1623,19 +1622,7 @@ class cert_find(Search, CertMethod):
)
def _get_cert_key(self, cert):
- # for cert-find with a certificate value
- if isinstance(cert, x509.IPACertificate):
- return (DN(cert.issuer), cert.serial_number)
-
- issuer = []
- for oid, value in cert.get_issuer().get_components():
- issuer.append(
- '{}={}'.format(oid.decode('utf-8'), value.decode('utf-8'))
- )
- issuer = ','.join(issuer)
- # Use this to flip from OpenSSL reverse to X500 ordering
- issuer = DN(issuer).x500_text()
- return (DN(issuer), cert.get_serial_number())
+ return (DN(cert.issuer), cert.serial_number)
def _cert_search(self, pkey_only, **options):
result = collections.OrderedDict()
@@ -1755,11 +1742,6 @@ class cert_find(Search, CertMethod):
return result, False, complete
def _ldap_search(self, all, pkey_only, no_members, **options):
- # defer import of the OpenSSL module to not affect the requests
- # module which will use pyopenssl if this is available.
- if sys.modules.get('OpenSSL.SSL', False) is None:
- del sys.modules["OpenSSL.SSL"]
- import OpenSSL.crypto
ldap = self.api.Backend.ldap2
filters = []
@@ -1818,14 +1800,12 @@ class cert_find(Search, CertMethod):
ca_enabled = getattr(context, 'ca_enabled')
for entry in entries:
for attr in ('usercertificate', 'usercertificate;binary'):
- for der in entry.raw.get(attr, []):
- cert = OpenSSL.crypto.load_certificate(
- OpenSSL.crypto.FILETYPE_ASN1, der)
+ for cert in entry.get(attr, []):
cert_key = self._get_cert_key(cert)
try:
obj = result[cert_key]
except KeyError:
- obj = {'serial_number': cert.get_serial_number()}
+ obj = {'serial_number': cert.serial_number}
if not pkey_only and (all or not ca_enabled):
# Retrieving certificate details is now deferred
# until after all certificates are collected.
From 3b1dbcdba2994bf57908f530913998e9ab888e4c Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Jun 16 2023 19:09:52 +0000
Subject: Revert "cert_find: fix call with --all"
This reverts commit 1f30cc65276a532e7288217f216b72a2b0628c8f.
The problem isn't with python-cryptography, it is with the
IPACertificate class which does way more work on a certificate
than is necessary in cert-find.
Related: https://pagure.io/freeipa/issue/9331
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
index 88c6b62..ba37525 100644
--- a/ipaserver/plugins/cert.py
+++ b/ipaserver/plugins/cert.py
@@ -1812,7 +1812,6 @@ class cert_find(Search, CertMethod):
# For the case of CA-less we need to keep
# the certificate because getting it again later
# would require unnecessary LDAP searches.
- cert = cert.to_cryptography()
obj['certificate'] = (
base64.b64encode(
cert.public_bytes(x509.Encoding.DER))
From d00fd3398c32beb2c3e72f4878c87f9d2c0e833d Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Jun 16 2023 19:09:52 +0000
Subject: Use the python-cryptography parser directly in cert-find
cert-find is a rather complex beast because it not only
looks for certificates in the optional CA but within the
IPA LDAP database as well. It has a process to deduplicate
the certificates since any PKI issued certificates will
also be associated with an IPA record.
In order to obtain the data to deduplicate the certificates
the cert from LDAP must be parser for issuer and serial number.
ipaldap has automation to determine the datatype of an
attribute and will use the ipalib.x509 IPACertificate class to
decode a certificate automatically if you access
entry['usercertificate'].
The downside is that this is comparatively slow. Here is the
parse time in microseconds:
cryptography 0.0081
OpenSSL.crypto 0.2271
ipalib.x509 2.6814
Since only issuer and subject are required there is no need to
make the expensive IPACertificate call.
The IPACertificate parsing time is fine if you're parsing one
certificate but if the LDAP search returns a lot of certificates,
say in the thousands, then those microseconds add up quickly.
In testing it took ~17 seconds to parse 5k certificates (excluding
transmission overhead, etc).
cert-find when there are a lot of certificates has been
historically slow. It isn't related to the CA which returns
large sets (well, 5k anyway) in a second or two. It was the
LDAP comparision adding tens of seconds to the runtime.
When searching with the default sizelimit of 100 the time is
~10s without this patch. With it the time is 1.5s.
CLI times from before and after searching for all certs:
original:
-------------------------------
Number of entries returned 5038
-------------------------------
real 0m15.507s
user 0m0.828s
sys 0m0.241s
using cryptography:
real 0m4.037s
user 0m0.816s
sys 0m0.193s
Fixes: https://pagure.io/freeipa/issue/9331
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
index ba37525..619be83 100644
--- a/ipaserver/plugins/cert.py
+++ b/ipaserver/plugins/cert.py
@@ -1800,7 +1800,8 @@ class cert_find(Search, CertMethod):
ca_enabled = getattr(context, 'ca_enabled')
for entry in entries:
for attr in ('usercertificate', 'usercertificate;binary'):
- for cert in entry.get(attr, []):
+ for der in entry.raw.get(attr, []):
+ cert = cryptography.x509.load_der_x509_certificate(der)
cert_key = self._get_cert_key(cert)
try:
obj = result[cert_key]
diff --git a/ipatests/test_xmlrpc/test_cert_plugin.py b/ipatests/test_xmlrpc/test_cert_plugin.py
index 433cebc..583c67f 100644
--- a/ipatests/test_xmlrpc/test_cert_plugin.py
+++ b/ipatests/test_xmlrpc/test_cert_plugin.py
@@ -254,6 +254,16 @@ class test_cert(BaseCert):
result = _emails_are_valid(email_addrs, [])
assert not result
+ def test_00012_cert_find_all(self):
+ """
+ Test that cert-find --all returns successfully.
+
+ We don't know how many we'll get but there should be at least 10
+ by default.
+ """
+ res = api.Command['cert_find'](all=True)
+ assert 'count' in res and res['count'] >= 10
+
def test_99999_cleanup(self):
"""
Clean up cert test data
@@ -283,7 +293,7 @@ class test_cert_find(XMLRPC_test):
short = api.env.host.split('.', maxsplit=1)[0]
- def test_0001_find_all(self):
+ def test_0001_find_all_certs(self):
"""
Search for all certificates.

View File

@ -0,0 +1,48 @@
From 8d34f453fb139c4cef055a4963f307a760316a73 Mon Sep 17 00:00:00 2001
From: Anuja More <amore@redhat.com>
Date: Thu, 11 May 2023 12:50:10 +0530
Subject: [PATCH] ipatests: Check that SSSD_PUBCONF_KRB5_INCLUDE_D_DIR is not
included in krb5.conf
SSSD already provides a config snippet which includes
SSSD_PUBCONF_KRB5_INCLUDE_D_DIR, and having both breaks Java.
Test checks that krb5.conf does not include
SSSD_PUBCONF_KRB5_INCLUDE_D_DIR.
Related: https://pagure.io/freeipa/issue/9267
Signed-off-by: Anuja More <amore@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
.../test_integration/test_installation_client.py | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/ipatests/test_integration/test_installation_client.py b/ipatests/test_integration/test_installation_client.py
index 014b0f6ab34dd92c00c0187c2c86b8bfbaa70e81..56e1593bfcfa3eb7f9918fc6f2993d836884ea38 100644
--- a/ipatests/test_integration/test_installation_client.py
+++ b/ipatests/test_integration/test_installation_client.py
@@ -76,6 +76,21 @@ class TestInstallClient(IntegrationTest):
result = self.clients[0].run_command(['cat', '/etc/ssh/ssh_config'])
assert 'HostKeyAlgorithms' not in result.stdout_text
+ def test_client_install_with_krb5(self):
+ """Test that SSSD_PUBCONF_KRB5_INCLUDE_D_DIR is not added in krb5.conf
+
+ SSSD already provides a config snippet which includes
+ SSSD_PUBCONF_KRB5_INCLUDE_D_DIR, and having both breaks Java.
+ Test checks that krb5.conf does not include
+ SSSD_PUBCONF_KRB5_INCLUDE_D_DIR.
+
+ related: https://pagure.io/freeipa/issue/9267
+ """
+ krb5_cfg = self.master.get_file_contents(paths.KRB5_CONF)
+ assert 'includedir {dir}'.format(
+ dir=paths.SSSD_PUBCONF_KRB5_INCLUDE_D_DIR
+ ).encode() not in krb5_cfg
+
class TestClientInstallBind(IntegrationTest):
"""
--
2.41.0

View File

@ -0,0 +1,103 @@
From 276138087158c6b2ea76b43c754084144e543c0b Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Wed, 7 Jun 2023 11:32:21 -0400
Subject: [PATCH] Revert "Use the OpenSSL certificate parser in cert-find"
This reverts commit 191880bc9f77c3e8a3cecc82e6eea33ab5ad03e4.
The problem isn't with python-cryptography, it is with the
IPACertificate class which does way more work on a certificate
than is necessary in cert-find.
Related: https://pagure.io/freeipa/issue/9331
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
freeipa.spec.in | 2 --
ipaserver/plugins/cert.py | 26 +++-----------------------
2 files changed, 3 insertions(+), 25 deletions(-)
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 3e23bbfe9d054a3a9febf468de0bcb4a6e81bb32..bec9780a82fe0d9bc5a50a93bdce8aa7e27a9f30 100755
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -412,7 +412,6 @@ BuildRequires: python3-pylint
BuildRequires: python3-pytest-multihost
BuildRequires: python3-pytest-sourceorder
BuildRequires: python3-qrcode-core >= 5.0.0
-BuildRequires: python3-pyOpenSSL
BuildRequires: python3-samba
BuildRequires: python3-six
BuildRequires: python3-sss
@@ -884,7 +883,6 @@ Requires: python3-netifaces >= 0.10.4
Requires: python3-pyasn1 >= 0.3.2-2
Requires: python3-pyasn1-modules >= 0.3.2-2
Requires: python3-pyusb
-Requires: python3-pyOpenSSL
Requires: python3-qrcode-core >= 5.0.0
Requires: python3-requests
Requires: python3-six
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
index 400b1b3cec0aba82e699a4a981516e121f3e0c77..2e32f4ecd50ac92c28bcaffcebe9c2c87557858a 100644
--- a/ipaserver/plugins/cert.py
+++ b/ipaserver/plugins/cert.py
@@ -30,7 +30,6 @@ import cryptography.x509
from cryptography.hazmat.primitives import hashes, serialization
from dns import resolver, reversename
import six
-import sys
from ipalib import Command, Str, Int, Flag, StrEnum, SerialNumber
from ipalib import api
@@ -1618,19 +1617,7 @@ class cert_find(Search, CertMethod):
)
def _get_cert_key(self, cert):
- # for cert-find with a certificate value
- if isinstance(cert, x509.IPACertificate):
- return (DN(cert.issuer), cert.serial_number)
-
- issuer = []
- for oid, value in cert.get_issuer().get_components():
- issuer.append(
- '{}={}'.format(oid.decode('utf-8'), value.decode('utf-8'))
- )
- issuer = ','.join(issuer)
- # Use this to flip from OpenSSL reverse to X500 ordering
- issuer = DN(issuer).x500_text()
- return (DN(issuer), cert.get_serial_number())
+ return (DN(cert.issuer), cert.serial_number)
def _cert_search(self, pkey_only, **options):
result = collections.OrderedDict()
@@ -1750,11 +1737,6 @@ class cert_find(Search, CertMethod):
return result, False, complete
def _ldap_search(self, all, pkey_only, no_members, **options):
- # defer import of the OpenSSL module to not affect the requests
- # module which will use pyopenssl if this is available.
- if sys.modules.get('OpenSSL.SSL', False) is None:
- del sys.modules["OpenSSL.SSL"]
- import OpenSSL.crypto
ldap = self.api.Backend.ldap2
filters = []
@@ -1813,14 +1795,12 @@ class cert_find(Search, CertMethod):
ca_enabled = getattr(context, 'ca_enabled')
for entry in entries:
for attr in ('usercertificate', 'usercertificate;binary'):
- for der in entry.raw.get(attr, []):
- cert = OpenSSL.crypto.load_certificate(
- OpenSSL.crypto.FILETYPE_ASN1, der)
+ for cert in entry.get(attr, []):
cert_key = self._get_cert_key(cert)
try:
obj = result[cert_key]
except KeyError:
- obj = {'serial_number': cert.get_serial_number()}
+ obj = {'serial_number': cert.serial_number}
if not pkey_only and (all or not ca_enabled):
# Retrieving certificate details is now deferred
# until after all certificates are collected.
--
2.41.0

View File

@ -0,0 +1,32 @@
From d83a4b0babdc7beb124d3748b5815ce309739eb7 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Tue, 13 Jun 2023 17:01:49 -0400
Subject: [PATCH] Revert "cert_find: fix call with --all"
This reverts commit 1f30cc65276a532e7288217f216b72a2b0628c8f.
The problem isn't with python-cryptography, it is with the
IPACertificate class which does way more work on a certificate
than is necessary in cert-find.
Related: https://pagure.io/freeipa/issue/9331
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
ipaserver/plugins/cert.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
index 2e32f4ecd50ac92c28bcaffcebe9c2c87557858a..36a0e8cb31b4dbdd9bff09165d1d8aa203936d37 100644
--- a/ipaserver/plugins/cert.py
+++ b/ipaserver/plugins/cert.py
@@ -1807,7 +1807,6 @@ class cert_find(Search, CertMethod):
# For the case of CA-less we need to keep
# the certificate because getting it again later
# would require unnecessary LDAP searches.
- cert = cert.to_cryptography()
obj['certificate'] = (
base64.b64encode(
cert.public_bytes(x509.Encoding.DER))
--
2.41.0

View File

@ -0,0 +1,115 @@
From d9aa75459d650e5282a160a3eef09ed175dc5b51 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Wed, 7 Jun 2023 11:44:05 -0400
Subject: [PATCH] Use the python-cryptography parser directly in cert-find
cert-find is a rather complex beast because it not only
looks for certificates in the optional CA but within the
IPA LDAP database as well. It has a process to deduplicate
the certificates since any PKI issued certificates will
also be associated with an IPA record.
In order to obtain the data to deduplicate the certificates
the cert from LDAP must be parser for issuer and serial number.
ipaldap has automation to determine the datatype of an
attribute and will use the ipalib.x509 IPACertificate class to
decode a certificate automatically if you access
entry['usercertificate'].
The downside is that this is comparatively slow. Here is the
parse time in microseconds:
cryptography 0.0081
OpenSSL.crypto 0.2271
ipalib.x509 2.6814
Since only issuer and subject are required there is no need to
make the expensive IPACertificate call.
The IPACertificate parsing time is fine if you're parsing one
certificate but if the LDAP search returns a lot of certificates,
say in the thousands, then those microseconds add up quickly.
In testing it took ~17 seconds to parse 5k certificates (excluding
transmission overhead, etc).
cert-find when there are a lot of certificates has been
historically slow. It isn't related to the CA which returns
large sets (well, 5k anyway) in a second or two. It was the
LDAP comparision adding tens of seconds to the runtime.
When searching with the default sizelimit of 100 the time is
~10s without this patch. With it the time is 1.5s.
CLI times from before and after searching for all certs:
original:
-------------------------------
Number of entries returned 5038
-------------------------------
real 0m15.507s
user 0m0.828s
sys 0m0.241s
using cryptography:
real 0m4.037s
user 0m0.816s
sys 0m0.193s
Fixes: https://pagure.io/freeipa/issue/9331
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
ipaserver/plugins/cert.py | 3 ++-
ipatests/test_xmlrpc/test_cert_plugin.py | 12 +++++++++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
index 36a0e8cb31b4dbdd9bff09165d1d8aa203936d37..4fb85069a835d94969c9d05789714345ecc60e2e 100644
--- a/ipaserver/plugins/cert.py
+++ b/ipaserver/plugins/cert.py
@@ -1795,7 +1795,8 @@ class cert_find(Search, CertMethod):
ca_enabled = getattr(context, 'ca_enabled')
for entry in entries:
for attr in ('usercertificate', 'usercertificate;binary'):
- for cert in entry.get(attr, []):
+ for der in entry.raw.get(attr, []):
+ cert = cryptography.x509.load_der_x509_certificate(der)
cert_key = self._get_cert_key(cert)
try:
obj = result[cert_key]
diff --git a/ipatests/test_xmlrpc/test_cert_plugin.py b/ipatests/test_xmlrpc/test_cert_plugin.py
index 433cebcd79f792e5c97307c6d599e50855ff4151..583c67fd942a61f42e578cc51a0e456cacf9a5e5 100644
--- a/ipatests/test_xmlrpc/test_cert_plugin.py
+++ b/ipatests/test_xmlrpc/test_cert_plugin.py
@@ -254,6 +254,16 @@ class test_cert(BaseCert):
result = _emails_are_valid(email_addrs, [])
assert not result
+ def test_00012_cert_find_all(self):
+ """
+ Test that cert-find --all returns successfully.
+
+ We don't know how many we'll get but there should be at least 10
+ by default.
+ """
+ res = api.Command['cert_find'](all=True)
+ assert 'count' in res and res['count'] >= 10
+
def test_99999_cleanup(self):
"""
Clean up cert test data
@@ -283,7 +293,7 @@ class test_cert_find(XMLRPC_test):
short = api.env.host.split('.', maxsplit=1)[0]
- def test_0001_find_all(self):
+ def test_0001_find_all_certs(self):
"""
Search for all certificates.
--
2.41.0

View File

@ -1,173 +0,0 @@
From 7a94acca6a9efb546f1cf59f63fcb89f98944ea5 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Thu, 25 May 2023 08:16:33 +0200
Subject: [PATCH] ACME tests: fix issue_and_expire_acme_cert method
The fixture issue_and_expire_acme_cert is changing the date
on master and client. It also resets the admin password as
it gets expired after the date change.
Currently the code is resetting the password by performing
kinit on the client, which leaves the master with an expired
ticket in its cache. Reset the password on the master instead
in order to have a valid ticket for the next operations.
Fixes: https://pagure.io/freeipa/issue/9383
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Mohammad Rizwan <myusuf@redhat.com>
---
ipatests/test_integration/test_acme.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py
index c73f441fc..c69e810da 100644
--- a/ipatests/test_integration/test_acme.py
+++ b/ipatests/test_integration/test_acme.py
@@ -583,20 +583,20 @@ class TestACMERenew(IntegrationTest):
tasks.kdestroy_all(host)
tasks.move_date(host, 'stop', '+90days')
- tasks.get_kdcinfo(host)
+ tasks.get_kdcinfo(self.master)
# Note raiseonerr=False:
# the assert is located after kdcinfo retrieval.
# run kinit command repeatedly until sssd gets settle
# after date change
tasks.run_repeatedly(
- host, "KRB5_TRACE=/dev/stdout kinit admin",
+ self.master, "KRB5_TRACE=/dev/stdout kinit admin",
stdin_text='{0}\n{0}\n{0}\n'.format(
- self.clients[0].config.admin_password
+ self.master.config.admin_password
)
)
# Retrieve kdc.$REALM after the password change, just in case SSSD
# domain status flipped to online during the password change.
- tasks.get_kdcinfo(host)
+ tasks.get_kdcinfo(self.master)
yield
--
2.41.0
From 998bafee86a870ad1ea4d6bccf12f0fae64c398c Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 31 May 2023 11:50:14 +0200
Subject: [PATCH] ipatest: remove xfail from test_smb
test_smb is now successful because the windows server version
has been updated to windows-server-2022 with
- KB5012170
- KB5025230
- KB5022507
- servicing stack 10.0.20348.1663
in freeipa-pr-ci commit 3ba4151.
Remove the xfail.
Fixes: https://pagure.io/freeipa/issue/9124
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Mohammad Rizwan <myusuf@redhat.com>
---
ipatests/test_integration/test_smb.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/ipatests/test_integration/test_smb.py b/ipatests/test_integration/test_smb.py
index 30f8d5901..eb3981bdd 100644
--- a/ipatests/test_integration/test_smb.py
+++ b/ipatests/test_integration/test_smb.py
@@ -349,7 +349,6 @@ class TestSMB(IntegrationTest):
@pytest.mark.skipif(
osinfo.id == 'fedora' and osinfo.version_number <= (31,),
reason='Test requires krb 1.18')
- @pytest.mark.xfail(reason="Pagure ticket 9124", strict=True)
def test_smb_service_s4u2self(self):
"""Test S4U2Self operation by IPA service
against both AD and IPA users
--
2.41.0
From 1b51fa4cb07380d1102891233e85a7940f804c72 Mon Sep 17 00:00:00 2001
From: Anuja More <amore@redhat.com>
Date: Thu, 11 May 2023 12:50:10 +0530
Subject: [PATCH] ipatests: Check that SSSD_PUBCONF_KRB5_INCLUDE_D_DIR is not
included in krb5.conf
SSSD already provides a config snippet which includes
SSSD_PUBCONF_KRB5_INCLUDE_D_DIR, and having both breaks Java.
Test checks that krb5.conf does not include
SSSD_PUBCONF_KRB5_INCLUDE_D_DIR.
Related: https://pagure.io/freeipa/issue/9267
Signed-off-by: Anuja More <amore@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
.../test_integration/test_installation_client.py | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/ipatests/test_integration/test_installation_client.py b/ipatests/test_integration/test_installation_client.py
index 014b0f6ab..56e1593bf 100644
--- a/ipatests/test_integration/test_installation_client.py
+++ b/ipatests/test_integration/test_installation_client.py
@@ -76,6 +76,21 @@ class TestInstallClient(IntegrationTest):
result = self.clients[0].run_command(['cat', '/etc/ssh/ssh_config'])
assert 'HostKeyAlgorithms' not in result.stdout_text
+ def test_client_install_with_krb5(self):
+ """Test that SSSD_PUBCONF_KRB5_INCLUDE_D_DIR is not added in krb5.conf
+
+ SSSD already provides a config snippet which includes
+ SSSD_PUBCONF_KRB5_INCLUDE_D_DIR, and having both breaks Java.
+ Test checks that krb5.conf does not include
+ SSSD_PUBCONF_KRB5_INCLUDE_D_DIR.
+
+ related: https://pagure.io/freeipa/issue/9267
+ """
+ krb5_cfg = self.master.get_file_contents(paths.KRB5_CONF)
+ assert 'includedir {dir}'.format(
+ dir=paths.SSSD_PUBCONF_KRB5_INCLUDE_D_DIR
+ ).encode() not in krb5_cfg
+
class TestClientInstallBind(IntegrationTest):
"""
--
2.41.0
From f599e2d67bad5945e4dcf99fdd584f01f1e20d1e Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Tue, 6 Jun 2023 09:04:48 +0200
Subject: [PATCH] webuitests: close notification which hides Add button
The webui test test_service.py::test_service::test_arbitrary_certificates
randomly fails.
The test is creating a new service then navigates to the Service page
and clicks on the Add Certificate button.
The notification area may still be present and hide the button, with
the message "Service successfully added".
Close all notifications before navigating to the Service page.
Fixes: https://pagure.io/freeipa/issue/9389
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
---
ipatests/test_webui/test_service.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/ipatests/test_webui/test_service.py b/ipatests/test_webui/test_service.py
index f1d9a9d62..e2976d73a 100644
--- a/ipatests/test_webui/test_service.py
+++ b/ipatests/test_webui/test_service.py
@@ -296,6 +296,7 @@ class test_service(sevice_tasks):
cert_widget_sel = "div.certificate-widget"
self.add_record(ENTITY, data)
+ self.close_notifications()
self.navigate_to_record(pkey)
# check whether certificate section is present
--
2.41.0

View File

@ -0,0 +1,38 @@
From f25003a730c0e28c22fae5fce607df734b55525c Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Mon, 19 Jun 2023 19:01:25 +0200
Subject: [PATCH] Upgrade: add PKI drop-in file if missing
During the installation of IPA server, the installer adds a drop-in
file in /etc/systemd/system/pki-tomcatd@pki-tomcat.service.d/ipa.conf
that ensures the CA is reachable before the start command returns.
If the file is missing (for instance because the server was installed
with an old version before this drop-in was created), the upgrade
should add the file.
Fixes: https://pagure.io/freeipa/issue/9381
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipaserver/install/server/upgrade.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index f8701c8a0d43c7c1c1090e8576976b1c370b0104..8f3d57353605f28103c69cb0a34bf1c16fc4ae19 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1742,6 +1742,10 @@ def upgrade_configuration():
os.path.join(paths.USR_SHARE_IPA_DIR,
"ipa-kdc-proxy.conf.template"))
if ca.is_configured():
+ # Ensure that the drop-in file is present
+ if not os.path.isfile(paths.SYSTEMD_PKI_TOMCAT_IPA_CONF):
+ ca.add_ipa_wait()
+
# Handle upgrade of AJP connector configuration
rewrite = ca.secure_ajp_connector()
if ca.ajp_secret:
--
2.41.0

View File

@ -1,44 +1,7 @@
From 86c1426b2d376a390e87b074d3e10d85fa124abf Mon Sep 17 00:00:00 2001
From 392e60e3fa0e39a2e364268a21d869a2f3a85905 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Jun 21 2023 17:02:48 +0000
Subject: Upgrade: add PKI drop-in file if missing
During the installation of IPA server, the installer adds a drop-in
file in /etc/systemd/system/pki-tomcatd@pki-tomcat.service.d/ipa.conf
that ensures the CA is reachable before the start command returns.
If the file is missing (for instance because the server was installed
with an old version before this drop-in was created), the upgrade
should add the file.
Fixes: https://pagure.io/freeipa/issue/9381
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index dd22ac2..e4dc7ae 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1737,6 +1737,10 @@ def upgrade_configuration():
os.path.join(paths.USR_SHARE_IPA_DIR,
"ipa-kdc-proxy.conf.template"))
if ca.is_configured():
+ # Ensure that the drop-in file is present
+ if not os.path.isfile(paths.SYSTEMD_PKI_TOMCAT_IPA_CONF):
+ ca.add_ipa_wait()
+
# Handle upgrade of AJP connector configuration
rewrite = ca.secure_ajp_connector()
if ca.ajp_secret:
From 356ec5cbfe0876686239f938bdf54892dc30571e Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Jun 21 2023 17:02:48 +0000
Subject: Integration test: add a test for upgrade and PKI drop-in file
Date: Mon, 19 Jun 2023 19:04:32 +0200
Subject: [PATCH] Integration test: add a test for upgrade and PKI drop-in file
Add an upgrade test with the following scenario:
- remove PKI drop-in file (to simulate an upgrade from an old
@ -51,11 +14,12 @@ Related: https://pagure.io/freeipa/issue/9381
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipatests/test_integration/test_upgrade.py | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/ipatests/test_integration/test_upgrade.py b/ipatests/test_integration/test_upgrade.py
index 9203503..182e3b5 100644
index 9203503cdccf4478f9864bd487e458761e9a2a2f..182e3b5da3c758cc10913ad4eed119b0983fcc23 100644
--- a/ipatests/test_integration/test_upgrade.py
+++ b/ipatests/test_integration/test_upgrade.py
@@ -455,3 +455,25 @@ class TestUpgrade(IntegrationTest):
@ -84,4 +48,6 @@ index 9203503..182e3b5 100644
+ self.master.run_command(['ipa-server-upgrade'])
+ assert self.master.transport.file_exists(
+ paths.SYSTEMD_PKI_TOMCAT_IPA_CONF)
--
2.41.0

View File

@ -0,0 +1,129 @@
From f93a6d3ff52247ce5e582816fec689b8901fc984 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 14 Jun 2023 15:12:39 +0200
Subject: [PATCH] Uninstaller: uninstall PKI before shutting down services
The uninstaller is stopping all the services before
calling pkidestroy to uninstall the CA.
With PKI 11.4+ this sequence fails as pkidestroy tries
to connect to PKI server in order to unregister from the
security domain. The error interrupts the full completion
of pkidestroy, is logged but doesn't make ipa uninstallation
fail.
The issue is that trying to re-install later on would fail because
pkidestroy did not completely uninstall the CA.
To avoid this, call pkidestroy before shutting down the services.
Also add an uninstall_check method that restarts IPA if it is
not running, and use pkidestroy --force to make sure that PKI
is uninstalled even if restart failed.
Fixes: https://pagure.io/freeipa/issue/9330
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipaserver/install/ca.py | 18 ++++++++++++++++++
ipaserver/install/dogtaginstance.py | 2 +-
ipaserver/install/kra.py | 2 ++
ipaserver/install/server/install.py | 8 +++++---
4 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index be0e732e8ff6966ccc0077d9339f9f0bc66ae6ec..c93ae1fce4c8848d493677eafee7952740e51631 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -169,6 +169,24 @@ def print_ca_configuration(options):
def uninstall_check(options):
+ """IPA needs to be running so pkidestroy can unregister CA"""
+ ca = cainstance.CAInstance(api.env.realm)
+ if not ca.is_installed():
+ return
+
+ result = ipautil.run([paths.IPACTL, 'status'],
+ raiseonerr=False)
+
+ if result.returncode not in [0, 4]:
+ try:
+ logger.info(
+ "Starting services to unregister CA from security domain")
+ ipautil.run([paths.IPACTL, 'start'])
+ except Exception:
+ logger.info("Re-starting IPA failed, continuing uninstall")
+
+
+def uninstall_crl_check(options):
"""Check if the host is CRL generation master"""
# Skip the checks if the host is not a CA instance
ca = cainstance.CAInstance(api.env.realm)
diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py
index c2c6b3f49243f096448c178fafd09f429f0f46c8..4967aca01807e58dfcc3157af10b92eff5dba206 100644
--- a/ipaserver/install/dogtaginstance.py
+++ b/ipaserver/install/dogtaginstance.py
@@ -305,7 +305,7 @@ class DogtagInstance(service.Service):
self.print_msg("Unconfiguring %s" % self.subsystem)
args = [paths.PKIDESTROY,
- "-i", "pki-tomcat",
+ "-i", "pki-tomcat", "--force",
"-s", self.subsystem]
# specify --log-file <path> on PKI 11.0.0 or later
diff --git a/ipaserver/install/kra.py b/ipaserver/install/kra.py
index 857c5165b808baee3f0815e78828fb899eb78a2d..59cbda812a853997752f7d932e0690e3a950aa1f 100644
--- a/ipaserver/install/kra.py
+++ b/ipaserver/install/kra.py
@@ -132,6 +132,8 @@ def uninstall_check(options):
if result.returncode not in [0, 4]:
try:
+ logger.info(
+ "Starting services to unregister KRA from security domain")
ipautil.run([paths.IPACTL, 'start'])
except Exception:
logger.info("Re-starting IPA failed, continuing uninstall")
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index 4e4076410f1c1af188a0ab3606ef13be39702b7d..ccb958232935de2166f2d4867b626f59d7ba5333 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -1110,6 +1110,7 @@ def uninstall_check(installer):
raise ScriptError("Aborting uninstall operation.")
kra.uninstall_check(options)
+ ca.uninstall_check(options)
try:
api.Backend.ldap2.connect(autobind=True)
@@ -1132,7 +1133,7 @@ def uninstall_check(installer):
else:
dns.uninstall_check(options)
- ca.uninstall_check(options)
+ ca.uninstall_crl_check(options)
cleanup_dogtag_server_specific_data()
@@ -1181,6 +1182,9 @@ def uninstall(installer):
# Uninstall the KRA prior to shutting the services down so it
# can un-register with the CA.
kra.uninstall()
+ # Uninstall the CA priori to shutting the services down so it
+ # can unregister from the security domain
+ ca.uninstall()
print("Shutting down all IPA services")
try:
@@ -1194,8 +1198,6 @@ def uninstall(installer):
restore_time_sync(sstore, fstore)
- ca.uninstall()
-
dns.uninstall()
httpinstance.HTTPInstance(fstore).uninstall()
--
2.41.0

View File

@ -0,0 +1,44 @@
From b9a07b1e97ee4e310b50860103872685da540da4 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Mon, 19 Jun 2023 15:40:39 +0200
Subject: [PATCH] Detection of PKI subsystem
In order to know if ca/kra is installed locally, the code
is calling pki-server subsystem-show _subsystem_
and ensures that "Enabled: True" is in the output.
If a subsystem fails to start, the command returns
"Enabled: False" but it doesn't mean that the subsystem
is not installed, it just means that it is not active
right now.
Same output if the subsystem has been disabled with
pki-server subsystem-disable _subsystem_.
The correct way to check if a subsystem is installed is to
ensure that subsystem-show does not exit on error and
contains "Enabled: ", whatever the value.
Related: https://pagure.io/freeipa/issue/9330
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipaserver/install/dogtaginstance.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py
index 4967aca01807e58dfcc3157af10b92eff5dba206..7fdf2e0ed0f3ed99a6672f527d38dda0ce5ef8bb 100644
--- a/ipaserver/install/dogtaginstance.py
+++ b/ipaserver/install/dogtaginstance.py
@@ -184,7 +184,7 @@ class DogtagInstance(service.Service):
['pki-server', 'subsystem-show', self.subsystem.lower()],
capture_output=True)
# parse the command output
- return 'Enabled: True' in result.output
+ return 'Enabled: ' in result.output
except ipautil.CalledProcessError:
return False
--
2.41.0

View File

@ -1,4 +1,4 @@
From d29b47512a39ada02fb371521994576cd9815a6c Mon Sep 17 00:00:00 2001
From ad77c4c6512f82019d1970d910647761b60aaedb Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Mon, 19 Jun 2023 10:36:29 +0200
Subject: [PATCH] Upgrade: fix replica agreement
@ -32,7 +32,7 @@ Reviewed-By: Rob Crittenden <rcritten@redhat.com>
1 file changed, 38 insertions(+), 42 deletions(-)
diff --git a/ipaserver/install/plugins/fix_replica_agreements.py b/ipaserver/install/plugins/fix_replica_agreements.py
index c0cdd3eb1..d963753d0 100644
index c0cdd3eb19c486121f727476360ce421b1d82728..d963753d0bf9ee65285a86fa9a249198c28a66e2 100644
--- a/ipaserver/install/plugins/fix_replica_agreements.py
+++ b/ipaserver/install/plugins/fix_replica_agreements.py
@@ -22,6 +22,7 @@ import logging
@ -162,72 +162,3 @@ index c0cdd3eb1..d963753d0 100644
--
2.41.0
From 93d97b59600c15e5028ee39b0e98450544165158 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Mon, 19 Jun 2023 10:36:59 +0200
Subject: [PATCH] Integration tests: add a test to ipa-server-upgrade
Add an integration test ensuring that the upgrade
properly updates the attributes to be excluded from
replication.
Related: https://pagure.io/freeipa/issue/9385
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
.../test_simple_replication.py | 30 +++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/ipatests/test_integration/test_simple_replication.py b/ipatests/test_integration/test_simple_replication.py
index 17092a499..d1e65ef7c 100644
--- a/ipatests/test_integration/test_simple_replication.py
+++ b/ipatests/test_integration/test_simple_replication.py
@@ -23,8 +23,10 @@ import pytest
from ipaplatform.paths import paths
from ipapython.dn import DN
+from ipaserver.install.replication import EXCLUDES
from ipatests.pytest_ipa.integration import tasks
from ipatests.test_integration.base import IntegrationTest
+from ipatests.test_integration.test_topology import find_segment
def check_replication(source_host, dest_host, login):
@@ -104,6 +106,34 @@ class TestSimpleReplication(IntegrationTest):
[paths.IPA_CUSTODIA_CHECK, self.master.hostname]
)
+ def test_fix_agreements(self):
+ """Test that upgrade fixes the list of attributes excluded from repl
+
+ Test for ticket 9385
+ """
+ # Prepare the server by removing some values from
+ # from the nsDS5ReplicatedAttributeList
+ segment = find_segment(self.master, self.replicas[0], "domain")
+ self.master.run_command([
+ "ipa", "topologysegment-mod", "domain", segment,
+ "--replattrs",
+ "(objectclass=*) $ EXCLUDE memberof idnssoaserial entryusn"])
+ # Run the upgrade
+ result = self.master.run_command(["ipa-server-upgrade"])
+ # Ensure that the upgrade updated the attribute without error
+ errmsg = "Error caught updating nsDS5ReplicatedAttributeList"
+ assert errmsg not in result.stdout_text
+ # Check the updated value
+ suffix = DN(self.master.domain.basedn)
+ dn = DN(('cn', str(suffix)), ('cn', 'mapping tree'), ('cn', 'config'))
+ result = tasks.ldapsearch_dm(self.master, str(dn),
+ ["nsDS5ReplicatedAttributeList"])
+ output = result.stdout_text.lower()
+
+ template = 'nsDS5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE %s'
+ expected_value = template % " ".join(EXCLUDES)
+ assert expected_value.lower() in output
+
def test_replica_removal(self):
"""Test replica removal"""
result = self.master.run_command(['ipa-replica-manage', 'list'])
--
2.41.0

View File

@ -0,0 +1,69 @@
From 3b58487c7b2f8ac133e37e8f90f85ff2fb05bf34 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Mon, 19 Jun 2023 10:36:59 +0200
Subject: [PATCH] Integration tests: add a test to ipa-server-upgrade
Add an integration test ensuring that the upgrade
properly updates the attributes to be excluded from
replication.
Related: https://pagure.io/freeipa/issue/9385
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
.../test_simple_replication.py | 30 +++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/ipatests/test_integration/test_simple_replication.py b/ipatests/test_integration/test_simple_replication.py
index 17092a49966e61d5a4a9b04c15abcb1de8be9683..d1e65ef7cc3e748670f2cdebe2a5cb7172af27f0 100644
--- a/ipatests/test_integration/test_simple_replication.py
+++ b/ipatests/test_integration/test_simple_replication.py
@@ -23,8 +23,10 @@ import pytest
from ipaplatform.paths import paths
from ipapython.dn import DN
+from ipaserver.install.replication import EXCLUDES
from ipatests.pytest_ipa.integration import tasks
from ipatests.test_integration.base import IntegrationTest
+from ipatests.test_integration.test_topology import find_segment
def check_replication(source_host, dest_host, login):
@@ -104,6 +106,34 @@ class TestSimpleReplication(IntegrationTest):
[paths.IPA_CUSTODIA_CHECK, self.master.hostname]
)
+ def test_fix_agreements(self):
+ """Test that upgrade fixes the list of attributes excluded from repl
+
+ Test for ticket 9385
+ """
+ # Prepare the server by removing some values from
+ # from the nsDS5ReplicatedAttributeList
+ segment = find_segment(self.master, self.replicas[0], "domain")
+ self.master.run_command([
+ "ipa", "topologysegment-mod", "domain", segment,
+ "--replattrs",
+ "(objectclass=*) $ EXCLUDE memberof idnssoaserial entryusn"])
+ # Run the upgrade
+ result = self.master.run_command(["ipa-server-upgrade"])
+ # Ensure that the upgrade updated the attribute without error
+ errmsg = "Error caught updating nsDS5ReplicatedAttributeList"
+ assert errmsg not in result.stdout_text
+ # Check the updated value
+ suffix = DN(self.master.domain.basedn)
+ dn = DN(('cn', str(suffix)), ('cn', 'mapping tree'), ('cn', 'config'))
+ result = tasks.ldapsearch_dm(self.master, str(dn),
+ ["nsDS5ReplicatedAttributeList"])
+ output = result.stdout_text.lower()
+
+ template = 'nsDS5ReplicatedAttributeList: (objectclass=*) $ EXCLUDE %s'
+ expected_value = template % " ".join(EXCLUDES)
+ assert expected_value.lower() in output
+
def test_replica_removal(self):
"""Test replica removal"""
result = self.master.run_command(['ipa-replica-manage', 'list'])
--
2.41.0

View File

@ -0,0 +1,55 @@
From 5e291da42898cc646f699c21a44b03b833d346e8 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Tue, 27 Jun 2023 15:30:08 +0200
Subject: [PATCH] tests: fix backup-restore scenario with replica
The test TestBackupAndRestoreWithReplica is simulating a
master crash in order to check the behavior after ipa-restore.
Since commit 67a33e5, the uninstaller restarts the services in
order to unregister the server from PKI security domain. An
indirect consequence is that master/replica communication is re-
established and operations removing entries (done by the uninstaller)
are replicated to the replica.
This means that the scenario does not really simulate a server crash.
To make sure that no replication happens during this "crash", stop
the replica first, then uninstall the master, and finally restart
the replica before calling the ipa-restore command on the master.
Fixes: https://pagure.io/freeipa/issue/9404
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipatests/test_integration/test_backup_and_restore.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/ipatests/test_integration/test_backup_and_restore.py b/ipatests/test_integration/test_backup_and_restore.py
index 390c065f373e9a8a667f228a09eebd9ac033a19f..83b6a6b44d805fb0615e2128d4be984c6f858bf9 100644
--- a/ipatests/test_integration/test_backup_and_restore.py
+++ b/ipatests/test_integration/test_backup_and_restore.py
@@ -602,6 +602,12 @@ class TestBackupAndRestoreWithReplica(IntegrationTest):
tasks.user_add(self.replica1, 'test2_replica')
# simulate master crash
+ # the replica is stopped to make sure master uninstallation
+ # does not delete any entry on the replica. In case of a
+ # real master crash there would not be any communication between
+ # master and replica
+ self.replica1.run_command(['ipactl', 'stop'])
+
self.master.run_command(['ipactl', 'stop'])
tasks.uninstall_master(self.master, clean=False)
@@ -612,6 +618,7 @@ class TestBackupAndRestoreWithReplica(IntegrationTest):
self.master.run_command([
"systemctl", "disable", "oddjobd"
])
+ self.replica1.run_command(['ipactl', 'start'])
self.master.run_command(['ipa-restore', '-U', backup_path])
--
2.41.0

View File

@ -1,8 +1,7 @@
From a7e167154b889f75463ccc9cd91a75c1afb22da9 Mon Sep 17 00:00:00 2001
From 631dd72369385b0793e5bc0e019c088b4f1e2bb3 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Jun 28 2023 19:43:16 +0000
Subject: OTP: fix data type to avoid endianness issue
Date: Mon, 26 Jun 2023 18:24:46 +0200
Subject: [PATCH] OTP: fix data type to avoid endianness issue
When 389-ds process an OTP authentication, the ipa-pwd-extop
plugin reads a buffer to extract the authentication type.
@ -21,11 +20,12 @@ Fixes: https://pagure.io/freeipa/issue/9402
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
index 9375941..4562652 100644
index 937594117956d57540d4cf4eabeef6d22860aec8..45626523ffa1030cdff4f3e0ccdfa1618a51ccaf 100644
--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c
@@ -1433,7 +1433,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
@ -49,4 +49,6 @@ index 9375941..4562652 100644
/* Retrieve the user's entry. */
sdn = slapi_sdn_dup(target_sdn);
--
2.41.0

View File

@ -1,4 +1,4 @@
From f68468718c1e01df4a9180e17d7e24d961850e19 Mon Sep 17 00:00:00 2001
From 1e8352486cd5f77ff79e18798f04f406baf0a9a1 Mon Sep 17 00:00:00 2001
From: Mohammad Rizwan <myusuf@redhat.com>
Date: Wed, 14 Jun 2023 17:32:02 +0530
Subject: [PATCH] ipatests: enable firewall rule for http service on acme
@ -16,18 +16,18 @@ Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
1 file changed, 4 insertions(+)
diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py
index c69e810da70..414fae8d751 100644
index 9718c408b7f48dd78dc2abae32fb9ecb85445dfb..cca20983e65f99d5ba0bb7bc6dc2b5684a6f37d9 100644
--- a/ipatests/test_integration/test_acme.py
+++ b/ipatests/test_integration/test_acme.py
@@ -10,6 +10,7 @@
@@ -10,6 +10,7 @@ import pytest
from ipalib.constants import IPA_CA_RECORD
from ipatests.test_integration.base import IntegrationTest
+from ipatests.pytest_ipa.integration.firewall import Firewall
from ipatests.pytest_ipa.integration import tasks
from ipatests.test_integration.test_caless import CALessBase, ipa_certs_cleanup
from ipaplatform.osinfo import osinfo
@@ -82,6 +83,9 @@ def prepare_acme_client(master, client):
from ipatests.test_integration.test_random_serial_numbers import (
@@ -85,6 +86,9 @@ def prepare_acme_client(master, client):
acme_host = f'{IPA_CA_RECORD}.{master.domain.name}'
acme_server = f'https://{acme_host}/acme/directory'
@ -37,3 +37,6 @@ index c69e810da70..414fae8d751 100644
# install acme client packages
if not skip_certbot_tests:
tasks.install_packages(client, ['certbot'])
--
2.41.0

View File

@ -0,0 +1,79 @@
From 387873080f1bc14aeaad89311b06dc46934be1ab Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 19 Jul 2023 13:24:55 +0200
Subject: [PATCH] User plugin: improve error related to non existing idp
The user and stageuser commands return the following error
when the user is created/updated with a non existing idp:
$ ipa user-add testuser --first test --last user --idp dummy
ipa: ERROR: no such entry
The error is not descriptive enough and has been modified to
display instead:
$ ipa user-add testuser --first test --last user --idp dummy
ipa: ERROR: External IdP configuration dummy not found
Fixes: https://pagure.io/freeipa/issue/9416
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipaserver/plugins/baseuser.py | 6 +++++-
ipaserver/plugins/stageuser.py | 6 +++++-
ipaserver/plugins/user.py | 6 +++++-
3 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py
index 73b76d328a88639afd40bd261c8a35f324ec865b..ba5f9b7763662b32f238c0fb0ca548ff2f07db0d 100644
--- a/ipaserver/plugins/baseuser.py
+++ b/ipaserver/plugins/baseuser.py
@@ -708,7 +708,11 @@ class baseuser_mod(LDAPUpdate):
if 'ipaidpuser' not in obj_classes:
entry_attrs['objectclass'].append('ipaidpuser')
- answer = self.api.Object['idp'].get_dn_if_exists(cl)
+ try:
+ answer = self.api.Object['idp'].get_dn_if_exists(cl)
+ except errors.NotFound:
+ reason = "External IdP configuration {} not found"
+ raise errors.NotFound(reason=_(reason).format(cl))
entry_attrs['ipaidpconfiglink'] = answer
# Note: we could have used the method add_missing_object_class
diff --git a/ipaserver/plugins/stageuser.py b/ipaserver/plugins/stageuser.py
index 51438a83a95d15fb320148d2934a52f13a38f390..852e51b0eb0d757940b84721a6f01e43c5f36dd2 100644
--- a/ipaserver/plugins/stageuser.py
+++ b/ipaserver/plugins/stageuser.py
@@ -404,7 +404,11 @@ class stageuser_add(baseuser_add):
if 'ipaidpuser' not in entry_attrs['objectclass']:
entry_attrs['objectclass'].append('ipaidpuser')
- answer = self.api.Object['idp'].get_dn_if_exists(cl)
+ try:
+ answer = self.api.Object['idp'].get_dn_if_exists(cl)
+ except errors.NotFound:
+ reason = "External IdP configuration {} not found"
+ raise errors.NotFound(reason=_(reason).format(cl))
entry_attrs['ipaidpconfiglink'] = answer
self.pre_common_callback(ldap, dn, entry_attrs, attrs_list, *keys,
diff --git a/ipaserver/plugins/user.py b/ipaserver/plugins/user.py
index 643b44f141e3add76f95cbeec6e90fec0ad4c9ad..a337e1fc7b44ef41ad16e18bd965b7af0a767d05 100644
--- a/ipaserver/plugins/user.py
+++ b/ipaserver/plugins/user.py
@@ -638,7 +638,11 @@ class user_add(baseuser_add):
if 'ipaidpuser' not in entry_attrs['objectclass']:
entry_attrs['objectclass'].append('ipaidpuser')
- answer = self.api.Object['idp'].get_dn_if_exists(rcl)
+ try:
+ answer = self.api.Object['idp'].get_dn_if_exists(rcl)
+ except errors.NotFound:
+ reason = "External IdP configuration {} not found"
+ raise errors.NotFound(reason=_(reason).format(rcl))
entry_attrs['ipaidpconfiglink'] = answer
self.pre_common_callback(ldap, dn, entry_attrs, attrs_list, *keys,
--
2.41.0

View File

@ -1,83 +1,8 @@
From 99aa03413421cf2839e89e10ca279ec19233dd01 Mon Sep 17 00:00:00 2001
From caacccc6b92c08f510fba2e31d9c56eb372abddc Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Jul 20 2023 08:23:36 +0000
Subject: User plugin: improve error related to non existing idp
The user and stageuser commands return the following error
when the user is created/updated with a non existing idp:
$ ipa user-add testuser --first test --last user --idp dummy
ipa: ERROR: no such entry
The error is not descriptive enough and has been modified to
display instead:
$ ipa user-add testuser --first test --last user --idp dummy
ipa: ERROR: External IdP configuration dummy not found
Fixes: https://pagure.io/freeipa/issue/9416
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
diff --git a/ipaserver/plugins/baseuser.py b/ipaserver/plugins/baseuser.py
index 73b76d3..ba5f9b7 100644
--- a/ipaserver/plugins/baseuser.py
+++ b/ipaserver/plugins/baseuser.py
@@ -708,7 +708,11 @@ class baseuser_mod(LDAPUpdate):
if 'ipaidpuser' not in obj_classes:
entry_attrs['objectclass'].append('ipaidpuser')
- answer = self.api.Object['idp'].get_dn_if_exists(cl)
+ try:
+ answer = self.api.Object['idp'].get_dn_if_exists(cl)
+ except errors.NotFound:
+ reason = "External IdP configuration {} not found"
+ raise errors.NotFound(reason=_(reason).format(cl))
entry_attrs['ipaidpconfiglink'] = answer
# Note: we could have used the method add_missing_object_class
diff --git a/ipaserver/plugins/stageuser.py b/ipaserver/plugins/stageuser.py
index 51438a8..852e51b 100644
--- a/ipaserver/plugins/stageuser.py
+++ b/ipaserver/plugins/stageuser.py
@@ -404,7 +404,11 @@ class stageuser_add(baseuser_add):
if 'ipaidpuser' not in entry_attrs['objectclass']:
entry_attrs['objectclass'].append('ipaidpuser')
- answer = self.api.Object['idp'].get_dn_if_exists(cl)
+ try:
+ answer = self.api.Object['idp'].get_dn_if_exists(cl)
+ except errors.NotFound:
+ reason = "External IdP configuration {} not found"
+ raise errors.NotFound(reason=_(reason).format(cl))
entry_attrs['ipaidpconfiglink'] = answer
self.pre_common_callback(ldap, dn, entry_attrs, attrs_list, *keys,
diff --git a/ipaserver/plugins/user.py b/ipaserver/plugins/user.py
index 643b44f..a337e1f 100644
--- a/ipaserver/plugins/user.py
+++ b/ipaserver/plugins/user.py
@@ -638,7 +638,11 @@ class user_add(baseuser_add):
if 'ipaidpuser' not in entry_attrs['objectclass']:
entry_attrs['objectclass'].append('ipaidpuser')
- answer = self.api.Object['idp'].get_dn_if_exists(rcl)
+ try:
+ answer = self.api.Object['idp'].get_dn_if_exists(rcl)
+ except errors.NotFound:
+ reason = "External IdP configuration {} not found"
+ raise errors.NotFound(reason=_(reason).format(rcl))
entry_attrs['ipaidpconfiglink'] = answer
self.pre_common_callback(ldap, dn, entry_attrs, attrs_list, *keys,
From dbcbe9a39c99008c6858bab53e2807b7bf01ba65 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Jul 20 2023 08:23:36 +0000
Subject: xmlrpc tests: add a test for user plugin with non-existing idp
Date: Wed, 19 Jul 2023 13:28:43 +0200
Subject: [PATCH] xmlrpc tests: add a test for user plugin with non-existing
idp
Add new tests checking the error returned for
ipa user-add ... --idp nonexistingidp
@ -92,11 +17,13 @@ Related: https://pagure.io/freeipa/issue/9416
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
ipatests/test_xmlrpc/test_stageuser_plugin.py | 20 +++++++++++++++
ipatests/test_xmlrpc/test_user_plugin.py | 25 +++++++++++++++++++
2 files changed, 45 insertions(+)
diff --git a/ipatests/test_xmlrpc/test_stageuser_plugin.py b/ipatests/test_xmlrpc/test_stageuser_plugin.py
index 394015f..9ae5561 100644
index 394015f87f9f4bd275a15bab930e28f16b299274..9ae5561dfa4e0d54fe1231501bfea3c0ba261849 100644
--- a/ipatests/test_xmlrpc/test_stageuser_plugin.py
+++ b/ipatests/test_xmlrpc/test_stageuser_plugin.py
@@ -39,6 +39,8 @@ gid = u'456'
@ -107,7 +34,7 @@ index 394015f..9ae5561 100644
+
invaliduser1 = u'+tuser1'
invaliduser2 = u'tuser1234567890123456789012345678901234567890'
invaliduser3 = u'1234'
@@ -431,6 +433,15 @@ class TestCreateInvalidAttributes(XMLRPC_test):
invalidrealm2))):
command()
@ -141,7 +68,7 @@ index 394015f..9ae5561 100644
@pytest.mark.tier1
class TestActive(XMLRPC_test):
diff --git a/ipatests/test_xmlrpc/test_user_plugin.py b/ipatests/test_xmlrpc/test_user_plugin.py
index 8ac19a4..baa2867 100644
index 8ac19a4f9ce4f341838282ecd3ed1bb491ac7004..baa28672e7552140a703ecdfa5772b445298cb37 100644
--- a/ipatests/test_xmlrpc/test_user_plugin.py
+++ b/ipatests/test_xmlrpc/test_user_plugin.py
@@ -86,6 +86,8 @@ expired_expiration_string = "1991-12-07T19:54:13Z"
@ -190,4 +117,6 @@ index 8ac19a4..baa2867 100644
@pytest.mark.tier1
class TestUserWithGroup(XMLRPC_test):
--
2.41.0

View File

@ -1,8 +1,7 @@
From 9438ce9207445e4ad4a9c7bdf0c9e569cabac571 Mon Sep 17 00:00:00 2001
From 421e8e9ac886c50b4bb463a62b8ad5de8da94f31 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Aug 01 2023 06:07:06 +0000
Subject: Fix memory leak in the OTP last token plugin
Date: Mon, 26 Jun 2023 13:06:51 -0400
Subject: [PATCH] Fix memory leak in the OTP last token plugin
Three memory leaks are addressed:
@ -19,11 +18,13 @@ Fixes: https://pagure.io/freeipa/issue/9403
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
.../ipa-otp-lasttoken/ipa_otp_lasttoken.c | 38 +++++++++++++------
daemons/ipa-slapi-plugins/libotp/otp_token.c | 1 +
2 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/daemons/ipa-slapi-plugins/ipa-otp-lasttoken/ipa_otp_lasttoken.c b/daemons/ipa-slapi-plugins/ipa-otp-lasttoken/ipa_otp_lasttoken.c
index b7a2ba7..11106b2 100644
index b7a2ba7f012fdbf90284ee6605788e196aa4793b..11106b239f9de9074125979cfae7c02e434936e1 100644
--- a/daemons/ipa-slapi-plugins/ipa-otp-lasttoken/ipa_otp_lasttoken.c
+++ b/daemons/ipa-slapi-plugins/ipa-otp-lasttoken/ipa_otp_lasttoken.c
@@ -54,7 +54,7 @@ void *ipa_otp_lasttoken_plugin_id;
@ -100,7 +101,7 @@ index b7a2ba7..11106b2 100644
static inline int send_error(Slapi_PBlock *pb, int rc, const char *errstr)
diff --git a/daemons/ipa-slapi-plugins/libotp/otp_token.c b/daemons/ipa-slapi-plugins/libotp/otp_token.c
index a3cbfb0..4be4ede 100644
index a3cbfb0621c071f8addb29f7ce02f870a807c61d..4be4ede07cbbd0d26bcc9952ef4d84d777076ae7 100644
--- a/daemons/ipa-slapi-plugins/libotp/otp_token.c
+++ b/daemons/ipa-slapi-plugins/libotp/otp_token.c
@@ -398,6 +398,7 @@ static struct otp_token **find(const struct otp_config *cfg, const char *user_dn
@ -111,4 +112,6 @@ index a3cbfb0..4be4ede 100644
slapi_pblock_destroy(pb);
return tokens;
}
--
2.41.0

View File

@ -1,8 +1,7 @@
From f215d3f45396fa29bdd69f56096b50842df14908 Mon Sep 17 00:00:00 2001
From 4b02322fc786ee9caaa0380659507a2cec0d4101 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Aug 01 2023 22:03:03 +0000
Subject: Prevent the admin user from being deleted
Date: Thu, 25 May 2023 18:24:29 -0400
Subject: [PATCH] Prevent the admin user from being deleted
admin is required for trust operations
@ -15,11 +14,13 @@ Fixes: https://pagure.io/freeipa/issue/8878
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
ipaserver/plugins/user.py | 19 +++++++++--
ipatests/test_xmlrpc/test_user_plugin.py | 40 ++++++++++++------------
2 files changed, 37 insertions(+), 22 deletions(-)
diff --git a/ipaserver/plugins/user.py b/ipaserver/plugins/user.py
index a337e1f..6f5e349 100644
index a337e1fc7b44ef41ad16e18bd965b7af0a767d05..6f5e34917e1b838a463dee146a4e9390f20c130a 100644
--- a/ipaserver/plugins/user.py
+++ b/ipaserver/plugins/user.py
@@ -138,14 +138,23 @@ MEMBEROF_ADMINS = "(memberOf={})".format(
@ -62,7 +63,7 @@ index a337e1f..6f5e349 100644
entry_attrs.update({'objectclass': oc})
self.pre_common_callback(ldap, dn, entry_attrs, attrs_list, *keys,
diff --git a/ipatests/test_xmlrpc/test_user_plugin.py b/ipatests/test_xmlrpc/test_user_plugin.py
index baa2867..df105a2 100644
index baa28672e7552140a703ecdfa5772b445298cb37..df105a23529b29944411a6418e5db55d56e2c72a 100644
--- a/ipatests/test_xmlrpc/test_user_plugin.py
+++ b/ipatests/test_xmlrpc/test_user_plugin.py
@@ -978,22 +978,32 @@ class TestManagers(XMLRPC_test):
@ -130,40 +131,6 @@ index baa2867..df105a2 100644
@pytest.mark.tier1
class TestPreferredLanguages(XMLRPC_test):
From 7d62d84bdd3c2acd2f4bf70bb5fabf14c72e8ee7 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Aug 08 2023 14:50:32 +0000
Subject: ipatests: update expected webui msg for admin deletion
The deletion of the admin is now forbidden (even if it is
not the last member of the admins group) and the error
message has changed from "admin cannot be deleted or
disabled because it is the last member of group admins"
to " user admin cannot be deleted/modified: privileged user".
Update the expected message in the webui test.
Related: https://pagure.io/freeipa/issue/8878
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
diff --git a/ipatests/test_webui/test_user.py b/ipatests/test_webui/test_user.py
index 8d44fbd..a8a92d0 100644
--- a/ipatests/test_webui/test_user.py
+++ b/ipatests/test_webui/test_user.py
@@ -50,8 +50,7 @@ INV_FIRSTNAME = ("invalid 'first': Leading and trailing spaces are "
FIELD_REQ = 'Required field'
ERR_INCLUDE = 'may only include letters, numbers, _, -, . and $'
ERR_MISMATCH = 'Passwords must match'
-ERR_ADMIN_DEL = ('admin cannot be deleted or disabled because it is the last '
- 'member of group admins')
+ERR_ADMIN_DEL = ('user admin cannot be deleted/modified: privileged user')
USR_EXIST = 'user with name "{}" already exists'
ENTRY_EXIST = 'This entry already exists'
ACTIVE_ERR = 'active user with name "{}" already exists'
--
2.41.0

View File

@ -1,8 +1,7 @@
From b5793c854035a122ed4c66f917cc427e5024e46a Mon Sep 17 00:00:00 2001
From fd32e6a3d95f28d2d11d41ee5dabb0d563cb5d51 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Aug 02 2023 11:52:30 +0000
Subject: ipa-kdb: fix error handling of is_master_host()
Date: Mon, 31 Jul 2023 11:26:43 +0200
Subject: [PATCH] ipa-kdb: fix error handling of is_master_host()
Adding proper error handling to the is_master_host() function to allow
it to make the difference between the absence of a master host object
@ -13,11 +12,12 @@ Fixes: https://pagure.io/freeipa/issue/9422
Signed-off-by: Julien Rische <jrische@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
daemons/ipa-kdb/ipa_kdb_mspac.c | 41 +++++++++++++++++++--------------
1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index 8da7543..83cb991 100644
index 83b507cb422c735f933edaebfc7b903b8fa908e4..1558e2bead288d9d00014e9b3b059934e80b54e4 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -401,27 +401,29 @@ static krb5_error_code ipadb_add_asserted_identity(struct ipadb_context *ipactx,
@ -82,4 +82,6 @@ index 8da7543..83cb991 100644
if (is_master) {
/* Well known RID of domain controllers group */
if (info3->base.rid == 0) {
--
2.41.0

View File

@ -0,0 +1,38 @@
From 13d5e88eb4ebb7a0132cbb050a9d230304ecbcff Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Wed, 2 Aug 2023 15:41:57 +0200
Subject: [PATCH] ipatests: update expected webui msg for admin deletion
The deletion of the admin is now forbidden (even if it is
not the last member of the admins group) and the error
message has changed from "admin cannot be deleted or
disabled because it is the last member of group admins"
to " user admin cannot be deleted/modified: privileged user".
Update the expected message in the webui test.
Related: https://pagure.io/freeipa/issue/8878
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
ipatests/test_webui/test_user.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/ipatests/test_webui/test_user.py b/ipatests/test_webui/test_user.py
index 8d44fbdb9380c94058307b02a96299d0e178cdc7..a8a92d00c7e1f40ef10eb9133cea8752daafe730 100644
--- a/ipatests/test_webui/test_user.py
+++ b/ipatests/test_webui/test_user.py
@@ -50,8 +50,7 @@ INV_FIRSTNAME = ("invalid 'first': Leading and trailing spaces are "
FIELD_REQ = 'Required field'
ERR_INCLUDE = 'may only include letters, numbers, _, -, . and $'
ERR_MISMATCH = 'Passwords must match'
-ERR_ADMIN_DEL = ('admin cannot be deleted or disabled because it is the last '
- 'member of group admins')
+ERR_ADMIN_DEL = ('user admin cannot be deleted/modified: privileged user')
USR_EXIST = 'user with name "{}" already exists'
ENTRY_EXIST = 'This entry already exists'
ACTIVE_ERR = 'active user with name "{}" already exists'
--
2.41.0

View File

@ -0,0 +1,70 @@
From ff6cfcacd67a0461a0341e17854732cbe301f1d6 Mon Sep 17 00:00:00 2001
From: Mohammad Rizwan <myusuf@redhat.com>
Date: Wed, 2 Aug 2023 12:48:40 +0530
Subject: [PATCH] ipatests: remove fixture call and wait to get things settle
system date moved in order to expire the certs. Sometime it
is observed that subsequent operation fails with 500 error for CA,
hence restart the services after moving date and wait for sometime
to get things settle.
Also the tests was calling fixture which is not required for it, hence
removed it as well.
Fixes: https://pagure.io/freeipa/issue/9348
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipatests/test_integration/test_acme.py | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py
index cca20983e65f99d5ba0bb7bc6dc2b5684a6f37d9..c7389732cd067d49541cd04ea6687a6b95b4669f 100644
--- a/ipatests/test_integration/test_acme.py
+++ b/ipatests/test_integration/test_acme.py
@@ -606,6 +606,11 @@ def issue_and_expire_acme_cert():
tasks.kdestroy_all(host)
tasks.move_date(host, 'stop', '+90days+60minutes')
+ # restart ipa services as date moved and wait to get things settle
+ time.sleep(10)
+ master.run_command(['ipactl', 'restart'])
+ time.sleep(10)
+
tasks.get_kdcinfo(master)
# Note raiseonerr=False:
# the assert is located after kdcinfo retrieval.
@@ -627,6 +632,11 @@ def issue_and_expire_acme_cert():
for host in hosts:
tasks.move_date(host, 'start', '-90days-60minutes')
+ # restart ipa services as date moved and wait to get things settle
+ time.sleep(10)
+ hosts[0].run_command(['ipactl', 'restart'])
+ time.sleep(10)
+
class TestACMERenew(IntegrationTest):
@@ -960,7 +970,7 @@ class TestACMEPrune(IntegrationTest):
)
assert f'Number of entries returned {no_of_cert - search_size_limit}'
- def test_prune_config_show(self, issue_and_expire_acme_cert):
+ def test_prune_config_show(self):
"""Test to check config-show command shows set param"""
if (tasks.get_pki_version(self.master)
< tasks.parse_version('11.3.0')):
@@ -1001,7 +1011,7 @@ class TestACMEPrune(IntegrationTest):
assert 'Request Search Time Limit: 0' in result.stdout_text
assert 'cron Schedule: 0 0 1 * *' in result.stdout_text
- def test_prune_disable(self, issue_and_expire_acme_cert):
+ def test_prune_disable(self):
"""Test prune command throw error after disabling the pruning"""
if (tasks.get_pki_version(self.master)
< tasks.parse_version('11.3.0')):
--
2.41.0

View File

@ -1,8 +1,7 @@
From fdaad3a45f5674876fd3f6cc7ad1e916ebfc7080 Mon Sep 17 00:00:00 2001
From 1278e614dd93bf0ac3d6e0c36cb9c277808afb2c Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Aug 14 2023 13:02:20 +0000
Subject: ipatests: fix test_topology
Date: Fri, 11 Aug 2023 08:01:18 +0200
Subject: [PATCH] ipatests: fix test_topology
The test TestTopologyOptions::test_add_remove_segment is
randomly failing downstream. Test scenario:
@ -17,11 +16,12 @@ before checking the user presence on repl2.
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Anuja More <amore@redhat.com>
---
ipatests/test_integration/test_topology.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/ipatests/test_integration/test_topology.py b/ipatests/test_integration/test_topology.py
index 8a240fa..618c9d5 100644
index 8a240fa3c081a05b8f4501fe48694e01086003a1..618c9d5dcce994cd0359a291b044eb2cf0bddc74 100644
--- a/ipatests/test_integration/test_topology.py
+++ b/ipatests/test_integration/test_topology.py
@@ -124,6 +124,9 @@ class TestTopologyOptions(IntegrationTest):
@ -55,4 +55,6 @@ index 8a240fa..618c9d5 100644
result4 = self.replicas[1].run_command(['ipa', 'user-find'])
assert('someuser' in result4.stdout_text), 'User not found: someuser'
# We end up having a line topology: master <-> replica1 <-> replica2
--
2.41.0

View File

@ -0,0 +1,560 @@
From ac6a2172f5dcb46701148c7b096ffa1b44076816 Mon Sep 17 00:00:00 2001
From: Sudhir Menon <sumenon@redhat.com>
Date: Thu, 27 Jul 2023 14:33:08 +0530
Subject: [PATCH] ipatests: idm api related tests.
IDM API related tests are automated in the
above PR
Ref: https://freeipa.readthedocs.io/en/latest/api/basic_usage.html
Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
ipatests/test_integration/test_idm_api.py | 534 ++++++++++++++++++++++
1 file changed, 534 insertions(+)
create mode 100644 ipatests/test_integration/test_idm_api.py
diff --git a/ipatests/test_integration/test_idm_api.py b/ipatests/test_integration/test_idm_api.py
new file mode 100644
index 0000000000000000000000000000000000000000..eafef5dd8526bc14725d6bc32819cb5c7387f868
--- /dev/null
+++ b/ipatests/test_integration/test_idm_api.py
@@ -0,0 +1,534 @@
+#
+# Copyright (C) 2018 FreeIPA Contributors see COPYING for license
+#
+from __future__ import absolute_import
+
+from ipatests.test_integration.base import IntegrationTest
+import textwrap
+
+API_INIT = """
+ from ipalib import api, errors
+ api.bootstrap_with_global_options(context="server")
+ api.finalize()
+ api.Backend.ldap2.connect()
+ """
+
+CERT = (
+ b"MIIEkDCCAvigAwIBAgIBCzANBgkqhkiG9w0BAQsFADA5MRcwFQYDVQQKD\n"
+ b"A5URVNUUkVBTE0uVEVTVDEeMBwGA1UEAwwVQ2VydGlmaWNhdGUgQXV0aG\n"
+ b"9yaXR5MB4XDTIzMDcyODE3MTIxOVoXDTI1MDcyODE3MTIxOVowKjEXMBU\n"
+ b"GA1UECgwOVEVTVFJFQUxNLlRFU1QxDzANBgNVBAMMBmpzbWl0aDCCASIw\n"
+ b"DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOF0XFrdVXmKp95AVZW5o\n"
+ b"BWcij6vJPqeU3UpzTLbM+fROhNaKMX9S+yXrJHifOmhCOuNA8TtptKVJx\n"
+ b"CIDZ1/5KwPBk4vrnwOBtVMCftHj87MabBqV/nmQQrCiKTcJu4aQEDI9Qh\n"
+ b"yza09EJKvG8KkpnyuShtkP2LgkUxIqkjBg4DLV7grO+I+aG17QTuQxUTy\n"
+ b"icfYDBnzD4hTKPLf7d9KNyG+sEeyN0gceLFMUYaQ4lyapcSzYJwOSAc2B\n"
+ b"EU73tLaJlQORHL7HmhxrjD1IgZyxFjp/ofLVZFFoJAqjz2FWzOxmQw+bc\n"
+ b"0WTzQjeSTGx+l3htj7MmhIRBMqr3Um6zXkLKMCAwEAAaOCATAwggEsMB8\n"
+ b"GA1UdIwQYMBaAFCIXu6QtsiBVo1yZQZ7MMHTl5Wj6MEAGCCsGAQUFBwEB\n"
+ b"BDQwMjAwBggrBgEFBQcwAYYkaHR0cDovL2lwYS1jYS50ZXN0cmVhbG0ud\n"
+ b"GVzdC9jYS9vY3NwMA4GA1UdDwEB/wQEAwIE8DAdBgNVHSUEFjAUBggrBg\n"
+ b"EFBQcDAQYIKwYBBQUHAwIweQYDVR0fBHIwcDBuoDagNIYyaHR0cDovL2l\n"
+ b"wYS1jYS50ZXN0cmVhbG0udGVzdC9pcGEvY3JsL01hc3RlckNSTC5iaW6i\n"
+ b"NKQyMDAxDjAMBgNVBAoMBWlwYWNhMR4wHAYDVQQDDBVDZXJ0aWZpY2F0Z\n"
+ b"SBBdXRob3JpdHkwHQYDVR0OBBYEFNwQNQAG8MsKQPwMFyGzRiMzRAa5MA\n"
+ b"0GCSqGSIb3DQEBCwUAA4IBgQB2g0mS8XAPI+aRBa5q7Vbp1245CvMP0Eq\n"
+ b"Cz6gvCNwtxW0UDKnB++d/YQ13ft+x9Xj3rB/M2YXxdxTpQnQQv34CUcyh\n"
+ b"PQKJthAsbKBpdusCGrbS54zKFR0MjxwOwIIDHuI6eu2AoSpsmYs5UGzQm\n"
+ b"oCfQhbImK7iGLy0rOHaON1cWAFmC6lzJ2TFELc4N3eLYGVZy2ZtyZTgA3\n"
+ b"l97rBCwbDDFF1JWoOByIq8Ij99ksyMXws++sNUpo/1l8Jt0Gn6RBiidZB\n"
+ b"ef4+kJN+t6RAAwRQ / 3cmEggXcFoV13KZ70PeMXeX6CKMwXIwt3q7A78\n"
+ b"Wc/0OIBREZLhXpkmogCzWCuatdzeBIhMhx0vDEzaxlhf32ZWfN5pFMpgq\n"
+ b"wLZsdwMf6J65kGbE5Pg3Yxk7OiByxZJnR8UlvbU3r6RhMWutD6C0aqqNt\n"
+ b"o3us5gTmfRc8Mf1l/BUgDqkBKOTU8FHREGemG1HoklBym/Pbua0VMUA+s\n"
+ b"0nECR4LLM/o9PCJ2Y3QPBZy8Hg=\n"
+)
+
+
+class TestAPIScenario(IntegrationTest):
+ """
+ Tests for IDM API scenarios
+ """
+
+ topology = "line"
+
+ def create_and_run_script(self, filename, user_code_script):
+ self.master.put_file_contents(filename, user_code_script)
+ self.master.run_command(["python3", filename])
+ self.master.run_command(["rm", filename])
+
+ def test_idm_user_add(self):
+ """
+ This test checks that ipa user using api.Command["user_add"]
+ and then checks that user is displayed using
+ api.Command["user_show"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ api.Command["user_add"]("jsmith", givenname="John", sn="Smith",
+ ipauserauthtype="otp")
+ cmd = api.Command["user_show"]("jsmith", all=True)["result"]
+ assert 'otp' in cmd['ipauserauthtype']
+ assert 'John Smith' in cmd['cn']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/user_add.py", user_code_script
+ )
+
+ def test_idm_user_find(self):
+ """
+ This test checks that user is displayed
+ using api.Command["user_find"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["user_find"]("jsmith")
+ assert '1 user matched' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/user_find.py", user_code_script
+ )
+
+ def test_idm_user_mod(self):
+ """
+ This test checks that user attribute is modified
+ using api.Command["user_mod"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["user_mod"]("jsmith",
+ mail="jsmith@example.org")["result"]
+ assert 'jsmith@example.org' in cmd['mail']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/user_mod.py", user_code_script
+ )
+
+ def test_disable_user(self):
+ """
+ This test checks that user is disabled
+ using api.Command["user_disable"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["user_disable"]("jsmith")
+ assert 'Disabled user account "jsmith"' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/disable_user.py", user_code_script
+ )
+
+ def test_enable_user(self):
+ """
+ This test checks that user is enabled
+ using api.Command["user_enable"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["user_enable"]("jsmith")
+ assert 'Enabled user account "jsmith"' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/enable_user.py", user_code_script
+ )
+
+ def test_create_ipa_group(self):
+ """
+ This test checks that group is created
+ using api.Command["group_add"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["group_add"]("developers", gidnumber=500,
+ description="Developers")
+ assert 'Added group "developers"' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/create_group.py", user_code_script
+ )
+
+ def test_show_ipa_group(self):
+ """
+ This test checks that group is displayed
+ using api.Command["group_show"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["group_show"]("developers")
+ assert 'developers' in cmd['result']['cn']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/group_show.py", user_code_script
+ )
+
+ def test_ipa_group_mod(self):
+ """
+ This test checks that group description is modified
+ using api.Command["group_mod"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["group_mod"]("developers", description='developer')
+ ["result"]
+ assert 'Modified group "developers"' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/group_mod.py", user_code_script
+ )
+
+ def test_add_members_to_ipa_group(self):
+ """
+ This test checks that member is added to group
+ using api.Command["group_add_member"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["group_add_member"]("developers",
+ user='jsmith')["result"]
+ assert 'jsmith' in cmd['member_user']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/create_group_members.py", user_code_script
+ )
+
+ def test_ipa_group_find(self):
+ """
+ This test checks that group is displayed
+ using api.Command["group_find"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["group_find"]("developers")
+ assert '1 group matched' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/group_find.py", user_code_script
+ )
+
+ def test_remove_member_group(self):
+ """
+ This test checks that group member is removed
+ using api.Command["group_remove_member"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["group_remove_member"]("developers",
+ user="jsmith")
+ assert 'member_user' not in cmd
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/remove_member_group.py", user_code_script
+ )
+
+ def test_add_permission(self):
+ """
+ This test checks that permission is added
+ using api.Command["permission_add"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["permission_add"]("Create users",
+ ipapermright='add', type='user')
+ assert 'Added permission "Create users"' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/add_perm.py", user_code_script
+ )
+
+ def test_create_hbac_rule(self):
+ """
+ This test checks that hbac rule is added
+ using api.Command["hbacrule_add"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["hbacrule_add"]("sshd_rule")
+ assert 'Added HBAC rule "sshd_rule"' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/add_hbac_rule.py", user_code_script
+ )
+
+ def test_add_hbac_service(self):
+ """
+ This test checks that hbac service is added using
+ api.Command["hbacsvc_add"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["hbacsvc_add"]("chronyd")
+ assert 'Added HBAC service "chronyd"' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/add_hbac_svc.py", user_code_script
+ )
+
+ def test_enable_hbac_rule(self):
+ """
+ This test checks that hbac rule is enabled using
+ api.Command["hbacrule_enable"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["hbacrule_enable"]("sshd_rule")
+ assert 'Enabled HBAC rule "sshd_rule"' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/enable_hbacrule.py", user_code_script
+ )
+
+ def test_create_sudo_rule(self):
+ """
+ This test checks that sudo rule is created using
+ api.Command["sudorule_add"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["sudorule_add"]("timechange")
+ assert 'Added Sudo Rule "timechange"' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/create_sudos.py", user_code_script
+ )
+
+ def test_add_user_certificate(self):
+ """
+ This test checks user certificate is added using
+ api.Command["user_add_cert"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ msg = 'Added certificates to user "jsmith"'
+ cmd = api.Command["user_add_cert"]("jsmith", usercertificate={CERT})
+ assert msg in cmd["summary"]
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/add_cert.py", user_code_script
+ )
+
+ def test_remove_user_certificate(self):
+ """
+ This test checks that user certificate is removed
+ using api.Command["user_remove_cert"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ msg = 'Removed certificates from user "jsmith"'
+ cmd = api.Command["user_remove_cert"]("jsmith", usercertificate={CERT})
+ assert msg in cmd["summary"]
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/remove_cert.py", user_code_script
+ )
+
+ def test_certmaprule_add(self):
+ """
+ This test checks that certmap rule is added using
+ api.Command["certmaprule_add"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ msg = ('Added Certificate Identity Mapping Rule "testrule"')
+ cmd = api.Command["certmaprule_add"]("testrule")
+ assert msg in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/certmap_rule_add.py", user_code_script
+ )
+
+ def test_certmaprule_enable(self):
+ """
+ This test checks that certmap rule is enabled
+ using api.Command["certmaprule_enable"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ msg = ('Enabled Certificate Identity Mapping Rule "testrule"')
+ cmd = api.Command["certmaprule_enable"]("testrule")
+ assert msg in cmd["summary"]
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/certmap_rule_enable.py", user_code_script
+ )
+
+ def test_certmaprule_disable(self):
+ """
+ This test checks that certmap rule is disabled using
+ api.Command["certmaprule_disable"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ msg = ('Disabled Certificate Identity Mapping Rule "testrule"')
+ cmd = api.Command["certmaprule_disable"]("testrule")
+ assert msg in cmd["summary"]
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/certmap_rule_disable.py", user_code_script
+ )
+
+ def test_certmaprule_del(self):
+ """
+ This test checks that certmap rule is deleted using
+ api.Command["certmaprule_del"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ msg = ('Deleted Certificate Identity Mapping Rule "testrule"')
+ cmd = api.Command["certmaprule_del"]("testrule")
+ assert msg in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/certmap_rule_del.py", user_code_script
+ )
+
+ def test_add_role(self):
+ """
+ This test checks that role and privilege is added using
+ api.Command["role_add"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd1 = api.Command["role_add"]("junioradmin",
+ description="Junior admin")
+ assert 'Added role "junioradmin"' in cmd1["summary"]
+ cmd2 = api.Command.role_add_privilege("junioradmin",
+ privilege="Vault Administrators")["result"]
+ assert 'Vault Administrators' in cmd2["memberof_privilege"]
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/add_role.py", user_code_script
+ )
+
+ def test_add_subid(self):
+ """
+ This test checks that subid is added for IPA user
+ using api.Command["subid_add"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["subid_add"](ipaowner="jsmith")
+ assert 'Added subordinate id ' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/add_subid.py", user_code_script
+ )
+
+ def test_add_otptoken(self):
+ """
+ This test checks that otp token is added for IPA user
+ using api.Command["otptoken_add"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["otptoken_add"](
+ type='HOTP', description='testotp',
+ ipatokenotpalgorithm='sha512', ipatokenowner='jsmith',
+ ipatokenotpdigits='6')
+ assert 'Added OTP token' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/add_otptoken.py", user_code_script
+ )
+
+ def test_user_del(self):
+ """
+ This test checks that user is deleted
+ using api.Command["user_del"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["user_del"]("jsmith")
+ assert 'Deleted user "jsmith"' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/user_del.py", user_code_script
+ )
+
+ def test_remove_ipa_group(self):
+ """
+ This test checks that group is removed
+ using api.Command["group_del"]
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ cmd = api.Command["group_del"]("developers")
+ assert 'Deleted group "developers"' in cmd['summary']
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/show_group.py", user_code_script
+ )
+
+ def test_batch_command(self):
+ """
+ This test checks that batch commands
+ can be run using api.
+ """
+ user_code_script = textwrap.dedent(
+ f"""
+ {API_INIT}
+ batch_args = []
+ for i in range(5):
+ user_id = "user%i" % i
+ args = [user_id]
+ kw = {{'givenname' : user_id, 'sn' : user_id}}
+ batch_args.append({{'method' : 'user_add', 'params' : [args, kw]}})
+ api.Command["batch"](*batch_args)
+ """
+ )
+ self.create_and_run_script(
+ "/tmp/batch.py", user_code_script
+ )
--
2.41.0

View File

@ -0,0 +1,45 @@
From f816b4d9e6ff7a47b0da1a368d2454add78af07c Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Fri, 11 Aug 2023 09:10:30 +0200
Subject: [PATCH] ipatests: fixture can produce IndexError
The fixture issue_and_expire_acme_cert returns a function
that fills the hosts array. If the function is not called in
the test (for instance because a test is skipped, as in
TestACMEPrune::test_prune_cert_search_size_limit), hosts = []
and hosts[0] raises an IndexError.
Fix the fixture to check first that hosts is not empty.
Related: https://pagure.io/freeipa/issue/9348
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Mohammad Rizwan Yusuf <myusuf@redhat.com>
---
ipatests/test_integration/test_acme.py | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/ipatests/test_integration/test_acme.py b/ipatests/test_integration/test_acme.py
index c7389732cd067d49541cd04ea6687a6b95b4669f..bc989a9a2a00b0ac68b9dcffd4ccea269314961b 100644
--- a/ipatests/test_integration/test_acme.py
+++ b/ipatests/test_integration/test_acme.py
@@ -633,9 +633,13 @@ def issue_and_expire_acme_cert():
tasks.move_date(host, 'start', '-90days-60minutes')
# restart ipa services as date moved and wait to get things settle
- time.sleep(10)
- hosts[0].run_command(['ipactl', 'restart'])
- time.sleep(10)
+ # if the internal fixture was not called (for instance because the test
+ # was skipped), hosts = [] and hosts[0] would produce an IndexError
+ # exception.
+ if hosts:
+ time.sleep(10)
+ hosts[0].run_command(['ipactl', 'restart'])
+ time.sleep(10)
class TestACMERenew(IntegrationTest):
--
2.41.0

View File

@ -1,8 +1,7 @@
From f38eefd9f7e54470de7c707782114b17aac8762a Mon Sep 17 00:00:00 2001
From 4a62a21499a4884f0db55d01966a6ff532a4ed1e Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Aug 16 2023 15:25:34 +0000
Subject: Installer: activate nss and pam services in sssd.conf
Date: Mon, 14 Aug 2023 10:53:05 +0200
Subject: [PATCH] Installer: activate nss and pam services in sssd.conf
If there is already a sssd.conf file before the installer is
executed, the nss and pam services may not be enabled by the
@ -20,11 +19,12 @@ Fixes: https://pagure.io/freeipa/issue/9427
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
ipaclient/install/client.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/ipaclient/install/client.py b/ipaclient/install/client.py
index ef29a2c..07d62a7 100644
index ef29a2c8a3f673860cb22e0e6953853fd96a8572..07d62a748f77e990a38e28e3675abb05eef0da8d 100644
--- a/ipaclient/install/client.py
+++ b/ipaclient/install/client.py
@@ -969,6 +969,9 @@ def configure_sssd_conf(
@ -37,4 +37,6 @@ index ef29a2c..07d62a7 100644
domain.set_option('ipa_domain', cli_domain)
domain.set_option('ipa_hostname', client_hostname)
if cli_domain.lower() != cli_realm.lower():
--
2.41.0

View File

@ -0,0 +1,122 @@
From 363fd5de98e883800ac08b2760e8c3150783e7e2 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Fri, 6 Oct 2023 20:16:29 +0000
Subject: [PATCH 1/3] Check the HTTP Referer header on all requests
The referer was only checked in WSGIExecutioner classes:
- jsonserver
- KerberosWSGIExecutioner
- xmlserver
- jsonserver_kerb
This left /i18n_messages, /session/login_kerberos,
/session/login_x509, /session/login_password,
/session/change_password and /session/sync_token unprotected
against CSRF attacks.
CVE-2023-5455
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
(cherry picked from commit 63f76159b0fe5ab779206a28e07a49500fc1fdbe)
---
ipaserver/rpcserver.py | 34 +++++++++++++++++++++++++++++++---
1 file changed, 31 insertions(+), 3 deletions(-)
diff --git a/ipaserver/rpcserver.py b/ipaserver/rpcserver.py
index b7116469d..198fc9e7d 100644
--- a/ipaserver/rpcserver.py
+++ b/ipaserver/rpcserver.py
@@ -156,6 +156,19 @@ _success_template = """<html>
</html>"""
class HTTP_Status(plugable.Plugin):
+ def check_referer(self, environ):
+ if "HTTP_REFERER" not in environ:
+ logger.error("Rejecting request with missing Referer")
+ return False
+ if (not environ["HTTP_REFERER"].startswith(
+ "https://%s/ipa" % self.api.env.host)
+ and not self.env.in_tree):
+ logger.error("Rejecting request with bad Referer %s",
+ environ["HTTP_REFERER"])
+ return False
+ logger.debug("Valid Referer %s", environ["HTTP_REFERER"])
+ return True
+
def not_found(self, environ, start_response, url, message):
"""
Return a 404 Not Found error.
@@ -331,9 +344,6 @@ class wsgi_dispatch(Executioner, HTTP_Status):
self.__apps[key] = app
-
-
-
class WSGIExecutioner(Executioner):
"""
Base class for execution backends with a WSGI application interface.
@@ -898,6 +908,9 @@ class jsonserver_session(jsonserver, KerberosSession):
logger.debug('WSGI jsonserver_session.__call__:')
+ if not self.check_referer(environ):
+ return self.bad_request(environ, start_response, 'denied')
+
# Redirect to login if no Kerberos credentials
ccache_name = self.get_environ_creds(environ)
if ccache_name is None:
@@ -950,6 +963,9 @@ class KerberosLogin(Backend, KerberosSession):
def __call__(self, environ, start_response):
logger.debug('WSGI KerberosLogin.__call__:')
+ if not self.check_referer(environ):
+ return self.bad_request(environ, start_response, 'denied')
+
# Redirect to login if no Kerberos credentials
user_ccache_name = self.get_environ_creds(environ)
if user_ccache_name is None:
@@ -968,6 +984,9 @@ class login_x509(KerberosLogin):
def __call__(self, environ, start_response):
logger.debug('WSGI login_x509.__call__:')
+ if not self.check_referer(environ):
+ return self.bad_request(environ, start_response, 'denied')
+
if 'KRB5CCNAME' not in environ:
return self.unauthorized(
environ, start_response, 'KRB5CCNAME not set',
@@ -1016,6 +1035,9 @@ class login_password(Backend, KerberosSession):
logger.debug('WSGI login_password.__call__:')
+ if not self.check_referer(environ):
+ return self.bad_request(environ, start_response, 'denied')
+
# Get the user and password parameters from the request
content_type = environ.get('CONTENT_TYPE', '').lower()
if not content_type.startswith('application/x-www-form-urlencoded'):
@@ -1148,6 +1170,9 @@ class change_password(Backend, HTTP_Status):
def __call__(self, environ, start_response):
logger.info('WSGI change_password.__call__:')
+ if not self.check_referer(environ):
+ return self.bad_request(environ, start_response, 'denied')
+
# Get the user and password parameters from the request
content_type = environ.get('CONTENT_TYPE', '').lower()
if not content_type.startswith('application/x-www-form-urlencoded'):
@@ -1365,6 +1390,9 @@ class xmlserver_session(xmlserver, KerberosSession):
logger.debug('WSGI xmlserver_session.__call__:')
+ if not self.check_referer(environ):
+ return self.bad_request(environ, start_response, 'denied')
+
ccache_name = environ.get('KRB5CCNAME')
# Redirect to /ipa/xml if no Kerberos credentials
--
2.27.0

View File

@ -0,0 +1,360 @@
From 48ec350051ead9c17e58a91405b3ab6935347f1b Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Thu, 12 Oct 2023 20:34:01 +0000
Subject: [PATCH 2/3] Integration tests for verifying Referer header in the UI
Validate that the change_password and login_password endpoints
verify the HTTP Referer header. There is some overlap in the
tests: belt and suspenders.
All endpoints except session/login_x509 are covered, sometimes
having to rely on expected bad results (see the i18n endpoint).
session/login_x509 is not tested yet as it requires significant
additional setup in order to associate a user certificate with
a user entry, etc.
This can be manually verified by modifying /etc/httpd/conf.d/ipa.conf
and adding:
Satisfy Any
Require all granted
Then comment out Auth and SSLVerify, etc. and restart httpd.
With a valid Referer will fail with a 401 and log that there is no
KRB5CCNAME. This comes after the referer check.
With an invalid Referer it will fail with a 400 Bad Request as
expected.
CVE-2023-5455
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
(cherry picked from commit ef158764a97490211b9fe2e53f40826c3acfb19b)
---
ipatests/test_ipaserver/httptest.py | 7 +-
ipatests/test_ipaserver/test_changepw.py | 12 +-
.../test_ipaserver/test_login_password.py | 88 ++++++++++++
ipatests/test_ipaserver/test_referer.py | 136 ++++++++++++++++++
ipatests/util.py | 4 +-
5 files changed, 242 insertions(+), 5 deletions(-)
create mode 100644 ipatests/test_ipaserver/test_login_password.py
create mode 100644 ipatests/test_ipaserver/test_referer.py
diff --git a/ipatests/test_ipaserver/httptest.py b/ipatests/test_ipaserver/httptest.py
index 6cd034a71..8924798fc 100644
--- a/ipatests/test_ipaserver/httptest.py
+++ b/ipatests/test_ipaserver/httptest.py
@@ -36,7 +36,7 @@ class Unauthorized_HTTP_test:
content_type = 'application/x-www-form-urlencoded'
accept_language = 'en-us'
- def send_request(self, method='POST', params=None):
+ def send_request(self, method='POST', params=None, host=None):
"""
Send a request to HTTP server
@@ -45,7 +45,10 @@ class Unauthorized_HTTP_test:
if params is not None:
if self.content_type == 'application/x-www-form-urlencoded':
params = urllib.parse.urlencode(params, True)
- url = 'https://' + self.host + self.app_uri
+ if host:
+ url = 'https://' + host + self.app_uri
+ else:
+ url = 'https://' + self.host + self.app_uri
headers = {'Content-Type': self.content_type,
'Accept-Language': self.accept_language,
diff --git a/ipatests/test_ipaserver/test_changepw.py b/ipatests/test_ipaserver/test_changepw.py
index c3a47ab26..df38ddb3d 100644
--- a/ipatests/test_ipaserver/test_changepw.py
+++ b/ipatests/test_ipaserver/test_changepw.py
@@ -53,10 +53,11 @@ class test_changepw(XMLRPC_test, Unauthorized_HTTP_test):
request.addfinalizer(fin)
- def _changepw(self, user, old_password, new_password):
+ def _changepw(self, user, old_password, new_password, host=None):
return self.send_request(params={'user': str(user),
'old_password' : str(old_password),
'new_password' : str(new_password)},
+ host=host
)
def _checkpw(self, user, password):
@@ -89,6 +90,15 @@ class test_changepw(XMLRPC_test, Unauthorized_HTTP_test):
# make sure that password is NOT changed
self._checkpw(testuser, old_password)
+ def test_invalid_referer(self):
+ response = self._changepw(testuser, old_password, new_password,
+ 'attacker.test')
+
+ assert_equal(response.status, 400)
+
+ # make sure that password is NOT changed
+ self._checkpw(testuser, old_password)
+
def test_pwpolicy_error(self):
response = self._changepw(testuser, old_password, '1')
diff --git a/ipatests/test_ipaserver/test_login_password.py b/ipatests/test_ipaserver/test_login_password.py
new file mode 100644
index 000000000..9425cb797
--- /dev/null
+++ b/ipatests/test_ipaserver/test_login_password.py
@@ -0,0 +1,88 @@
+# Copyright (C) 2023 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import pytest
+import uuid
+
+from ipatests.test_ipaserver.httptest import Unauthorized_HTTP_test
+from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test
+from ipatests.util import assert_equal
+from ipalib import api, errors
+from ipapython.ipautil import run
+
+testuser = u'tuser'
+password = u'password'
+
+
+@pytest.mark.tier1
+class test_login_password(XMLRPC_test, Unauthorized_HTTP_test):
+ app_uri = '/ipa/session/login_password'
+
+ @pytest.fixture(autouse=True)
+ def login_setup(self, request):
+ ccache = os.path.join('/tmp', str(uuid.uuid4()))
+ try:
+ api.Command['user_add'](uid=testuser, givenname=u'Test', sn=u'User')
+ api.Command['passwd'](testuser, password=password)
+ run(['kinit', testuser], stdin='{0}\n{0}\n{0}\n'.format(password),
+ env={"KRB5CCNAME": ccache})
+ except errors.ExecutionError as e:
+ pytest.skip(
+ 'Cannot set up test user: %s' % e
+ )
+
+ def fin():
+ try:
+ api.Command['user_del']([testuser])
+ except errors.NotFound:
+ pass
+ os.unlink(ccache)
+
+ request.addfinalizer(fin)
+
+ def _login(self, user, password, host=None):
+ return self.send_request(params={'user': str(user),
+ 'password' : str(password)},
+ host=host)
+
+ def test_bad_options(self):
+ for params in (
+ None, # no params
+ {"user": "foo"}, # missing options
+ {"user": "foo", "password": ""}, # empty option
+ ):
+ response = self.send_request(params=params)
+ assert_equal(response.status, 400)
+ assert_equal(response.reason, 'Bad Request')
+
+ def test_invalid_auth(self):
+ response = self._login(testuser, 'wrongpassword')
+
+ assert_equal(response.status, 401)
+ assert_equal(response.getheader('X-IPA-Rejection-Reason'),
+ 'invalid-password')
+
+ def test_invalid_referer(self):
+ response = self._login(testuser, password, 'attacker.test')
+
+ assert_equal(response.status, 400)
+
+ def test_success(self):
+ response = self._login(testuser, password)
+
+ assert_equal(response.status, 200)
+ assert response.getheader('X-IPA-Rejection-Reason') is None
diff --git a/ipatests/test_ipaserver/test_referer.py b/ipatests/test_ipaserver/test_referer.py
new file mode 100644
index 000000000..4eade8bba
--- /dev/null
+++ b/ipatests/test_ipaserver/test_referer.py
@@ -0,0 +1,136 @@
+# Copyright (C) 2023 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import pytest
+import uuid
+
+from ipatests.test_ipaserver.httptest import Unauthorized_HTTP_test
+from ipatests.test_xmlrpc.xmlrpc_test import XMLRPC_test
+from ipatests.util import assert_equal
+from ipalib import api, errors
+from ipapython.ipautil import run
+
+testuser = u'tuser'
+password = u'password'
+
+
+@pytest.mark.tier1
+class test_referer(XMLRPC_test, Unauthorized_HTTP_test):
+
+ @pytest.fixture(autouse=True)
+ def login_setup(self, request):
+ ccache = os.path.join('/tmp', str(uuid.uuid4()))
+ tokenid = None
+ try:
+ api.Command['user_add'](uid=testuser, givenname=u'Test', sn=u'User')
+ api.Command['passwd'](testuser, password=password)
+ run(['kinit', testuser], stdin='{0}\n{0}\n{0}\n'.format(password),
+ env={"KRB5CCNAME": ccache})
+ result = api.Command["otptoken_add"](
+ type='HOTP', description='testotp',
+ ipatokenotpalgorithm='sha512', ipatokenowner=testuser,
+ ipatokenotpdigits='6')
+ tokenid = result['result']['ipatokenuniqueid'][0]
+ except errors.ExecutionError as e:
+ pytest.skip(
+ 'Cannot set up test user: %s' % e
+ )
+
+ def fin():
+ try:
+ api.Command['user_del']([testuser])
+ api.Command['otptoken_del']([tokenid])
+ except errors.NotFound:
+ pass
+ os.unlink(ccache)
+
+ request.addfinalizer(fin)
+
+ def _request(self, params={}, host=None):
+ # implicit is that self.app_uri is set to the appropriate value
+ return self.send_request(params=params, host=host)
+
+ def test_login_password_valid(self):
+ """Valid authentication of a user"""
+ self.app_uri = "/ipa/session/login_password"
+ response = self._request(
+ params={'user': 'tuser', 'password': password})
+ assert_equal(response.status, 200, self.app_uri)
+
+ def test_change_password_valid(self):
+ """This actually changes the user password"""
+ self.app_uri = "/ipa/session/change_password"
+ response = self._request(
+ params={'user': 'tuser',
+ 'old_password': password,
+ 'new_password': 'new_password'}
+ )
+ assert_equal(response.status, 200, self.app_uri)
+
+ def test_sync_token_valid(self):
+ """We aren't testing that sync works, just that we can get there"""
+ self.app_uri = "/ipa/session/sync_token"
+ response = self._request(
+ params={'user': 'tuser',
+ 'first_code': '1234',
+ 'second_code': '5678',
+ 'password': 'password'})
+ assert_equal(response.status, 200, self.app_uri)
+
+ def test_i18n_messages_valid(self):
+ # i18n_messages requires a valid JSON request and we send
+ # nothing. If we get a 500 error then it got past the
+ # referer check.
+ self.app_uri = "/ipa/i18n_messages"
+ response = self._request()
+ assert_equal(response.status, 500, self.app_uri)
+
+ # /ipa/session/login_x509 is not tested yet as it requires
+ # significant additional setup.
+ # This can be manually verified by adding
+ # Satisfy Any and Require all granted to the configuration
+ # section and comment out all Auth directives. The request
+ # will fail and log that there is no KRB5CCNAME which comes
+ # after the referer check.
+
+ def test_endpoints_auth_required(self):
+ """Test endpoints that require pre-authorization which will
+ fail before we even get to the Referer check
+ """
+ self.endpoints = {
+ "/ipa/xml",
+ "/ipa/session/login_kerberos",
+ "/ipa/session/json",
+ "/ipa/session/xml"
+ }
+ for self.app_uri in self.endpoints:
+ response = self._request(host="attacker.test")
+
+ # referer is checked after auth
+ assert_equal(response.status, 401, self.app_uri)
+
+ def notest_endpoints_invalid(self):
+ """Pass in a bad Referer, expect a 400 Bad Request"""
+ self.endpoints = {
+ "/ipa/session/login_password",
+ "/ipa/session/change_password",
+ "/ipa/session/sync_token",
+ }
+ for self.app_uri in self.endpoints:
+ response = self._request(host="attacker.test")
+
+ assert_equal(response.status, 400, self.app_uri)
diff --git a/ipatests/util.py b/ipatests/util.py
index 929c3e899..61af0c40d 100644
--- a/ipatests/util.py
+++ b/ipatests/util.py
@@ -163,12 +163,12 @@ class ExceptionNotRaised(Exception):
return self.msg % self.expected.__name__
-def assert_equal(val1, val2):
+def assert_equal(val1, val2, msg=''):
"""
Assert ``val1`` and ``val2`` are the same type and of equal value.
"""
assert type(val1) is type(val2), '%r != %r' % (val1, val2)
- assert val1 == val2, '%r != %r' % (val1, val2)
+ assert val1 == val2, '%r != %r %r' % (val1, val2, msg)
def assert_not_equal(val1, val2):
--
2.27.0

View File

@ -0,0 +1,39 @@
From f123b01d81696c52e9a4008d46e549864e4a8069 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Wed, 3 May 2023 10:47:19 +0300
Subject: [PATCH] updates: add ACIs for RBCD self-management
Fixes: https://pagure.io/freeipa/issue/9354
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Julien Rische <jrische@redhat.com>
---
install/updates/73-service-rbcd.update | 5 +++++
install/updates/Makefile.am | 1 +
2 files changed, 6 insertions(+)
create mode 100644 install/updates/73-service-rbcd.update
diff --git a/install/updates/73-service-rbcd.update b/install/updates/73-service-rbcd.update
new file mode 100644
index 00000000000..08a8b0f84a7
--- /dev/null
+++ b/install/updates/73-service-rbcd.update
@@ -0,0 +1,5 @@
+dn: $SUFFIX
+add:aci: (targetattr = "memberPrincipal")(targattrfilters="add=objectclass:(objectclass=resourcedelegation)")(version 3.0;acl "permission:RBCD:Kerberos principals can manage resource-based constrained delegation for themselves";allow (write) userdn = "ldap:///self";)
+add:aci: (targetattr = "memberPrincipal")(targattrfilters="add=objectclass:(objectclass=resourcedelegation)")(version 3.0;acl "permission:RBCD:Managing principals can manage resource-based constrained delegation for other principals";allow (write) userattr = "managedby#GROUPDN" or userattr = "managedby#USERDN";)
+add:aci: (targetattr = "memberPrincipal")(targattrfilters="add=objectclass:(objectclass=resourcedelegation)")(version 3.0;acl "permission:RBCD:Delegated permission to manage resource-based constrained delegation for other principals";allow (write) userattr="ipaAllowedToPerform;write_delegation#GROUPDN" or userattr="ipaAllowedToPerform;write_delegation#USERDN" ;)
+
diff --git a/install/updates/Makefile.am b/install/updates/Makefile.am
index fbc1b76ae4e..fd96831d8fd 100644
--- a/install/updates/Makefile.am
+++ b/install/updates/Makefile.am
@@ -66,6 +66,7 @@ app_DATA = \
73-subid.update \
73-winsync.update \
73-certmap.update \
+ 73-service-rbcd.update \
75-user-trust-attributes.update \
80-schema_compat.update \
81-externalmembers.update \

View File

@ -0,0 +1,33 @@
From 2bbfd1454fc69c5975826d1a3f39b301d135abb5 Mon Sep 17 00:00:00 2001
From: Mohammad Rizwan <myusuf@redhat.com>
Date: Sep 20 2023 06:05:00 +0000
Subject: ipatests: restart ipa services after moving date
When system date is moved into future, it have unprecedented
behavior i.e CA becomes irresponsive or unexpected certificcate
state. Hence restart the ipa service after moving the date to
gracefully serve the request.
Fixes: https://pagure.io/freeipa/issue/9379
Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
diff --git a/ipatests/test_integration/test_ipa_cert_fix.py b/ipatests/test_integration/test_ipa_cert_fix.py
index 77076e7..ec9456e 100644
--- a/ipatests/test_integration/test_ipa_cert_fix.py
+++ b/ipatests/test_integration/test_ipa_cert_fix.py
@@ -408,6 +408,9 @@ class TestCertFixReplica(IntegrationTest):
# move system date to expire certs
for host in self.master, self.replicas[0]:
tasks.move_date(host, 'stop', '+3years+1days')
+ host.run_command(
+ ['ipactl', 'restart', '--ignore-service-failures']
+ )
yield

View File

@ -0,0 +1,127 @@
From 9bc582a2d78fd3ff9e70fa927b87ab06dcb7c9ae Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Nov 17 2023 09:08:44 +0000
Subject: ipatests: ignore nsslapd-accesslog-logbuffering WARN in healthcheck
Log buffering is disabled in the integration tests so we can have all
the logs at the end. This is causing a warning to show in the 389-ds
checks and causing tests to fail that expect all SUCCESS.
Add an exclude for this specific key so tests will pass again.
We may eventually want a more sophisiticated mechanism to handle
excludes, or updating the config in general, but this is fine for now.
Fixes: https://pagure.io/freeipa/issue/9400
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
---
diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py
index 5d79f2b..278f75a 100644
--- a/ipatests/test_integration/test_ipahealthcheck.py
+++ b/ipatests/test_integration/test_ipahealthcheck.py
@@ -10,6 +10,7 @@ from __future__ import absolute_import
from configparser import RawConfigParser, NoOptionError
from datetime import datetime, timedelta
+import io
import json
import os
import re
@@ -209,6 +210,28 @@ def run_healthcheck(host, source=None, check=None, output_type="json",
return result.returncode, data
+def set_excludes(host, option, value,
+ config_file='/etc/ipahealthcheck/ipahealthcheck.conf'):
+ """Mark checks that should be excluded from the results
+
+ This will set in the [excludes] section on host:
+ option=value
+ """
+ EXCLUDES = "excludes"
+
+ conf = host.get_file_contents(config_file, encoding='utf-8')
+ cfg = RawConfigParser()
+ cfg.read_string(conf)
+ if not cfg.has_section(EXCLUDES):
+ cfg.add_section(EXCLUDES)
+ if not cfg.has_option(EXCLUDES, option):
+ cfg.set(EXCLUDES, option, value)
+ out = io.StringIO()
+ cfg.write(out)
+ out.seek(0)
+ host.put_file_contents(config_file, out.read())
+
+
@pytest.fixture
def restart_service():
"""Shut down and restart a service as a fixture"""
@@ -266,6 +289,7 @@ class TestIpaHealthCheck(IntegrationTest):
setup_dns=True,
extra_args=['--no-dnssec-validation']
)
+ set_excludes(cls.master, "key", "DSCLE0004")
def test_ipa_healthcheck_install_on_master(self):
"""
@@ -558,6 +582,7 @@ class TestIpaHealthCheck(IntegrationTest):
setup_dns=True,
extra_args=['--no-dnssec-validation']
)
+ set_excludes(self.replicas[0], "key", "DSCLE0004")
# Init a user on replica to assign a DNA range
tasks.kinit_admin(self.replicas[0])
@@ -698,6 +723,7 @@ class TestIpaHealthCheck(IntegrationTest):
'output_type=human'
])
)
+ set_excludes(self.master, "key", "DSCLE0004", config_file)
returncode, output = run_healthcheck(
self.master, failures_only=True, config=config_file
)
@@ -713,6 +739,7 @@ class TestIpaHealthCheck(IntegrationTest):
'output_file=%s' % HC_LOG,
])
)
+ set_excludes(self.master, "key", "DSCLE0004")
returncode, _unused = run_healthcheck(
self.master, config=config_file
)
@@ -2408,6 +2435,7 @@ class TestIpaHealthCLI(IntegrationTest):
cls.master, setup_dns=True, extra_args=['--no-dnssec-validation']
)
tasks.install_packages(cls.master, HEALTHCHECK_PKG)
+ set_excludes(cls.master, "key", "DSCLE0004")
def test_indent(self):
"""
diff --git a/ipatests/test_integration/test_replica_promotion.py b/ipatests/test_integration/test_replica_promotion.py
index d477c3a..b71f2d5 100644
--- a/ipatests/test_integration/test_replica_promotion.py
+++ b/ipatests/test_integration/test_replica_promotion.py
@@ -13,7 +13,7 @@ import pytest
from ipatests.test_integration.base import IntegrationTest
from ipatests.test_integration.test_ipahealthcheck import (
- run_healthcheck, HEALTHCHECK_PKG
+ run_healthcheck, set_excludes, HEALTHCHECK_PKG
)
from ipatests.pytest_ipa.integration import tasks
from ipatests.pytest_ipa.integration.tasks import (
@@ -983,6 +983,9 @@ class TestHiddenReplicaPromotion(IntegrationTest):
# manually install KRA to verify that hidden state is synced
tasks.install_kra(cls.replicas[0])
+ set_excludes(cls.master, "key", "DSCLE0004")
+ set_excludes(cls.replicas[0], "key", "DSCLE0004")
+
def _check_dnsrecords(self, hosts_expected, hosts_unexpected=()):
domain = DNSName(self.master.domain.name).make_absolute()
rset = [

View File

@ -0,0 +1,44 @@
From 96dd277ad960f57c36c38820a7b0542c97f9e67d Mon Sep 17 00:00:00 2001
From: Sudhir Menon <sumenon@redhat.com>
Date: Jan 11 2024 22:26:57 +0000
Subject: ipatests: Skip ds_encryption tests on RHEL9 SUT.
test_ipahealthcheck_ds_encryption tests are failing
in RHEL9 SUT because in this test tls protocol version
is set to TLS1.0 using the below command, but its
reset to TLS1.2 causing the test to fail.
'dsconf', 'slapd-TESTREALM-TEST', 'security', 'set', '--tls-protocol-min=TLS1.0'
Hence the test is skipped to be run on RHEL9.0 SUT.
Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
diff --git a/ipatests/test_integration/test_ipahealthcheck.py b/ipatests/test_integration/test_ipahealthcheck.py
index 785e9ab..40c8489 100644
--- a/ipatests/test_integration/test_ipahealthcheck.py
+++ b/ipatests/test_integration/test_ipahealthcheck.py
@@ -158,7 +158,6 @@ TOMCAT_CONFIG_FILES = (
paths.CA_CS_CFG_PATH,
)
-
def run_healthcheck(host, source=None, check=None, output_type="json",
failures_only=False, config=None):
"""
@@ -1262,6 +1261,10 @@ class TestIpaHealthCheck(IntegrationTest):
)
self.master.run_command(cmd)
+ @pytest.mark.skipif((osinfo.id == 'rhel'
+ and osinfo.version_number >= (9,0)),
+ reason=" TLS versions below 1.2 are not "
+ "supported anymore in RHEL9.0 and above.")
def test_ipahealthcheck_ds_encryption(self, modify_tls):
"""
This testcase modifies the default TLS version of

View File

@ -0,0 +1,32 @@
From 3baa30ad3f6ee563089839a5ef56d5ac6eb43959 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Jan 18 2024 09:05:30 +0000
Subject: adtrustinstance: make sure NetBIOS name defaults are set properly
Some tools may pass None as NetBIOS name if not put explicitly by a
user. This meant to use default NetBIOS name generator based on the
domain (realm) name. However, this wasn't done properly, so None is
passed later to python-ldap and it rejects such LDAP entry.
Fixes: https://pagure.io/freeipa/issue/9514
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py
index d55ba84..2ff68df 100644
--- a/ipaserver/install/adtrustinstance.py
+++ b/ipaserver/install/adtrustinstance.py
@@ -189,6 +189,8 @@ class ADTRUSTInstance(service.Service):
self.fqdn = self.fqdn or api.env.host
self.host_netbios_name = make_netbios_name(self.fqdn)
self.realm = self.realm or api.env.realm
+ if not self.netbios_name:
+ self.netbios_name = make_netbios_name(self.realm)
self.suffix = ipautil.realm_to_suffix(self.realm)
self.ldapi_socket = "%%2fvar%%2frun%%2fslapd-%s.socket" % \

View File

@ -0,0 +1,40 @@
From 257b2b470b4e3f83a0cbc476d54dc74ddf2cf311 Mon Sep 17 00:00:00 2001
From: Masahiro Matsuya <mmatsuya@redhat.com>
Date: Jan 24 2024 16:42:45 +0000
Subject: ipatests: wait for replica update in test_dns_locations
test_ipa_ca_records and test_adtrust_system_records can fail with
NXDOMAIN, because it doesn't wait enough for the update on replica.
It can be resolved by waiting for the update with wait_for_replication.
Fixes: https://pagure.io/freeipa/issue/9504
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
diff --git a/ipatests/test_integration/test_dns_locations.py b/ipatests/test_integration/test_dns_locations.py
index 44900af..89a3108 100644
--- a/ipatests/test_integration/test_dns_locations.py
+++ b/ipatests/test_integration/test_dns_locations.py
@@ -534,6 +534,9 @@ class TestDNSLocations(IntegrationTest):
expected_servers = (self.master.ip, self.replicas[1].ip)
+ ldap = self.master.ldap_connect()
+ tasks.wait_for_replication(ldap)
+
for ip in (self.master.ip, self.replicas[0].ip, self.replicas[1].ip):
self._test_A_rec_against_server(ip, self.domain, expected_servers)
@@ -557,6 +560,9 @@ class TestDNSLocations(IntegrationTest):
(self.PRIO_HIGH, self.WEIGHT, DNSName(self.master.hostname)),
)
+ ldap = self.master.ldap_connect()
+ tasks.wait_for_replication(ldap)
+
for ip in (self.master.ip, self.replicas[0].ip, self.replicas[1].ip):
self._test_SRV_rec_against_server(
ip, self.domain, expected_servers,

View File

@ -0,0 +1,142 @@
From 2e649b26d1d8ec988ec64477af73cd1f033731fd Mon Sep 17 00:00:00 2001
From: Stanislav Levin <slev@altlinux.org>
Date: Jan 30 2024 15:07:56 +0000
Subject: ipapython: Clean up krb5_error
`krb5_error` has different definition in MIT krb.
https://web.mit.edu/kerberos/krb5-latest/doc/appdev/refs/types/krb5_error.html
> Error message structure.
>
> Declaration:
> typedef struct _krb5_error krb5_error
While `krb5_error_code`
https://web.mit.edu/kerberos/www/krb5-latest/doc/appdev/refs/types/krb5_error_code.html#c.krb5_error_code
> krb5_error_code
> Used to convey an operation status.
>
> The value 0 indicates success; any other values are com_err codes. Use krb5_get_error_message() to obtain a string describing the error.
>
> Declaration
> typedef krb5_int32 krb5_error_code
And this is what was actually used.
To prevent confusion of types `krb5_error` was replaced with
`krb5_error_code`.
Fixes: https://pagure.io/freeipa/issue/9519
Signed-off-by: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py
index c43ef7d..371cf15 100644
--- a/ipapython/session_storage.py
+++ b/ipapython/session_storage.py
@@ -111,7 +111,7 @@ class KRB5Error(Exception):
def krb5_errcheck(result, func, arguments):
- """Error checker for krb5_error return value"""
+ """Error checker for krb5_error_code return value"""
if result != 0:
raise KRB5Error(result, func.__name__, arguments)
@@ -119,14 +119,13 @@ def krb5_errcheck(result, func, arguments):
krb5_context = ctypes.POINTER(_krb5_context)
krb5_ccache = ctypes.POINTER(_krb5_ccache)
krb5_data_p = ctypes.POINTER(_krb5_data)
-krb5_error = ctypes.c_int32
krb5_creds = _krb5_creds
krb5_pointer = ctypes.c_void_p
krb5_cc_cursor = krb5_pointer
krb5_init_context = LIBKRB5.krb5_init_context
krb5_init_context.argtypes = (ctypes.POINTER(krb5_context), )
-krb5_init_context.restype = krb5_error
+krb5_init_context.restype = krb5_error_code
krb5_init_context.errcheck = krb5_errcheck
krb5_free_context = LIBKRB5.krb5_free_context
@@ -143,30 +142,30 @@ krb5_free_data_contents.restype = None
krb5_cc_default = LIBKRB5.krb5_cc_default
krb5_cc_default.argtypes = (krb5_context, ctypes.POINTER(krb5_ccache), )
-krb5_cc_default.restype = krb5_error
+krb5_cc_default.restype = krb5_error_code
krb5_cc_default.errcheck = krb5_errcheck
krb5_cc_close = LIBKRB5.krb5_cc_close
krb5_cc_close.argtypes = (krb5_context, krb5_ccache, )
-krb5_cc_close.restype = krb5_error
+krb5_cc_close.restype = krb5_error_code
krb5_cc_close.errcheck = krb5_errcheck
krb5_parse_name = LIBKRB5.krb5_parse_name
krb5_parse_name.argtypes = (krb5_context, ctypes.c_char_p,
ctypes.POINTER(krb5_principal), )
-krb5_parse_name.restype = krb5_error
+krb5_parse_name.restype = krb5_error_code
krb5_parse_name.errcheck = krb5_errcheck
krb5_cc_set_config = LIBKRB5.krb5_cc_set_config
krb5_cc_set_config.argtypes = (krb5_context, krb5_ccache, krb5_principal,
ctypes.c_char_p, krb5_data_p, )
-krb5_cc_set_config.restype = krb5_error
+krb5_cc_set_config.restype = krb5_error_code
krb5_cc_set_config.errcheck = krb5_errcheck
krb5_cc_get_principal = LIBKRB5.krb5_cc_get_principal
krb5_cc_get_principal.argtypes = (krb5_context, krb5_ccache,
ctypes.POINTER(krb5_principal), )
-krb5_cc_get_principal.restype = krb5_error
+krb5_cc_get_principal.restype = krb5_error_code
krb5_cc_get_principal.errcheck = krb5_errcheck
# krb5_build_principal is a variadic function but that can't be expressed
@@ -177,26 +176,26 @@ krb5_build_principal.argtypes = (krb5_context, ctypes.POINTER(krb5_principal),
ctypes.c_uint, ctypes.c_char_p,
ctypes.c_char_p, ctypes.c_char_p,
ctypes.c_char_p, ctypes.c_char_p, )
-krb5_build_principal.restype = krb5_error
+krb5_build_principal.restype = krb5_error_code
krb5_build_principal.errcheck = krb5_errcheck
krb5_cc_start_seq_get = LIBKRB5.krb5_cc_start_seq_get
krb5_cc_start_seq_get.argtypes = (krb5_context, krb5_ccache,
ctypes.POINTER(krb5_cc_cursor), )
-krb5_cc_start_seq_get.restype = krb5_error
+krb5_cc_start_seq_get.restype = krb5_error_code
krb5_cc_start_seq_get.errcheck = krb5_errcheck
krb5_cc_next_cred = LIBKRB5.krb5_cc_next_cred
krb5_cc_next_cred.argtypes = (krb5_context, krb5_ccache,
ctypes.POINTER(krb5_cc_cursor),
ctypes.POINTER(krb5_creds), )
-krb5_cc_next_cred.restype = krb5_error
+krb5_cc_next_cred.restype = krb5_error_code
krb5_cc_next_cred.errcheck = krb5_errcheck
krb5_cc_end_seq_get = LIBKRB5.krb5_cc_end_seq_get
krb5_cc_end_seq_get.argtypes = (krb5_context, krb5_ccache,
ctypes.POINTER(krb5_cc_cursor), )
-krb5_cc_end_seq_get.restype = krb5_error
+krb5_cc_end_seq_get.restype = krb5_error_code
krb5_cc_end_seq_get.errcheck = krb5_errcheck
krb5_free_cred_contents = LIBKRB5.krb5_free_cred_contents
@@ -212,7 +211,7 @@ krb5_principal_compare.restype = krb5_boolean
krb5_unparse_name = LIBKRB5.krb5_unparse_name
krb5_unparse_name.argtypes = (krb5_context, krb5_principal,
ctypes.POINTER(ctypes.c_char_p), )
-krb5_unparse_name.restype = krb5_error
+krb5_unparse_name.restype = krb5_error_code
krb5_unparse_name.errcheck = krb5_errcheck
krb5_free_unparsed_name = LIBKRB5.krb5_free_unparsed_name

View File

@ -0,0 +1,45 @@
From 59f010774d13ea6a0148235db2ff05a3f3c93c7b Mon Sep 17 00:00:00 2001
From: Stanislav Levin <slev@altlinux.org>
Date: Jan 30 2024 15:07:56 +0000
Subject: ipapython: Correct return type of krb5_free_cred_contents
According to https://web.mit.edu/kerberos/krb5-latest/doc/appdev/refs/api/krb5_free_cred_contents.html
> krb5_free_cred_contents - Free the contents of a krb5_creds structure.
>
> void krb5_free_cred_contents(krb5_context context, krb5_creds * val)
> param:
> [in] context - Library context
>
> [in] val - Credential structure to free contents of
>
> This function frees the contents of val , but not the structure itself.
https://github.com/krb5/krb5/blob/5b00197227231943bd2305328c8260dd0b0dbcf0/src/lib/krb5/krb/kfree.c#L166
This leads to undefined behavior and `krb5_free_cred_contents` can
raise KRB5Error (because of garbage data) while actually its foreign
function doesn't.
Fixes: https://pagure.io/freeipa/issue/9519
Signed-off-by: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py
index 371cf15..dc36f54 100644
--- a/ipapython/session_storage.py
+++ b/ipapython/session_storage.py
@@ -200,8 +200,7 @@ krb5_cc_end_seq_get.errcheck = krb5_errcheck
krb5_free_cred_contents = LIBKRB5.krb5_free_cred_contents
krb5_free_cred_contents.argtypes = (krb5_context, ctypes.POINTER(krb5_creds))
-krb5_free_cred_contents.restype = krb5_error
-krb5_free_cred_contents.errcheck = krb5_errcheck
+krb5_free_cred_contents.restype = None
krb5_principal_compare = LIBKRB5.krb5_principal_compare
krb5_principal_compare.argtypes = (krb5_context, krb5_principal,

View File

@ -0,0 +1,51 @@
From e69d98add55f25641459fc1dfb973260e85f9b95 Mon Sep 17 00:00:00 2001
From: Stanislav Levin <slev@altlinux.org>
Date: Jan 30 2024 15:07:56 +0000
Subject: ipapython: Propagate KRB5Error exceptions on iterating ccache
`ipapython.session_storage.get_data` iterates over
credentials in a credential cache till `krb5_cc_next_cred` returns
an error. This function doesn't expect any error on calling
other kerberos foreign functions during iteration. But that can
actually happen and KRB5Error exceptions stop an iteration while
they should be propagated.
With this change iteration will exactly stop on `krb5_cc_next_cred`
error as it was supposed to be.
Fixes: https://pagure.io/freeipa/issue/9519
Signed-off-by: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
diff --git a/ipapython/session_storage.py b/ipapython/session_storage.py
index dc36f54..e890dc9 100644
--- a/ipapython/session_storage.py
+++ b/ipapython/session_storage.py
@@ -312,8 +312,12 @@ def get_data(princ_name, key):
checkcreds = krb5_creds()
# the next function will throw an error and break out of the
# while loop when we try to access past the last cred
- krb5_cc_next_cred(context, ccache, ctypes.byref(cursor),
- ctypes.byref(checkcreds))
+ try:
+ krb5_cc_next_cred(context, ccache, ctypes.byref(cursor),
+ ctypes.byref(checkcreds))
+ except KRB5Error:
+ break
+
if (krb5_principal_compare(context, principal,
checkcreds.client) == 1 and
krb5_principal_compare(context, srv_princ,
@@ -328,8 +332,6 @@ def get_data(princ_name, key):
else:
krb5_free_cred_contents(context,
ctypes.byref(checkcreds))
- except KRB5Error:
- pass
finally:
krb5_cc_end_seq_get(context, ccache, ctypes.byref(cursor))

View File

@ -0,0 +1,89 @@
From e831416320fdc73a18fba7716209edec76681721 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Jan 30 2024 15:16:22 +0000
Subject: ipa-kdb: Fix memory leak during PAC verification
Commit 0022bd70d93708d325855d5271516d6cd894d6e8 introduced a memory leak
during the copy of some PAC buffers, because of an unfreed memory
allocation context.
Fixes: https://pagure.io/freeipa/issue/9520
Signed-off-by: Julien Rische <jrische@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
---
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index 1558e2b..2866304 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -2316,6 +2316,7 @@ krb5_error_code ipadb_common_verify_pac(krb5_context context,
size_t i;
struct dom_sid *requester_sid = NULL;
struct dom_sid req_sid;
+ TALLOC_CTX *tmpctx = NULL;
if (signing_krbtgt != NULL &&
ipadb_is_cross_realm_krbtgt(signing_krbtgt->princ)) {
@@ -2371,6 +2372,12 @@ krb5_error_code ipadb_common_verify_pac(krb5_context context,
goto done;
}
+ tmpctx = talloc_new(NULL);
+ if (tmpctx == NULL) {
+ kerr = ENOMEM;
+ goto done;
+ }
+
for (i = 0; i < num_buffers; i++) {
if (types[i] == KRB5_PAC_SERVER_CHECKSUM ||
types[i] == KRB5_PAC_PRIVSVR_CHECKSUM ||
@@ -2398,32 +2405,21 @@ krb5_error_code ipadb_common_verify_pac(krb5_context context,
DATA_BLOB pac_attrs_data;
krb5_boolean pac_requested;
- TALLOC_CTX *tmpctx = talloc_new(NULL);
- if (tmpctx == NULL) {
- kerr = ENOMEM;
- goto done;
- }
-
kerr = ipadb_client_requested_pac(context, old_pac, tmpctx, &pac_requested);
- if (kerr != 0) {
- talloc_free(tmpctx);
+ if (kerr)
goto done;
- }
kerr = ipadb_get_pac_attrs_blob(tmpctx, &pac_requested, &pac_attrs_data);
- if (kerr) {
- talloc_free(tmpctx);
+ if (kerr)
goto done;
- }
+
data.magic = KV5M_DATA;
data.data = (char *)pac_attrs_data.data;
data.length = pac_attrs_data.length;
kerr = krb5_pac_add_buffer(context, new_pac, PAC_TYPE_ATTRIBUTES_INFO, &data);
- if (kerr) {
- talloc_free(tmpctx);
+ if (kerr)
goto done;
- }
continue;
}
@@ -2470,6 +2466,8 @@ done:
if (kerr != 0 && (new_pac != *pac)) {
krb5_pac_free(context, new_pac);
}
+ if (tmpctx)
+ talloc_free(tmpctx);
krb5_free_data_contents(context, &pac_blob);
free(types);
return kerr;

View File

@ -0,0 +1,80 @@
From d4008aece36569131b6e81192cc7d7dfa9f9af2b Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Jan 31 2024 08:33:17 +0000
Subject: sidgen: ignore staged users when generating SIDs
Staged users have
uidNumber: -1
gidNumber: -1
ipaUniqueID: autogenerate
We cannot generate ipaSecurityIdentifier based on those UID/GID numbers.
However, '-1' value will trigger an error
find_sid_for_ldap_entry - [file ipa_sidgen_common.c, line 483]: ID value too large.
And that, in turn, will cause stopping SID generation for all users.
Detect 'ipaUniqueID: autogenerate' situation and ignore these entries.
Fixes: https://pagure.io/freeipa/issue/9517
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
---
diff --git a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h
index 0feff7e..bd46982 100644
--- a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h
+++ b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h
@@ -45,6 +45,8 @@
#define UID_NUMBER "uidnumber"
#define GID_NUMBER "gidnumber"
#define IPA_SID "ipantsecurityidentifier"
+#define IPA_UNIQUEID "ipauniqueid"
+#define IPA_UNIQUEID_AUTOGENERATE "autogenerate"
#define DOM_ATTRS_FILTER OBJECTCLASS"=ipantdomainattrs"
#define DOMAIN_ID_RANGE_FILTER OBJECTCLASS"=ipadomainidrange"
#define POSIX_ACCOUNT "posixaccount"
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 6f78480..cb763eb 100644
--- a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_common.c
+++ b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen_common.c
@@ -454,6 +454,7 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry,
uint32_t id;
char *sid = NULL;
char **objectclasses = NULL;
+ char *uniqueid = NULL;
Slapi_PBlock *mod_pb = NULL;
Slapi_Mods *smods = NULL;
int result;
@@ -479,6 +480,16 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry,
goto done;
}
+ uniqueid = slapi_entry_attr_get_charptr(entry, IPA_UNIQUEID);
+ if (uniqueid != NULL &&
+ strncmp(IPA_UNIQUEID_AUTOGENERATE, uniqueid,
+ sizeof(IPA_UNIQUEID_AUTOGENERATE)) == 0) {
+ LOG("Staged entry [%s] does not have Posix IDs, nothing to do.\n",
+ dn_str);
+ ret = 0;
+ goto done;
+ }
+
if (uid_number >= UINT32_MAX || gid_number >= UINT32_MAX) {
LOG_FATAL("ID value too large.\n");
ret = LDAP_CONSTRAINT_VIOLATION;
@@ -554,6 +565,7 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry,
}
done:
+ slapi_ch_free_string(&uniqueid);
slapi_ch_free_string(&sid);
slapi_pblock_destroy(mod_pb);
slapi_mods_free(&smods);

View File

@ -0,0 +1,24 @@
From e6f96a9f2edd55ef335eb430b8dd8f6c9faf008f Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Jan 31 2024 08:33:17 +0000
Subject: sidgen: fix missing prototypes
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
---
diff --git a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h
index bd46982..aec8627 100644
--- a/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h
+++ b/daemons/ipa-slapi-plugins/ipa-sidgen/ipa_sidgen.h
@@ -106,3 +106,6 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry,
const char *base_dn,
const char *dom_sid,
struct range_info **ranges);
+
+int sidgen_task_init(Slapi_PBlock *pb);
+int ipa_sidgen_init(Slapi_PBlock *pb);

View File

@ -0,0 +1,45 @@
From 196d63109730666f547f99814a54a5b2cd72c80e Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Jan 31 2024 08:33:17 +0000
Subject: kdb: PAC generator: do not fail if canonical principal is missing
krbCanonicalName is mandatory for services but IPA services created
before commit e6ff83e (FreeIPA 4.4.0, ~2016) had no normalization done
to set krbCanonicalName; services created after that version were
upgraded to do have krbCanonicalName.
Accept krbPrincipalName alone since they have no alias either */
Fixes: https://pagure.io/freeipa/issue/9465
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
---
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index 2866304..16374a5 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -496,8 +496,16 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
"krbCanonicalName", &strres);
if (ret) {
- /* krbCanonicalName is mandatory for services */
- return ret;
+ /* krbCanonicalName is mandatory for services but IPA services
+ * created before commit e6ff83e (FreeIPA 4.4.0, ~2016) had no
+ * normalization to set krbCanonicalName; services created after
+ * that version were upgraded to do have krbCanonicalName.
+ *
+ * Accept krbPrincipalName alone since they have no alias either */
+ ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
+ "krbPrincipalName", &strres);
+ if (ret)
+ return ret;
}
ret = krb5_parse_name(ipactx->kcontext, strres, &princ);

View File

@ -0,0 +1,34 @@
From 278c2cbb193496302f8c0abc4ce502ec83f47a12 Mon Sep 17 00:00:00 2001
From: Florence Blanc-Renaud <flo@redhat.com>
Date: Feb 14 2024 12:23:15 +0000
Subject: ipatests: fix tasks.wait_for_replication method
With the fix for https://pagure.io/freeipa/issue/9171, the
method entry.single_value['nsds5replicaupdateinprogress'] now
returns a Boolean instead of a string "TRUE"/"FALSE".
The method tasks.wait_for_replication needs to be fixed so that
it properly detects when replication is not done.
Fixes: https://pagure.io/freeipa/issue/9530
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
---
diff --git a/ipatests/pytest_ipa/integration/tasks.py b/ipatests/pytest_ipa/integration/tasks.py
index 3dd32cf..9c73ac4 100755
--- a/ipatests/pytest_ipa/integration/tasks.py
+++ b/ipatests/pytest_ipa/integration/tasks.py
@@ -1520,7 +1520,7 @@ def wait_for_replication(ldap, timeout=30,
statuses = [entry.single_value[status_attr] for entry in entries]
wrong_statuses = [s for s in statuses
if not re.match(target_status_re, s)]
- if any(e.single_value[progress_attr] == 'TRUE' for e in entries):
+ if any(e.single_value[progress_attr] for e in entries):
msg = 'Replication not finished'
logger.debug(msg)
elif wrong_statuses:

View File

@ -0,0 +1,699 @@
From 7b7f5c3f806e53ff883865c7b7f4d17453d63ce6 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Feb 16 2024 11:58:21 +0000
Subject: ipa-kdb: Rework ipadb_reinit_mspac()
Modify ipadb_reinit_mspac() to allocate and initialize ipactx->mspac
only if all its attributes can be set. If not, ipactx->mspac is set to
NULL. This makes easier to determine if the KDC is able to generate PACs
or not.
Also ipadb_reinit_mspac() is now able to return a status message
explaining why initialization of the PAC generator failed. This message
is printed in KDC logs.
Fixes: https://pagure.io/freeipa/issue/9535
Signed-off-by: Julien Rische <jrische@redhat.com>
Reviewed-By: Alexander Bokovoy <abbra@users.noreply.github.com>
---
diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c
index a60f16c..f17cb11 100644
--- a/daemons/ipa-kdb/ipa_kdb.c
+++ b/daemons/ipa-kdb/ipa_kdb.c
@@ -448,6 +448,7 @@ int ipadb_get_connection(struct ipadb_context *ipactx)
struct timeval tv = { 5, 0 };
LDAPMessage *res = NULL;
LDAPMessage *first;
+ const char *stmsg;
int ret;
int v3;
@@ -527,16 +528,9 @@ int ipadb_get_connection(struct ipadb_context *ipactx)
}
/* get adtrust options using default refresh interval */
- ret = ipadb_reinit_mspac(ipactx, false);
- if (ret && ret != ENOENT) {
- /* TODO: log that there is an issue with adtrust settings */
- if (ipactx->lcontext == NULL) {
- /* for some reason ldap connection was reset in ipadb_reinit_mspac
- * and is no longer established => failure of ipadb_get_connection
- */
- goto done;
- }
- }
+ ret = ipadb_reinit_mspac(ipactx, false, &stmsg);
+ if (ret && stmsg)
+ krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", stmsg);
ret = 0;
diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
index 7b7c03b..3647ecd 100644
--- a/daemons/ipa-kdb/ipa_kdb.h
+++ b/daemons/ipa-kdb/ipa_kdb.h
@@ -369,7 +369,9 @@ krb5_error_code ipadb_v9_issue_pac(krb5_context context, unsigned int flags,
krb5_data ***auth_indicators);
#endif
-krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_reinit);
+krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx,
+ bool force_reinit,
+ const char **stmsg);
void ipadb_mspac_struct_free(struct ipadb_mspac **mspac);
krb5_error_code ipadb_check_transited_realms(krb5_context kcontext,
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index 16374a5..b0eb332 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -793,16 +793,16 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
return ret;
}
+ if (!ipactx->mspac) {
+ /* can't give a PAC without server NetBIOS name or primary group RID */
+ return ENOENT;
+ }
+
if (info3->base.primary_gid == 0) {
if (is_host || is_service) {
info3->base.primary_gid = 515; /* Well known RID for domain computers group */
} else {
- if (ipactx->mspac->fallback_rid) {
- info3->base.primary_gid = ipactx->mspac->fallback_rid;
- } else {
- /* can't give a pack without a primary group rid */
- return ENOENT;
- }
+ info3->base.primary_gid = ipactx->mspac->fallback_rid;
}
}
@@ -812,26 +812,16 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
/* always zero out, not used for Krb, only NTLM */
memset(&info3->base.key, '\0', sizeof(info3->base.key));
- if (ipactx->mspac->flat_server_name) {
- info3->base.logon_server.string =
- talloc_strdup(memctx, ipactx->mspac->flat_server_name);
- if (!info3->base.logon_server.string) {
- return ENOMEM;
- }
- } else {
- /* can't give a pack without Server NetBIOS Name :-| */
- return ENOENT;
+ info3->base.logon_server.string =
+ talloc_strdup(memctx, ipactx->mspac->flat_server_name);
+ if (!info3->base.logon_server.string) {
+ return ENOMEM;
}
- if (ipactx->mspac->flat_domain_name) {
- info3->base.logon_domain.string =
- talloc_strdup(memctx, ipactx->mspac->flat_domain_name);
- if (!info3->base.logon_domain.string) {
- return ENOMEM;
- }
- } else {
- /* can't give a pack without Domain NetBIOS Name :-| */
- return ENOENT;
+ info3->base.logon_domain.string =
+ talloc_strdup(memctx, ipactx->mspac->flat_domain_name);
+ if (!info3->base.logon_domain.string) {
+ return ENOMEM;
}
if (is_host || is_service) {
@@ -1044,6 +1034,11 @@ krb5_error_code ipadb_get_pac(krb5_context kcontext,
return KRB5_KDB_DBNOTINITED;
}
+ /* Check if PAC generator is initialized */
+ if (!ipactx->mspac) {
+ return ENOENT;
+ }
+
ied = (struct ipadb_e_data *)client->e_data;
if (ied->magic != IPA_E_DATA_MAGIC) {
return EINVAL;
@@ -1626,14 +1621,14 @@ static struct ipadb_adtrusts *get_domain_from_realm(krb5_context context,
{
struct ipadb_context *ipactx;
struct ipadb_adtrusts *domain;
- int i;
+ size_t i;
ipactx = ipadb_get_context(context);
if (!ipactx) {
return NULL;
}
- if (ipactx->mspac == NULL) {
+ if (!ipactx->mspac) {
return NULL;
}
@@ -1655,6 +1650,7 @@ static struct ipadb_adtrusts *get_domain_from_realm_update(krb5_context context,
{
struct ipadb_context *ipactx;
struct ipadb_adtrusts *domain;
+ const char *stmsg = NULL;
krb5_error_code kerr;
ipactx = ipadb_get_context(context);
@@ -1663,8 +1659,10 @@ static struct ipadb_adtrusts *get_domain_from_realm_update(krb5_context context,
}
/* re-init MS-PAC info using default update interval */
- kerr = ipadb_reinit_mspac(ipactx, false);
+ kerr = ipadb_reinit_mspac(ipactx, false, &stmsg);
if (kerr != 0) {
+ if (stmsg)
+ krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", stmsg);
return NULL;
}
domain = get_domain_from_realm(context, realm);
@@ -1717,6 +1715,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
struct ipadb_e_data *ied = NULL;
int flags = 0;
struct dom_sid client_sid;
+ const char *stmsg = NULL;
#ifdef KRB5_KDB_FLAG_ALIAS_OK
flags = KRB5_KDB_FLAG_ALIAS_OK;
#endif
@@ -1730,10 +1729,14 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
* check that our own view on the PAC details is up to date */
if (ipactx->mspac->domsid.num_auths == 0) {
/* Force re-init of KDB's view on our domain */
- kerr = ipadb_reinit_mspac(ipactx, true);
+ kerr = ipadb_reinit_mspac(ipactx, true, &stmsg);
if (kerr != 0) {
- krb5_klog_syslog(LOG_ERR,
- "PAC issue: unable to update realm's view on PAC info");
+ if (stmsg) {
+ krb5_klog_syslog(LOG_ERR, "MS-PAC generator: %s", stmsg);
+ } else {
+ krb5_klog_syslog(LOG_ERR, "PAC issue: unable to update " \
+ "realm's view on PAC info");
+ }
return KRB5KDC_ERR_POLICY;
}
}
@@ -1746,7 +1749,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
if (is_s4u && (ipactx->mspac->trusts != NULL)) {
/* Iterate through list of trusts and check if this SID belongs to
* one of the domains we trust */
- for(int i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
+ for(size_t i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
result = dom_sid_check(&ipactx->mspac->trusts[i].domsid,
info->info->info3.base.domain_sid, true);
if (result) {
@@ -1858,11 +1861,11 @@ krb5_error_code filter_logon_info(krb5_context context,
struct ipadb_mspac *mspac_ctx = ipactx->mspac;
result = FALSE;
/* Didn't match but perhaps the original PAC was issued by a child domain's DC? */
- for (k = 0; k < mspac_ctx->num_trusts; k++) {
- result = dom_sid_check(&mspac_ctx->trusts[k].domsid,
+ for (size_t m = 0; m < mspac_ctx->num_trusts; m++) {
+ result = dom_sid_check(&mspac_ctx->trusts[m].domsid,
info->info->info3.base.domain_sid, true);
if (result) {
- domain = &mspac_ctx->trusts[k];
+ domain = &mspac_ctx->trusts[m];
break;
}
}
@@ -2091,10 +2094,10 @@ static krb5_error_code ipadb_check_logon_info(krb5_context context,
return KRB5_KDB_DBNOTINITED;
}
/* In S4U case we might be dealing with the PAC issued by the trusted domain */
- if ((ipactx->mspac->trusts != NULL)) {
+ if (ipactx->mspac->trusts) {
/* Iterate through list of trusts and check if this SID belongs to
* one of the domains we trust */
- for(int i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
+ for(size_t i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
result = dom_sid_check(&ipactx->mspac->trusts[i].domsid,
&client_sid, false);
if (result) {
@@ -2634,7 +2637,7 @@ static char *get_server_netbios_name(struct ipadb_context *ipactx)
void ipadb_mspac_struct_free(struct ipadb_mspac **mspac)
{
- int i, j;
+ size_t i, j;
if (!*mspac) return;
@@ -2789,7 +2792,8 @@ ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx)
LDAPDN dn = NULL;
char **sid_blocklist_incoming = NULL;
char **sid_blocklist_outgoing = NULL;
- int ret, n, i;
+ size_t i, n;
+ int ret;
ret = asprintf(&base, "cn=ad,cn=trusts,%s", ipactx->base);
if (ret == -1) {
@@ -2874,7 +2878,7 @@ ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx)
t[n].upn_suffixes_len = NULL;
if (t[n].upn_suffixes != NULL) {
- int len = 0;
+ size_t len = 0;
for (; t[n].upn_suffixes[len] != NULL; len++);
@@ -2989,108 +2993,114 @@ done:
return ret;
}
-krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_reinit)
+krb5_error_code
+ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_reinit,
+ const char **stmsg)
{
char *dom_attrs[] = { "ipaNTFlatName",
"ipaNTFallbackPrimaryGroup",
"ipaNTSecurityIdentifier",
NULL };
char *grp_attrs[] = { "ipaNTSecurityIdentifier", NULL };
- krb5_error_code kerr;
LDAPMessage *result = NULL;
LDAPMessage *lentry;
- struct dom_sid gsid;
- char *resstr;
- int ret;
+ struct dom_sid gsid, domsid;
+ char *resstr = NULL;
+ char *flat_domain_name = NULL;
+ char *flat_server_name = NULL;
+ char *fallback_group = NULL;
+ uint32_t fallback_rid;
time_t now;
+ const char *in_stmsg = NULL;
+ int err;
+ krb5_error_code trust_kerr = 0;
+
/* Do not update the mspac struct more than once a minute. This would
* avoid heavy load on the directory server if there are lots of requests
* from domains which we do not trust. */
now = time(NULL);
- if (ipactx->mspac != NULL &&
- (force_reinit == false) &&
- (now > ipactx->mspac->last_update) &&
- (now - ipactx->mspac->last_update) < 60) {
- return 0;
- }
-
- if (ipactx->mspac && ipactx->mspac->num_trusts == 0) {
- /* Check if there is any trust configured. If not, just return
- * and do not re-initialize the MS-PAC structure. */
- kerr = ipadb_mspac_check_trusted_domains(ipactx);
- if (kerr == KRB5_KDB_NOENTRY) {
- kerr = 0;
- goto done;
- } else if (kerr != 0) {
- goto done;
+ if (ipactx->mspac) {
+ if (!force_reinit &&
+ (now > ipactx->mspac->last_update) &&
+ (now - ipactx->mspac->last_update) < 60) {
+ /* SKIP */
+ err = 0;
+ goto end;
+ }
+
+ if (ipactx->mspac->num_trusts == 0) {
+ /* Check if there is any trust configured. If not, just return
+ * and do not re-initialize the MS-PAC structure. */
+ err = ipadb_mspac_check_trusted_domains(ipactx);
+ if (err) {
+ if (err == KRB5_KDB_NOENTRY) {
+ /* SKIP */
+ err = 0;
+ } else {
+ in_stmsg = "Failed to fetch trusted domains information";
+ }
+ goto end;
+ }
}
}
- /* clean up in case we had old values around */
- ipadb_mspac_struct_free(&ipactx->mspac);
-
- ipactx->mspac = calloc(1, sizeof(struct ipadb_mspac));
- if (!ipactx->mspac) {
- kerr = ENOMEM;
- goto done;
- }
-
- ipactx->mspac->last_update = now;
-
- kerr = ipadb_simple_search(ipactx, ipactx->base, LDAP_SCOPE_SUBTREE,
- "(objectclass=ipaNTDomainAttrs)", dom_attrs,
- &result);
- if (kerr == KRB5_KDB_NOENTRY) {
- return ENOENT;
- } else if (kerr != 0) {
- return EIO;
+ err = ipadb_simple_search(ipactx, ipactx->base, LDAP_SCOPE_SUBTREE,
+ "(objectclass=ipaNTDomainAttrs)", dom_attrs,
+ &result);
+ if (err == KRB5_KDB_NOENTRY) {
+ err = ENOENT;
+ in_stmsg = "Local domain NT attributes not configured";
+ goto end;
+ } else if (err) {
+ err = EIO;
+ in_stmsg = "Failed to fetch local domain NT attributes";
+ goto end;
}
lentry = ldap_first_entry(ipactx->lcontext, result);
if (!lentry) {
- kerr = ENOENT;
- goto done;
+ err = ENOENT;
+ in_stmsg = "Local domain NT attributes not configured";
+ goto end;
}
- ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
- "ipaNTFlatName",
- &ipactx->mspac->flat_domain_name);
- if (ret) {
- kerr = ret;
- goto done;
+ err = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry, "ipaNTFlatName",
+ &flat_domain_name);
+ if (err) {
+ in_stmsg = "Local domain NT flat name not configured";
+ goto end;
}
- ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
- "ipaNTSecurityIdentifier",
- &resstr);
- if (ret) {
- kerr = ret;
- goto done;
+ err = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
+ "ipaNTSecurityIdentifier", &resstr);
+ if (err) {
+ in_stmsg = "Local domain SID not configured";
+ goto end;
}
- ret = ipadb_string_to_sid(resstr, &ipactx->mspac->domsid);
- if (ret) {
- kerr = ret;
- free(resstr);
- goto done;
+ err = ipadb_string_to_sid(resstr, &domsid);
+ if (err) {
+ in_stmsg = "Malformed local domain SID";
+ goto end;
}
+
free(resstr);
- free(ipactx->mspac->flat_server_name);
- ipactx->mspac->flat_server_name = get_server_netbios_name(ipactx);
- if (!ipactx->mspac->flat_server_name) {
- kerr = ENOMEM;
- goto done;
+ flat_server_name = get_server_netbios_name(ipactx);
+ if (!flat_server_name) {
+ err = ENOMEM;
+ goto end;
}
- ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
- "ipaNTFallbackPrimaryGroup",
- &ipactx->mspac->fallback_group);
- if (ret && ret != ENOENT) {
- kerr = ret;
- goto done;
+ err = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
+ "ipaNTFallbackPrimaryGroup", &fallback_group);
+ if (err) {
+ in_stmsg = (err == ENOENT)
+ ? "Local fallback primary group not configured"
+ : "Failed to fetch local fallback primary group";
+ goto end;
}
/* result and lentry not valid any more from here on */
@@ -3098,53 +3108,81 @@ krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_rein
result = NULL;
lentry = NULL;
- if (ret != ENOENT) {
- kerr = ipadb_simple_search(ipactx, ipactx->mspac->fallback_group,
- LDAP_SCOPE_BASE,
- "(objectclass=posixGroup)",
- grp_attrs, &result);
- if (kerr && kerr != KRB5_KDB_NOENTRY) {
- kerr = ret;
- goto done;
- }
+ err = ipadb_simple_search(ipactx, fallback_group, LDAP_SCOPE_BASE,
+ "(objectclass=posixGroup)", grp_attrs, &result);
+ if (err) {
+ in_stmsg = (err == KRB5_KDB_NOENTRY)
+ ? "Local fallback primary group has no POSIX definition"
+ : "Failed to fetch SID of POSIX group mapped as local fallback " \
+ "primary group";
+ goto end;
+ }
- lentry = ldap_first_entry(ipactx->lcontext, result);
- if (!lentry) {
- kerr = ENOENT;
- goto done;
- }
+ lentry = ldap_first_entry(ipactx->lcontext, result);
+ if (!lentry) {
+ err = ENOENT;
+ goto end;
+ }
- if (kerr == 0) {
- ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
- "ipaNTSecurityIdentifier",
- &resstr);
- if (ret && ret != ENOENT) {
- kerr = ret;
- goto done;
- }
- if (ret == 0) {
- ret = ipadb_string_to_sid(resstr, &gsid);
- if (ret) {
- free(resstr);
- kerr = ret;
- goto done;
- }
- ret = sid_split_rid(&gsid, &ipactx->mspac->fallback_rid);
- if (ret) {
- free(resstr);
- kerr = ret;
- goto done;
- }
- free(resstr);
- }
- }
+ err = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
+ "ipaNTSecurityIdentifier", &resstr);
+ if (err) {
+ in_stmsg = (err == ENOENT)
+ ? "The POSIX group set as fallback primary group has no SID " \
+ "configured"
+ : "Failed to fetch SID of POSIX group set as local fallback " \
+ "primary group";
+ goto end;
}
- kerr = ipadb_mspac_get_trusted_domains(ipactx);
+ err = ipadb_string_to_sid(resstr, &gsid);
+ if (err) {
+ in_stmsg = "Malformed SID of POSIX group set as local fallback " \
+ "primary group";
+ goto end;
+ }
-done:
+ err = sid_split_rid(&gsid, &fallback_rid);
+ if (err) {
+ in_stmsg = "Malformed SID of POSIX group mapped as local fallback " \
+ "primary group";
+ goto end;
+ }
+
+ /* clean up in case we had old values around */
+ ipadb_mspac_struct_free(&ipactx->mspac);
+
+ ipactx->mspac = calloc(1, sizeof(struct ipadb_mspac));
+ if (!ipactx->mspac) {
+ err = ENOMEM;
+ goto end;
+ }
+
+ ipactx->mspac->last_update = now;
+ ipactx->mspac->flat_domain_name = flat_domain_name;
+ ipactx->mspac->flat_server_name = flat_server_name;
+ ipactx->mspac->domsid = domsid;
+ ipactx->mspac->fallback_group = fallback_group;
+ ipactx->mspac->fallback_rid = fallback_rid;
+
+ trust_kerr = ipadb_mspac_get_trusted_domains(ipactx);
+ if (trust_kerr)
+ in_stmsg = "Failed to assemble trusted domains information";
+
+end:
+ if (stmsg)
+ *stmsg = in_stmsg;
+
+ if (resstr) free(resstr);
ldap_msgfree(result);
- return kerr;
+
+ if (err) {
+ if (flat_domain_name) free(flat_domain_name);
+ if (flat_server_name) free(flat_server_name);
+ if (fallback_group) free(fallback_group);
+ }
+
+ return err ? (krb5_error_code)err : trust_kerr;
}
krb5_error_code ipadb_check_transited_realms(krb5_context kcontext,
@@ -3154,11 +3192,11 @@ krb5_error_code ipadb_check_transited_realms(krb5_context kcontext,
{
struct ipadb_context *ipactx;
bool has_transited_contents, has_client_realm, has_server_realm;
- int i;
+ size_t i;
krb5_error_code ret;
ipactx = ipadb_get_context(kcontext);
- if (!ipactx || !ipactx->mspac) {
+ if (!ipactx) {
return KRB5_KDB_DBNOTINITED;
}
@@ -3220,7 +3258,7 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
char **trusted_realm)
{
struct ipadb_context *ipactx;
- int i, j, length;
+ size_t i, j, length;
const char *name;
bool result = false;
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac_private.h b/daemons/ipa-kdb/ipa_kdb_mspac_private.h
index 7f0ca7a..e650cfa 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac_private.h
+++ b/daemons/ipa-kdb/ipa_kdb_mspac_private.h
@@ -31,7 +31,7 @@ struct ipadb_mspac {
char *fallback_group;
uint32_t fallback_rid;
- int num_trusts;
+ size_t num_trusts;
struct ipadb_adtrusts *trusts;
time_t last_update;
};
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac_v6.c b/daemons/ipa-kdb/ipa_kdb_mspac_v6.c
index faf47ad..96cd50e 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac_v6.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac_v6.c
@@ -233,6 +233,7 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
krb5_db_entry *client_entry = NULL;
krb5_boolean is_equal;
bool force_reinit_mspac = false;
+ const char *stmsg = NULL;
is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0);
@@ -309,7 +310,9 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
force_reinit_mspac = true;
}
- (void)ipadb_reinit_mspac(ipactx, force_reinit_mspac);
+ kerr = ipadb_reinit_mspac(ipactx, force_reinit_mspac, &stmsg);
+ if (kerr && stmsg)
+ krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", stmsg);
kerr = ipadb_get_pac(context, flags, client, server, NULL, authtime, &pac);
if (kerr != 0 && kerr != ENOENT) {
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac_v9.c b/daemons/ipa-kdb/ipa_kdb_mspac_v9.c
index 3badd5b..60db048 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac_v9.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac_v9.c
@@ -46,6 +46,7 @@ ipadb_v9_issue_pac(krb5_context context, unsigned int flags,
bool with_pad;
krb5_error_code kerr = 0;
bool is_as_req = flags & CLIENT_REFERRALS_FLAGS;
+ const char *stmsg = NULL;
if (is_as_req) {
get_authz_data_types(context, client, &with_pac, &with_pad);
@@ -110,12 +111,19 @@ ipadb_v9_issue_pac(krb5_context context, unsigned int flags,
force_reinit_mspac = TRUE;
}
}
- (void)ipadb_reinit_mspac(ipactx, force_reinit_mspac);
- /* MS-PAC needs proper configuration and if it is missing, we simply skip issuing one */
- if (ipactx->mspac->flat_server_name == NULL) {
+ /* MS-PAC generator has to be initalized */
+ kerr = ipadb_reinit_mspac(ipactx, force_reinit_mspac, &stmsg);
+ if (kerr && stmsg)
+ krb5_klog_syslog(LOG_ERR, "MS-PAC generator: %s", stmsg);
+
+ /* Continue even if initilization of PAC generator failed.
+ * It may caused by the trust objects part only. */
+
+ /* At least the core part of the PAC generator is required. */
+ if (!ipactx->mspac)
return KRB5_PLUGIN_OP_NOTSUPP;
- }
+
kerr = ipadb_get_pac(context, flags,
client, server, replaced_reply_key,
authtime, &new_pac);
diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
index 00387d4..ffc0fd8 100644
--- a/daemons/ipa-kdb/ipa_kdb_principals.c
+++ b/daemons/ipa-kdb/ipa_kdb_principals.c
@@ -1567,6 +1567,7 @@ static krb5_error_code dbget_alias(krb5_context kcontext,
-1,
};
size_t i = 0;
+ const char *stmsg = NULL;
/* For TGS-REQ server principal lookup, KDC asks with KRB5_KDB_FLAG_REFERRAL_OK
* and client usually asks for an KRB5_NT_PRINCIPAL type principal. */
@@ -1654,8 +1655,11 @@ static krb5_error_code dbget_alias(krb5_context kcontext,
if (kerr == KRB5_KDB_NOENTRY) {
/* If no trusted realm found, refresh trusted domain data and try again
* because it might be a freshly added trust to AD */
- kerr = ipadb_reinit_mspac(ipactx, false);
+ kerr = ipadb_reinit_mspac(ipactx, false, &stmsg);
if (kerr != 0) {
+ if (stmsg)
+ krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s",
+ stmsg);
kerr = KRB5_KDB_NOENTRY;
goto done;
}

View File

@ -0,0 +1,26 @@
From f1efe4490c1e33b81178ba887600a3a5826c11c2 Mon Sep 17 00:00:00 2001
From: Julien Rische <jrische@redhat.com>
Date: Feb 20 2024 18:12:39 +0000
Subject: ipa-kdb: Fix double free in ipadb_reinit_mspac()
Fixes: https://pagure.io/freeipa/issue/9535
Signed-off-by: Julien Rische <jrische@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
---
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index b0eb332..9723103 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -3087,6 +3087,7 @@ ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_reinit,
}
free(resstr);
+ resstr = NULL;
flat_server_name = get_server_netbios_name(ipactx);
if (!flat_server_name) {

View File

@ -1,69 +0,0 @@
From 0d44e959e5bbe822b51137a8e7cf48fa25533805 Mon Sep 17 00:00:00 2001
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
Date: Fri, 10 Dec 2021 12:15:36 -0300
Subject: [PATCH] Revert "freeipa.spec: depend on bind-dnssec-utils"
This reverts commit f89d59b6e18b54967682f6a37ce92ae67ab3fcda.
---
freeipa.spec.in | 4 +---
ipaplatform/base/paths.py | 2 +-
ipaplatform/fedora/paths.py | 1 +
ipaserver/dnssec/bindmgr.py | 1 -
4 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 8f5c370e5..e20edb7bc 100755
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -576,11 +576,9 @@ Requires: %{name}-server = %{version}-%{release}
Requires: bind-dyndb-ldap >= 11.2-2
Requires: bind >= %{bind_version}
Requires: bind-utils >= %{bind_version}
-# bind-dnssec-utils is required by the OpenDNSSec integration
-# https://pagure.io/freeipa/issue/9026
-Requires: bind-dnssec-utils >= %{bind_version}
%if %{with bind_pkcs11}
Requires: bind-pkcs11 >= %{bind_version}
+Requires: bind-pkcs11-utils >= %{bind_version}
%else
Requires: softhsm >= %{softhsm_version}
Requires: openssl-pkcs11 >= %{openssl_pkcs11_version}
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
index 7d21367ec..42a47f1df 100644
--- a/ipaplatform/base/paths.py
+++ b/ipaplatform/base/paths.py
@@ -259,7 +259,6 @@ class BasePathNamespace:
IPA_PKI_RETRIEVE_KEY = "/usr/libexec/ipa/ipa-pki-retrieve-key"
IPA_HTTPD_PASSWD_READER = "/usr/libexec/ipa/ipa-httpd-pwdreader"
IPA_PKI_WAIT_RUNNING = "/usr/libexec/ipa/ipa-pki-wait-running"
- DNSSEC_KEYFROMLABEL = "/usr/sbin/dnssec-keyfromlabel"
+ DNSSEC_KEYFROMLABEL = "/usr/sbin/dnssec-keyfromlabel-pkcs11"
- DNSSEC_KEYFROMLABEL_9_17 = "/usr/bin/dnssec-keyfromlabel"
GETSEBOOL = "/usr/sbin/getsebool"
GROUPADD = "/usr/sbin/groupadd"
diff --git a/ipaplatform/fedora/paths.py b/ipaplatform/fedora/paths.py
index 4e993c063..92a948966 100644
--- a/ipaplatform/fedora/paths.py
+++ b/ipaplatform/fedora/paths.py
@@ -36,6 +36,7 @@ class FedoraPathNamespace(RedHatPathNamespace):
NAMED_CRYPTO_POLICY_FILE = "/etc/crypto-policies/back-ends/bind.config"
if HAS_NFS_CONF:
SYSCONFIG_NFS = '/etc/nfs.conf'
+ DNSSEC_KEYFROMLABEL = "/usr/sbin/dnssec-keyfromlabel"
paths = FedoraPathNamespace()
diff --git a/ipaserver/dnssec/bindmgr.py b/ipaserver/dnssec/bindmgr.py
index 0c79cc03d..a15c0e601 100644
--- a/ipaserver/dnssec/bindmgr.py
+++ b/ipaserver/dnssec/bindmgr.py
@@ -127,7 +127,6 @@ class BINDMgr:
)
cmd = [
paths.DNSSEC_KEYFROMLABEL,
- '-E', 'pkcs11',
'-K', workdir,
'-a', attrs['idnsSecAlgorithm'][0],
'-l', uri
--
2.31.1

View File

@ -1,60 +0,0 @@
From 7807bcc55b4927fc327830d2237200772d2e1106 Mon Sep 17 00:00:00 2001
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
Date: Fri, 17 Jun 2022 15:40:04 -0300
Subject: [PATCH] webui IdP: Remove arrow notation due to uglify-js limitation.
uglify-js 2.x series do not support ECMAScript 6 arrow notation ('=>')
for callback definition.
This patch changes the arrow definition callbacks for regular anonymous
function definitions.
---
install/ui/src/freeipa/idp.js | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/install/ui/src/freeipa/idp.js b/install/ui/src/freeipa/idp.js
index ada09c075..be3c4f0e6 100644
--- a/install/ui/src/freeipa/idp.js
+++ b/install/ui/src/freeipa/idp.js
@@ -227,7 +227,7 @@ IPA.add_idp_policy = function() {
// For custom template we show custom fields
// and mark all of them required and passed to the RPC
// If show_custom is false, the opposite happens
- custom_fields.forEach(fname => {
+ custom_fields.forEach(function(fname) {
widget_f = that.container.fields.get_field(fname);
widget_f.set_required(show_custom);
widget_f.set_enabled(show_custom);
@@ -235,7 +235,7 @@ IPA.add_idp_policy = function() {
});
// For template fields we show them if custom aren't shown
- template_fields.forEach(fname => {
+ template_fields.forEach(function(fname) {
widget_f = that.container.fields.get_field(fname);
widget_f.set_enabled(!show_custom);
widget_f.widget.set_visible(!show_custom);
@@ -252,7 +252,7 @@ IPA.add_idp_policy = function() {
var value = prov_f.get_value()[0];
// First, clear template fields from the previous provider choice
- template_fields.forEach(fname => {
+ template_fields.forEach(function(fname) {
widget_f = that.container.fields.get_field(fname);
widget_f.widget.set_visible(false);
widget_f.set_required(false);
@@ -260,9 +260,9 @@ IPA.add_idp_policy = function() {
});
// Second, enable and get required template-specific fields
- idp.templates.forEach(idp_v => {
+ idp.templates.forEach(function(idp_v) {
if (idp_v['value'] == value) {
- idp_v['fields'].forEach(fname => {
+ idp_v['fields'].forEach(function(fname) {
widget_f = that.container.fields.get_field(fname);
widget_f.set_required(true);
widget_f.set_enabled(true);
--
2.36.1

View File

@ -1,120 +0,0 @@
From 9a33838407f244e481523fe643bc0626874e8b1a Mon Sep 17 00:00:00 2001
From: Rafael Guterres Jeffman <rjeffman@redhat.com>
Date: Mon, 19 Dec 2022 14:57:03 -0300
Subject: [PATCH] Revert "DNSResolver: Fix use of nameservers with ports"
This reverts commit 5e2e4664aec641886923c2bec61ce25b96edb62a.
diff --git a/ipapython/dnsutil.py b/ipapython/dnsutil.py
index 58de365ab..4baeaf8cc 100644
--- a/ipapython/dnsutil.py 2023-05-19 05:12:52.471239297 -0300
+++ b/ipapython/dnsutil.py 2023-05-24 12:20:13.588867053 -0300
@@ -145,55 +145,6 @@
nameservers.remove(ipv4_loopback)
self.nameservers = nameservers
- @property
- def nameservers(self):
- return self._nameservers
-
- @nameservers.setter
- def nameservers(self, nameservers):
- """
- *nameservers*, a ``list`` of nameservers with optional ports:
- "SERVER_IP port PORT_NUMBER".
-
- Overloads dns.resolver.Resolver.nameservers setter to split off ports
- into nameserver_ports after setting nameservers successfully with the
- setter in dns.resolver.Resolver.
- """
- # Get nameserver_ports if it is already set
- if hasattr(self, "nameserver_ports"):
- nameserver_ports = self.nameserver_ports
- else:
- nameserver_ports = {}
-
- # Check nameserver items in list and split out converted port number
- # into nameserver_ports: { nameserver: port }
- if isinstance(nameservers, list):
- _nameservers = []
- for nameserver in nameservers:
- splits = nameserver.split()
- if len(splits) == 3 and splits[1] == "port":
- nameserver = splits[0]
- try:
- port = int(splits[2])
- if port < 0 or port > 65535:
- raise ValueError()
- except ValueError:
- raise ValueError(
- "invalid nameserver: %s is not a valid port" %
- splits[2])
- nameserver_ports[nameserver] = port
- _nameservers.append(nameserver)
- nameservers = _nameservers
-
- # Call dns.resolver.Resolver.nameservers setter
- if hasattr(dns.resolver.Resolver, "nameservers"):
- dns.resolver.Resolver.nameservers.__set__(self, nameservers)
- else:
- # old dnspython (<2) doesn't have 'nameservers' property
- self._nameservers = nameservers
- # Set nameserver_ports after successfull call to setter
- self.nameserver_ports = nameserver_ports
-
class DNSZoneAlreadyExists(dns.exception.DNSException):
supp_kwargs = {'zone', 'ns'}
diff --git a/ipatests/test_ipapython/test_dnsutil.py b/ipatests/test_ipapython/test_dnsutil.py
index 9070d89ad..5e7a46197 100644
--- a/ipatests/test_ipapython/test_dnsutil.py
+++ b/ipatests/test_ipapython/test_dnsutil.py
@@ -101,48 +101,3 @@ class TestSortURI:
assert dnsutil.sort_prio_weight([h3, h2, h1]) == [h1, h2, h3]
assert dnsutil.sort_prio_weight([h3, h3, h3]) == [h3]
assert dnsutil.sort_prio_weight([h2, h2, h1, h1]) == [h1, h2]
-
-
-class TestDNSResolver:
- @pytest.fixture(name="res")
- def resolver(self):
- """Resolver that doesn't read /etc/resolv.conf
-
- /etc/resolv.conf is not mandatory on systems
- """
- return dnsutil.DNSResolver(configure=False)
-
- def test_nameservers(self, res):
- res.nameservers = ["4.4.4.4", "8.8.8.8"]
- assert res.nameservers == ["4.4.4.4", "8.8.8.8"]
-
- def test_nameservers_with_ports(self, res):
- res.nameservers = ["4.4.4.4 port 53", "8.8.8.8 port 8053"]
- assert res.nameservers == ["4.4.4.4", "8.8.8.8"]
- assert res.nameserver_ports == {"4.4.4.4": 53, "8.8.8.8": 8053}
-
- res.nameservers = ["4.4.4.4 port 53", "8.8.8.8 port 8053"]
- assert res.nameservers == ["4.4.4.4", "8.8.8.8"]
- assert res.nameserver_ports == {"4.4.4.4": 53, "8.8.8.8": 8053}
-
- def test_nameservers_with_bad_ports(self, res):
- try:
- res.nameservers = ["4.4.4.4 port a"]
- except ValueError:
- pass
- else:
- pytest.fail("No fail on bad port a")
-
- try:
- res.nameservers = ["4.4.4.4 port -1"]
- except ValueError:
- pass
- else:
- pytest.fail("No fail on bad port -1")
-
- try:
- res.nameservers = ["4.4.4.4 port 65536"]
- except ValueError:
- pass
- else:
- pytest.fail("No fail on bad port 65536")

View File

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEE11Z2TU1+KXxtrRFyaYdvcqbi008FAmR+6S4ACgkQaYdvcqbi
008kvQ/9HuW6rWRJPY9/bqfaaeTKAT9JPCdq6jwDj7rSxpzJRE2r8vuwL3XxvXEa
8qW3qwx4qcBV3hrOPX3annilCgfyUN0ayF72rfDxGmVzTifooEVd0mmaDJOd9JHy
wLVYbImvsitC59luFF/XTIx5Xgo8Msu7BtAC5Tf5+mws0/i6ZxmyufYBPEmydgVM
jdpVSZfq4hd4HwfYH0Ej5c8sWfv2OTTENyBWn5x9LiWvC6rJi42u7ubcnWoCi6If
kXzJCRf7JTDzDvmMDVZMoTJCQa0EwlST7Yr9V7rLJViUGDwqxVO7VoeQi2WoV5PN
zDSoLoCVEgLdDt0EAYRlBxPzoe65kNBdGFhC3eT0uIO676NZuTMVEXaRtId1wfnU
o52xx3r5OPvRrjRLhKsAsMSiqX0Cr/wgH1L8QuSpriM1gMO6jZTkFpGtjD1XEvWd
VsiSVqR0y+E8U3bkLOTHvByPvWk9QlmN0e6WDyV0FvGPaPlD2VCGNLqraldeEKvr
wQxVvMWMqX+CKs2ZWYlzfgzFd0ZlUfsYhTcDaliJIh5Tcn5Ow+CSX/vWMXS6Msyh
80fS5k7NswIsa3bA0QSoFpAcSkNxxovKyIWpXamL/MgX/nqZqJE74aUtchANl9jd
j5yAU2s4eUuvbTMQkQjEJHl97a/jjGCGKnCunF/RO3WLaGdi9Dk=
=Bq0h
-----END PGP SIGNATURE-----

View File

@ -1,16 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEE11Z2TU1+KXxtrRFyaYdvcqbi008FAmRnL+gACgkQaYdvcqbi
00/1Gg/8CFABojXZyUkQnWeaHdrFeHeE+DW2qTs9Wr/TQwF67fYkh7lj3p+WqMlD
kMMNAfLn4wUnJNDMv64QlE6RAz71KetQlQt+mZQVT9M0nDepLhBw86qmNbJj611J
+2B79hzNLT8tmOf9NyLRJbFp3QebSPELX9hycPj1Ovd1tr/61tcwcNzE6ZLrX5vb
IPkCT2bo+6MceIsR50tTRxxK6J9jFYX73PjHJ5Ix7ssDf4vg2OBRTwUdLeZAkWlA
q+0bPPp+F3PWLhnSs+vIs5plHUI/hcGCt9pTvw/d6jUUxuwZadGGbRZSyDN7aj2Q
zEXeZsCtOSk5cx65lWHl+7TTyVvCoemeZPZ92EiCtVJfiuK3/6a/WFWanBZoO0E3
N0p6HUcvIRPrEj0nQwH2vr0zkfSPA4g30k+Q9qeP3ArN+i+5OFfuiwiqk1AIJ2rv
ERhBRryOaNeiVpYghMQdtacWP/qQunfH6VdhA61Q089/lhomGeSytQI+fV4TXOhV
ldV7dftaWpQT3QYWSsKzoiHpyjIwOA8dBvQF2YDX7LNmeO/hj4ToFp00CVCWdb0j
MHs2X9p42kkhw2oZOf3GNyNvpybxUv59ER4YDEHbj8+iZyVjiqfcp71373DqpieW
iGjB3Wc0gO3cdYk3Mdl0SgkD7k0U9iwwh7qJeqqUYT3gKf9mqbY=
=dT0o
-----END PGP SIGNATURE-----

3356
SPECS/freeipa.spec Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff