Compare commits
No commits in common. "c8-stream-DL1" and "a9" have entirely different histories.
c8-stream-
...
a9
|
@ -1 +1 @@
|
|||
SOURCES/freeipa-4.9.12.tar.gz
|
||||
SOURCES/freeipa-4.10.2.tar.gz
|
||||
|
|
|
@ -1 +1 @@
|
|||
ea6c8a209748b4ad8d07da556f705a366b3dd6c1 SOURCES/freeipa-4.9.12.tar.gz
|
||||
17d580b7dccb1586898aa46c7ecdd2bd2754ee5f SOURCES/freeipa-4.10.2.tar.gz
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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 \
|
|
@ -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
|
||||
|
||||
|
|
@ -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 = [
|
||||
|
|
@ -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
|
||||
|
|
@ -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" % \
|
||||
|
|
@ -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,
|
||||
|
|
@ -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
|
||||
|
|
@ -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,
|
||||
|
|
@ -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))
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
@ -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:
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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")
|
|
@ -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-----
|
|
@ -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-----
|
File diff suppressed because it is too large
Load Diff
5278
SPECS/ipa.spec
5278
SPECS/ipa.spec
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue