diff --git a/.ansible-freeipa.metadata b/.ansible-freeipa.metadata deleted file mode 100644 index a00700e..0000000 --- a/.ansible-freeipa.metadata +++ /dev/null @@ -1 +0,0 @@ -03f590ebf93439a08c56f8b98e61f38619309556 SOURCES/ansible-freeipa-1.9.2.tar.gz diff --git a/.gitignore b/.gitignore index b2787d0..d893a1a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/ansible-freeipa-1.9.2.tar.gz +SOURCES/ansible-freeipa-1.12.1.tar.gz diff --git a/SOURCES/ansible-freeipa-1.9.2-ipaclient-Defer-creating-the-final-krb5.conf-on-clients_RHBZ#2189238.patch b/SOURCES/ansible-freeipa-1.9.2-ipaclient-Defer-creating-the-final-krb5.conf-on-clients_RHBZ#2189238.patch deleted file mode 100644 index 08aa73d..0000000 --- a/SOURCES/ansible-freeipa-1.9.2-ipaclient-Defer-creating-the-final-krb5.conf-on-clients_RHBZ#2189238.patch +++ /dev/null @@ -1,727 +0,0 @@ -From 6b5acd9b0c8de965d9b815f8033a2bace9dd737d Mon Sep 17 00:00:00 2001 -From: Thomas Woerner -Date: Wed, 22 Feb 2023 13:35:18 +0100 -Subject: [PATCH] ipaclient: Defer creating the final krb5.conf on clients - -A temporary krb5 configuration was used to join the domain in -ipaclient_join. After that the final krkb5 configuration was created -with enabled DNS discovery and used for the remainaing tasks, where also -a connection to the IPA API was done. - -With several servers the DNS discovery could have picked up a different -server. If the client deployment was faster than the replication this -could have lead to an unknown host error. - -The issue was seen in performance testing where many simultaneous client -enrollments have been done.. - -The goal is to keep server affinity as long as possible within the -deployment process: - -The temporary krb5.conf that was used before in ipaclient_join was -pulled out into an own module. The generated temporary krb5.conf is now -used in ipaclient_join and also ipaclient_api. - -The generation of the final krb5.conf is moved to the end of the -deployment process. - -Same as: https://pagure.io/freeipa/issue/9228 - -The setup of certmonger has been pulled out of ipaclient_setup_nss and moved -to the end of the process after generating the final krb5.conf as it will -use t will only use /etc/krb5.conf. - -Certificate issuance may fail during deployment due to using the final -krb5.conf, but certmonger will re-try the request in this case. - -Same as: https://pagure.io/freeipa/issue/9246 ---- - roles/ipaclient/library/ipaclient_api.py | 8 + - roles/ipaclient/library/ipaclient_join.py | 55 ++---- - .../library/ipaclient_setup_certmonger.py | 123 +++++++++++++ - .../ipaclient/library/ipaclient_setup_nss.py | 4 +- - .../ipaclient/library/ipaclient_temp_krb5.py | 163 ++++++++++++++++++ - .../library/ipaclient_test_keytab.py | 6 + - roles/ipaclient/tasks/install.yml | 69 ++++++-- - 7 files changed, 365 insertions(+), 63 deletions(-) - create mode 100644 roles/ipaclient/library/ipaclient_setup_certmonger.py - create mode 100644 roles/ipaclient/library/ipaclient_temp_krb5.py - -diff --git a/roles/ipaclient/library/ipaclient_api.py b/roles/ipaclient/library/ipaclient_api.py -index 7d4b829..9193f60 100644 ---- a/roles/ipaclient/library/ipaclient_api.py -+++ b/roles/ipaclient/library/ipaclient_api.py -@@ -55,6 +55,10 @@ options: - type: bool - required: no - default: no -+ krb_name: -+ description: The krb5 config file name -+ type: str -+ required: yes - author: - - Thomas Woerner (@t-woerner) - ''' -@@ -65,6 +69,7 @@ EXAMPLES = ''' - servers: ["server1.example.com","server2.example.com"] - domain: example.com - hostname: client1.example.com -+ krb_name: /tmp/tmpkrb5.conf - register: result_ipaclient_api - ''' - -@@ -99,6 +104,7 @@ def main(): - realm=dict(required=True, type='str'), - hostname=dict(required=True, type='str'), - debug=dict(required=False, type='bool', default="false"), -+ krb_name=dict(required=True, type='str'), - ), - supports_check_mode=False, - ) -@@ -110,9 +116,11 @@ def main(): - realm = module.params.get('realm') - hostname = module.params.get('hostname') - debug = module.params.get('debug') -+ krb_name = module.params.get('krb_name') - - host_principal = 'host/%s@%s' % (hostname, realm) - os.environ['KRB5CCNAME'] = paths.IPA_DNS_CCACHE -+ os.environ['KRB5_CONFIG'] = krb_name - - ca_certs = x509.load_certificate_list_from_file(paths.IPA_CA_CRT) - if 40500 <= NUM_VERSION < 40590: -diff --git a/roles/ipaclient/library/ipaclient_join.py b/roles/ipaclient/library/ipaclient_join.py -index 5d41a54..68379ea 100644 ---- a/roles/ipaclient/library/ipaclient_join.py -+++ b/roles/ipaclient/library/ipaclient_join.py -@@ -46,10 +46,6 @@ options: - type: list - elements: str - required: yes -- domain: -- description: Primary DNS domain of the IPA deployment -- type: str -- required: yes - realm: - description: Kerberos realm name of the IPA deployment - type: str -@@ -58,10 +54,6 @@ options: - description: Fully qualified name of this host - type: str - required: yes -- kdc: -- description: The name or address of the host running the KDC -- type: str -- required: yes - basedn: - description: The basedn of the IPA server (of the form dc=example,dc=com) - type: str -@@ -102,6 +94,10 @@ options: - description: Turn on extra debugging - type: bool - required: no -+ krb_name: -+ description: The krb5 config file name -+ type: str -+ required: yes - author: - - Thomas Woerner (@t-woerner) - ''' -@@ -111,27 +107,25 @@ EXAMPLES = ''' - - name: Join IPA in force mode with maximum 5 kinit attempts - ipaclient_join: - servers: ["server1.example.com","server2.example.com"] -- domain: example.com - realm: EXAMPLE.COM -- kdc: server1.example.com - basedn: dc=example,dc=com - hostname: client1.example.com - principal: admin - password: MySecretPassword - force_join: yes - kinit_attempts: 5 -+ krb_name: /tmp/tmpkrb5.conf - - # Join IPA to get the keytab using ipadiscovery return values - - name: Join IPA - ipaclient_join: - servers: "{{ ipadiscovery.servers }}" -- domain: "{{ ipadiscovery.domain }}" - realm: "{{ ipadiscovery.realm }}" -- kdc: "{{ ipadiscovery.kdc }}" - basedn: "{{ ipadiscovery.basedn }}" - hostname: "{{ ipadiscovery.hostname }}" - principal: admin - password: MySecretPassword -+ krb_name: /tmp/tmpkrb5.conf - ''' - - RETURN = ''' -@@ -147,9 +141,9 @@ import tempfile - from ansible.module_utils.basic import AnsibleModule - from ansible.module_utils.ansible_ipa_client import ( - setup_logging, check_imports, -- SECURE_PATH, sysrestore, paths, options, configure_krb5_conf, -- realm_to_suffix, kinit_keytab, GSSError, kinit_password, NUM_VERSION, -- get_ca_cert, get_ca_certs, errors, run -+ SECURE_PATH, sysrestore, paths, options, realm_to_suffix, kinit_keytab, -+ GSSError, kinit_password, NUM_VERSION, get_ca_cert, get_ca_certs, errors, -+ run - ) - - -@@ -157,10 +151,8 @@ def main(): - module = AnsibleModule( - argument_spec=dict( - servers=dict(required=True, type='list', elements='str'), -- domain=dict(required=True, type='str'), - realm=dict(required=True, type='str'), - hostname=dict(required=True, type='str'), -- kdc=dict(required=True, type='str'), - basedn=dict(required=True, type='str'), - principal=dict(required=False, type='str'), - password=dict(required=False, type='str', no_log=True), -@@ -170,6 +162,7 @@ def main(): - force_join=dict(required=False, type='bool'), - kinit_attempts=dict(required=False, type='int', default=5), - debug=dict(required=False, type='bool'), -+ krb_name=dict(required=True, type='str'), - ), - supports_check_mode=False, - ) -@@ -179,11 +172,9 @@ def main(): - setup_logging() - - servers = module.params.get('servers') -- domain = module.params.get('domain') - realm = module.params.get('realm') - hostname = module.params.get('hostname') - basedn = module.params.get('basedn') -- kdc = module.params.get('kdc') - force_join = module.params.get('force_join') - principal = module.params.get('principal') - password = module.params.get('password') -@@ -192,6 +183,7 @@ def main(): - ca_cert_file = module.params.get('ca_cert_file') - kinit_attempts = module.params.get('kinit_attempts') - debug = module.params.get('debug') -+ krb_name = module.params.get('krb_name') - - if password is not None and keytab is not None: - module.fail_json(msg="Password and keytab cannot be used together") -@@ -199,12 +191,10 @@ def main(): - if password is None and admin_keytab is None: - module.fail_json(msg="Password or admin_keytab is needed") - -- client_domain = hostname[hostname.find(".") + 1:] - nolog = tuple() - env = {'PATH': SECURE_PATH} - fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) - host_principal = 'host/%s@%s' % (hostname, realm) -- sssd = True - - options.ca_cert_file = ca_cert_file - options.principal = principal -@@ -215,19 +205,6 @@ def main(): - changed = False - already_joined = False - try: -- (krb_fd, krb_name) = tempfile.mkstemp() -- os.close(krb_fd) -- configure_krb5_conf( -- cli_realm=realm, -- cli_domain=domain, -- cli_server=servers, -- cli_kdc=kdc, -- dnsok=False, -- filename=krb_name, -- client_domain=client_domain, -- client_hostname=hostname, -- configure_sssd=sssd, -- force=False) - env['KRB5_CONFIG'] = krb_name - ccache_dir = tempfile.mkdtemp(prefix='krbcc') - ccache_name = os.path.join(ccache_dir, 'ccache') -@@ -336,27 +313,17 @@ def main(): - paths.IPA_DNS_CCACHE, - config=krb_name, - attempts=kinit_attempts) -- env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = paths.IPA_DNS_CCACHE - except GSSError as e: - # failure to get ticket makes it impossible to login and - # bind from sssd to LDAP, abort installation - module.fail_json(msg="Failed to obtain host TGT: %s" % e) - - finally: -- try: -- os.remove(krb_name) -- except OSError: -- module.fail_json(msg="Could not remove %s" % krb_name) - if ccache_dir is not None: - try: - os.rmdir(ccache_dir) - except OSError: - pass -- if os.path.exists(krb_name + ".ipabkp"): -- try: -- os.remove(krb_name + ".ipabkp") -- except OSError: -- module.fail_json(msg="Could not remove %s.ipabkp" % krb_name) - - module.exit_json(changed=changed, - already_joined=already_joined) -diff --git a/roles/ipaclient/library/ipaclient_setup_certmonger.py b/roles/ipaclient/library/ipaclient_setup_certmonger.py -new file mode 100644 -index 0000000..5c81b40 ---- /dev/null -+++ b/roles/ipaclient/library/ipaclient_setup_certmonger.py -@@ -0,0 +1,123 @@ -+# -*- coding: utf-8 -*- -+ -+# Authors: -+# Thomas Woerner -+# -+# Based on ipa-client-install code -+# -+# Copyright (C) 2017-2022 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 . -+ -+from __future__ import (absolute_import, division, print_function) -+ -+__metaclass__ = type -+ -+ANSIBLE_METADATA = { -+ 'metadata_version': '1.0', -+ 'supported_by': 'community', -+ 'status': ['preview'], -+} -+ -+DOCUMENTATION = ''' -+--- -+module: ipaclient_setup_certmonger -+short_description: Setup certmonger for IPA client -+description: Setup certmonger for IPA client -+options: -+ realm: -+ description: Kerberos realm name of the IPA deployment -+ type: str -+ required: yes -+ hostname: -+ description: Fully qualified name of this host -+ type: str -+ required: yes -+ subject_base: -+ description: | -+ The certificate subject base (default O=). -+ RDNs are in LDAP order (most specific RDN first). -+ type: str -+ required: yes -+ ca_enabled: -+ description: Whether the Certificate Authority is enabled or not -+ type: bool -+ required: yes -+ request_cert: -+ description: Request certificate for the machine -+ type: bool -+ required: yes -+author: -+ - Thomas Woerner (@t-woerner) -+''' -+ -+EXAMPLES = ''' -+- name: Setup certmonger for IPA client -+ ipaclient_setup_certmonger: -+ realm: EXAMPLE.COM -+ hostname: client1.example.com -+ subject_base: O=EXAMPLE.COM -+ ca_enabled: true -+ request_cert: false -+''' -+ -+RETURN = ''' -+''' -+ -+from ansible.module_utils.basic import AnsibleModule -+from ansible.module_utils.ansible_ipa_client import ( -+ setup_logging, check_imports, -+ options, sysrestore, paths, ScriptError, configure_certmonger -+) -+ -+ -+def main(): -+ module = AnsibleModule( -+ argument_spec=dict( -+ realm=dict(required=True, type='str'), -+ hostname=dict(required=True, type='str'), -+ subject_base=dict(required=True, type='str'), -+ ca_enabled=dict(required=True, type='bool'), -+ request_cert=dict(required=True, type='bool'), -+ ), -+ supports_check_mode=False, -+ ) -+ -+ module._ansible_debug = True -+ check_imports(module) -+ setup_logging() -+ -+ cli_realm = module.params.get('realm') -+ hostname = module.params.get('hostname') -+ subject_base = module.params.get('subject_base') -+ ca_enabled = module.params.get('ca_enabled') -+ -+ fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) -+ -+ options.request_cert = module.params.get('request_cert') -+ options.hostname = hostname -+ -+ try: -+ configure_certmonger(fstore, subject_base, cli_realm, hostname, -+ options, ca_enabled) -+ -+ except ScriptError as e: -+ module.fail_json(msg=str(e)) -+ -+ module.exit_json(changed=True) -+ -+ -+if __name__ == '__main__': -+ main() -diff --git a/roles/ipaclient/library/ipaclient_setup_nss.py b/roles/ipaclient/library/ipaclient_setup_nss.py -index 3dc0dcc..240bc76 100644 ---- a/roles/ipaclient/library/ipaclient_setup_nss.py -+++ b/roles/ipaclient/library/ipaclient_setup_nss.py -@@ -177,7 +177,7 @@ from ansible.module_utils.ansible_ipa_client import ( - options, sysrestore, paths, ansible_module_get_parsed_ip_addresses, - api, errors, create_ipa_nssdb, ipautil, ScriptError, CLIENT_INSTALL_ERROR, - get_certs_from_ldap, DN, certstore, x509, logger, certdb, -- CalledProcessError, tasks, client_dns, configure_certmonger, services, -+ CalledProcessError, tasks, client_dns, services, - update_ssh_keys, save_state, configure_ldap_conf, configure_nslcd_conf, - configure_openldap_conf, hardcode_ldap_server, getargspec, NUM_VERSION, - serialization -@@ -350,8 +350,6 @@ def main(): - - if not options.on_master: - client_dns(cli_server[0], hostname, options) -- configure_certmonger(fstore, subject_base, cli_realm, hostname, -- options, ca_enabled) - - if hasattr(paths, "SSH_CONFIG_DIR"): - ssh_config_dir = paths.SSH_CONFIG_DIR -diff --git a/roles/ipaclient/library/ipaclient_temp_krb5.py b/roles/ipaclient/library/ipaclient_temp_krb5.py -new file mode 100644 -index 0000000..cbe652c ---- /dev/null -+++ b/roles/ipaclient/library/ipaclient_temp_krb5.py -@@ -0,0 +1,163 @@ -+# -*- coding: utf-8 -*- -+ -+# Authors: -+# Thomas Woerner -+# -+# Based on ipa-client-install code -+# -+# Copyright (C) 2017-2022 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 . -+ -+from __future__ import (absolute_import, division, print_function) -+ -+__metaclass__ = type -+ -+ANSIBLE_METADATA = { -+ 'metadata_version': '1.0', -+ 'supported_by': 'community', -+ 'status': ['preview'], -+} -+ -+DOCUMENTATION = ''' -+--- -+module: ipaclient_temp_krb5 -+short_description: -+ Create temporary krb5 configuration. -+description: -+ Create temporary krb5 configuration for deferring the creation of the final -+ krb5.conf on clients -+options: -+ servers: -+ description: Fully qualified name of IPA servers to enroll to -+ type: list -+ elements: str -+ required: yes -+ domain: -+ description: Primary DNS domain of the IPA deployment -+ type: str -+ required: yes -+ realm: -+ description: Kerberos realm name of the IPA deployment -+ type: str -+ required: yes -+ hostname: -+ description: Fully qualified name of this host -+ type: str -+ required: yes -+ kdc: -+ description: The name or address of the host running the KDC -+ type: str -+ required: yes -+ on_master: -+ description: Whether the configuration is done on the master or not -+ type: bool -+ required: no -+ default: no -+author: -+ - Thomas Woerner (@t-woerner) -+''' -+ -+EXAMPLES = ''' -+# Test IPA with local keytab -+- name: Test IPA in force mode with maximum 5 kinit attempts -+ ipaclient_test_keytab: -+ servers: ["server1.example.com","server2.example.com"] -+ domain: example.com -+ realm: EXAMPLE.COM -+ kdc: server1.example.com -+ hostname: client1.example.com -+ -+# Test IPA with ipadiscovery return values -+- name: Join IPA -+ ipaclient_test_keytab: -+ servers: "{{ ipadiscovery.servers }}" -+ domain: "{{ ipadiscovery.domain }}" -+ realm: "{{ ipadiscovery.realm }}" -+ kdc: "{{ ipadiscovery.kdc }}" -+ hostname: "{{ ipadiscovery.hostname }}" -+''' -+ -+RETURN = ''' -+krb_name: -+ description: The krb5 config file name -+ returned: always -+ type: str -+''' -+ -+import os -+import tempfile -+ -+from ansible.module_utils.basic import AnsibleModule -+from ansible.module_utils.ansible_ipa_client import ( -+ setup_logging, check_imports, configure_krb5_conf -+) -+ -+ -+def main(): -+ module = AnsibleModule( -+ argument_spec=dict( -+ servers=dict(required=True, type='list', elements='str'), -+ domain=dict(required=True, type='str'), -+ realm=dict(required=True, type='str'), -+ hostname=dict(required=True, type='str'), -+ kdc=dict(required=True, type='str'), -+ on_master=dict(required=False, type='bool', default=False), -+ ), -+ supports_check_mode=False, -+ ) -+ -+ module._ansible_debug = True -+ check_imports(module) -+ setup_logging() -+ -+ servers = module.params.get('servers') -+ domain = module.params.get('domain') -+ realm = module.params.get('realm') -+ hostname = module.params.get('hostname') -+ kdc = module.params.get('kdc') -+ client_domain = hostname[hostname.find(".") + 1:] -+ -+ krb_name = None -+ # Create temporary krb5 configuration -+ try: -+ (krb_fd, krb_name) = tempfile.mkstemp() -+ os.close(krb_fd) -+ configure_krb5_conf( -+ cli_realm=realm, -+ cli_domain=domain, -+ cli_server=servers, -+ cli_kdc=kdc, -+ dnsok=False, -+ filename=krb_name, -+ client_domain=client_domain, -+ client_hostname=hostname, -+ configure_sssd=True, -+ force=False) -+ except Exception as ex: -+ if krb_name: -+ try: -+ os.remove(krb_name) -+ except OSError: -+ module.fail_json(msg="Could not remove %s" % krb_name) -+ module.fail_json( -+ msg="Failed to create temporary krb5 configuration: %s" % str(ex)) -+ -+ module.exit_json(changed=False, -+ krb_name=krb_name) -+ -+ -+if __name__ == '__main__': -+ main() -diff --git a/roles/ipaclient/library/ipaclient_test_keytab.py b/roles/ipaclient/library/ipaclient_test_keytab.py -index 3f1c69d..3bebeea 100644 ---- a/roles/ipaclient/library/ipaclient_test_keytab.py -+++ b/roles/ipaclient/library/ipaclient_test_keytab.py -@@ -244,6 +244,12 @@ def main(): - os.remove(krb_name) - except OSError: - module.fail_json(msg="Could not remove %s" % krb_name) -+ if os.path.exists(krb_name + ".ipabkp"): -+ try: -+ os.remove(krb_name + ".ipabkp") -+ except OSError: -+ module.fail_json( -+ msg="Could not remove %s.ipabkp" % krb_name) - - module.exit_json(changed=False, - krb5_keytab_ok=krb5_keytab_ok, -diff --git a/roles/ipaclient/tasks/install.yml b/roles/ipaclient/tasks/install.yml -index fa33f89..1b889d0 100644 ---- a/roles/ipaclient/tasks/install.yml -+++ b/roles/ipaclient/tasks/install.yml -@@ -239,12 +239,19 @@ - hostname: "{{ result_ipaclient_test.hostname }}" - when: not ipaclient_on_master | bool - -- - name: Install - Join IPA -- ipaclient_join: -+ - name: Install - Create temporary krb5 configuration -+ ipaclient_temp_krb5: - servers: "{{ result_ipaclient_test.servers }}" - domain: "{{ result_ipaclient_test.domain }}" - realm: "{{ result_ipaclient_test.realm }}" -+ hostname: "{{ result_ipaclient_test.hostname }}" - kdc: "{{ result_ipaclient_test.kdc }}" -+ register: result_ipaclient_temp_krb5 -+ -+ - name: Install - Join IPA -+ ipaclient_join: -+ servers: "{{ result_ipaclient_test.servers }}" -+ realm: "{{ result_ipaclient_test.realm }}" - basedn: "{{ result_ipaclient_test.basedn }}" - hostname: "{{ result_ipaclient_test.hostname }}" - force_join: "{{ ipaclient_force_join | default(omit) }}" -@@ -255,6 +262,7 @@ - admin_keytab: "{{ ipaadmin_keytab if ipaadmin_keytab is defined and not ipaclient_use_otp | bool else omit }}" - # ca_cert_file: "{{ ipaclient_ca_cert_file | default(omit) }}" - kinit_attempts: "{{ ipaclient_kinit_attempts | default(omit) }}" -+ krb_name: "{{ result_ipaclient_temp_krb5.krb_name }}" - register: result_ipaclient_join - when: not ipaclient_on_master | bool and - (not result_ipaclient_test_keytab.krb5_keytab_ok or -@@ -323,26 +331,13 @@ - "{{ ipassd_no_krb5_offline_passwords - | default(ipasssd_no_krb5_offline_passwords) }}" - -- - name: Install - Configure krb5 for IPA realm -- ipaclient_setup_krb5: -- realm: "{{ result_ipaclient_test.realm }}" -- domain: "{{ result_ipaclient_test.domain }}" -- servers: "{{ result_ipaclient_test.servers }}" -- kdc: "{{ result_ipaclient_test.kdc }}" -- dnsok: "{{ result_ipaclient_test.dnsok }}" -- client_domain: "{{ result_ipaclient_test.client_domain }}" -- hostname: "{{ result_ipaclient_test.hostname }}" -- sssd: "{{ result_ipaclient_test.sssd }}" -- force: "{{ ipaclient_force }}" -- # on_master: "{{ ipaclient_on_master }}" -- when: not ipaclient_on_master | bool -- - - name: Install - IPA API calls for remaining enrollment parts - ipaclient_api: - servers: "{{ result_ipaclient_test.servers }}" - realm: "{{ result_ipaclient_test.realm }}" - hostname: "{{ result_ipaclient_test.hostname }}" - # debug: yes -+ krb_name: "{{ result_ipaclient_temp_krb5.krb_name }}" - register: result_ipaclient_api - - - name: Install - Fix IPA ca -@@ -412,6 +407,36 @@ - domain: "{{ result_ipaclient_test.domain }}" - nisdomain: "{{ ipaclient_nisdomain | default(omit) }}" - when: not ipaclient_no_nisdomain | bool -+ -+ - name: Remove temporary krb5.conf -+ ansible.builtin.file: -+ path: "{{ result_ipaclient_temp_krb5.krb_name }}" -+ state: absent -+ when: result_ipaclient_temp_krb5.krb_name is defined -+ -+ - name: Install - Configure krb5 for IPA realm -+ ipaclient_setup_krb5: -+ realm: "{{ result_ipaclient_test.realm }}" -+ domain: "{{ result_ipaclient_test.domain }}" -+ servers: "{{ result_ipaclient_test.servers }}" -+ kdc: "{{ result_ipaclient_test.kdc }}" -+ dnsok: "{{ result_ipaclient_test.dnsok }}" -+ client_domain: "{{ result_ipaclient_test.client_domain }}" -+ hostname: "{{ result_ipaclient_test.hostname }}" -+ sssd: "{{ result_ipaclient_test.sssd }}" -+ force: "{{ ipaclient_force }}" -+ # on_master: "{{ ipaclient_on_master }}" -+ when: not ipaclient_on_master | bool -+ -+ - name: Install - Configure certmonger -+ ipaclient_setup_certmonger: -+ realm: "{{ result_ipaclient_test.realm }}" -+ hostname: "{{ result_ipaclient_test.hostname }}" -+ subject_base: "{{ result_ipaclient_api.subject_base }}" -+ ca_enabled: "{{ result_ipaclient_api.ca_enabled }}" -+ request_cert: "{{ ipaclient_request_cert }}" -+ when: not ipaclient_on_master | bool -+ - always: - - name: Install - Restore original admin password if overwritten by OTP - no_log: yes -@@ -423,3 +448,15 @@ - ansible.builtin.file: - path: "/etc/ipa/.dns_ccache" - state: absent -+ -+ - name: Remove temporary krb5.conf -+ ansible.builtin.file: -+ path: "{{ result_ipaclient_temp_krb5.krb_name }}" -+ state: absent -+ when: result_ipaclient_temp_krb5.krb_name is defined -+ -+ - name: Remove temporary krb5.conf backup -+ ansible.builtin.file: -+ path: "{{ result_ipaclient_temp_krb5.krb_name }}.ipabkp" -+ state: absent -+ when: result_ipaclient_temp_krb5.krb_name is defined --- -2.39.2 - diff --git a/SOURCES/ansible-freeipa-1.9.2-ipaclient-Defer-krb5-configuration-fix_RHBZ#2189238.patch b/SOURCES/ansible-freeipa-1.9.2-ipaclient-Defer-krb5-configuration-fix_RHBZ#2189238.patch deleted file mode 100644 index dda52d1..0000000 --- a/SOURCES/ansible-freeipa-1.9.2-ipaclient-Defer-krb5-configuration-fix_RHBZ#2189238.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0ec89eb53cf8771b34528ec210b2614370d9b662 Mon Sep 17 00:00:00 2001 -From: Thomas Woerner -Date: Thu, 23 Mar 2023 18:13:08 +0100 -Subject: [PATCH] ipaclient: ipaclient_setup_nss also needs krb_name parameter - -With the fix to defer creating the final krb5.conf on clients a bug has -been introduced with ipaclient_setup_nss: The krb_name parameter that -points to the temporary krb5 configuration was not added to the module. - -With a properly configured DNS (like for example IPA DNS) the krb TXT -records have been present in the DNS configuration. These have been used -automatically as a fallback and broke server affinity for the client. -Without the TXT records creating the IPA NSS database failed with - "Cannot find KDC for realm ..". - -The krb_name parameter has been added to ipaclient_setup_nss and is also -properly set in tasks/install.yml. ---- - roles/ipaclient/library/ipaclient_setup_nss.py | 8 ++++++++ - roles/ipaclient/tasks/install.yml | 1 + - 2 files changed, 9 insertions(+) - -diff --git a/roles/ipaclient/library/ipaclient_setup_nss.py b/roles/ipaclient/library/ipaclient_setup_nss.py -index 74ca9d4..0e8c658 100644 ---- a/roles/ipaclient/library/ipaclient_setup_nss.py -+++ b/roles/ipaclient/library/ipaclient_setup_nss.py -@@ -152,6 +152,10 @@ options: - The dist of nss_ldap or nss-pam-ldapd files if sssd is disabled - required: yes - type: dict -+ krb_name: -+ description: The krb5 config file name -+ type: str -+ required: yes - author: - - Thomas Woerner (@t-woerner) - ''' -@@ -167,6 +171,7 @@ EXAMPLES = ''' - subject_base: O=EXAMPLE.COM - principal: admin - ca_enabled: yes -+ krb_name: /tmp/tmpkrb5.conf - ''' - - RETURN = ''' -@@ -218,6 +223,7 @@ def main(): - no_krb5_offline_passwords=dict(required=False, type='bool'), - no_dns_sshfp=dict(required=False, type='bool', default=False), - nosssd_files=dict(required=True, type='dict'), -+ krb_name=dict(required=True, type='str'), - ), - supports_check_mode=False, - ) -@@ -268,6 +274,8 @@ def main(): - options.sssd = not options.no_sssd - options.no_ac = False - nosssd_files = module.params.get('nosssd_files') -+ krb_name = module.params.get('krb_name') -+ os.environ['KRB5_CONFIG'] = krb_name - - # pylint: disable=invalid-name - CCACHE_FILE = paths.IPA_DNS_CCACHE -diff --git a/roles/ipaclient/tasks/install.yml b/roles/ipaclient/tasks/install.yml -index 662f09a..1dc6fdf 100644 ---- a/roles/ipaclient/tasks/install.yml -+++ b/roles/ipaclient/tasks/install.yml -@@ -382,6 +382,7 @@ - | default(ipasssd_no_krb5_offline_passwords) }}" - no_dns_sshfp: "{{ ipaclient_no_dns_sshfp }}" - nosssd_files: "{{ result_ipaclient_test.nosssd_files }}" -+ krb_name: "{{ result_ipaclient_temp_krb5.krb_name }}" - - - name: Install - Configure SSH and SSHD - ipaclient_setup_ssh: --- -2.39.2 - -From 10d072a8c42e6aa91485661d02b31f79bcc89fc0 Mon Sep 17 00:00:00 2001 -From: Thomas Woerner -Date: Fri, 24 Mar 2023 12:40:32 +0100 -Subject: [PATCH] ipaclient: ipaclient_fix_ca also needs krb_name parameter - -With the fix to defer creating the final krb5.conf on clients a bug has -been introduced with ipaclient_fix_ca: The krb_name parameter that -points to the temporary krb5 configuration was not added to the module - -Without this the server affinity is broken for allow_repair and additionally -ipaclient_fix_ca could fail if krb5 configuration needs to be repraied -and also CA needs to be fixed. - -The krb_name parameter has been added to ipaclient_fix_ca and is also -properly set in tasks/install.yml. ---- - roles/ipaclient/library/ipaclient_fix_ca.py | 8 ++++++++ - roles/ipaclient/tasks/install.yml | 1 + - 2 files changed, 9 insertions(+) - -diff --git a/roles/ipaclient/library/ipaclient_fix_ca.py b/roles/ipaclient/library/ipaclient_fix_ca.py -index 238b316..ede8d56 100644 ---- a/roles/ipaclient/library/ipaclient_fix_ca.py -+++ b/roles/ipaclient/library/ipaclient_fix_ca.py -@@ -54,6 +54,10 @@ options: - the host entry will not be changed on the server - type: bool - required: yes -+ krb_name: -+ description: The krb5 config file name -+ type: str -+ required: yes - author: - - Thomas Woerner (@t-woerner) - ''' -@@ -65,6 +69,7 @@ EXAMPLES = ''' - realm: EXAMPLE.COM - basedn: dc=example,dc=com - allow_repair: yes -+ krb_name: /tmp/tmpkrb5.conf - ''' - - RETURN = ''' -@@ -87,6 +92,7 @@ def main(): - realm=dict(required=True, type='str'), - basedn=dict(required=True, type='str'), - allow_repair=dict(required=True, type='bool'), -+ krb_name=dict(required=True, type='str'), - ), - ) - -@@ -98,6 +104,8 @@ def main(): - realm = module.params.get('realm') - basedn = module.params.get('basedn') - allow_repair = module.params.get('allow_repair') -+ krb_name = module.params.get('krb_name') -+ os.environ['KRB5_CONFIG'] = krb_name - - env = {'PATH': SECURE_PATH} - fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE) -diff --git a/roles/ipaclient/tasks/install.yml b/roles/ipaclient/tasks/install.yml -index 1dc6fdf..7ff2c39 100644 ---- a/roles/ipaclient/tasks/install.yml -+++ b/roles/ipaclient/tasks/install.yml -@@ -346,6 +346,7 @@ - realm: "{{ result_ipaclient_test.realm }}" - basedn: "{{ result_ipaclient_test.basedn }}" - allow_repair: "{{ ipaclient_allow_repair }}" -+ krb_name: "{{ result_ipaclient_temp_krb5.krb_name }}" - when: not ipaclient_on_master | bool and - result_ipaclient_test_keytab.krb5_keytab_ok and - not result_ipaclient_test_keytab.ca_crt_exists --- -2.39.2 - diff --git a/SOURCES/ansible-freeipa-1.9.2-paclient-Fix-allow_repair-with-removed-krb5.conf-an_RHBZ#2189235.patch b/SOURCES/ansible-freeipa-1.9.2-paclient-Fix-allow_repair-with-removed-krb5.conf-an_RHBZ#2189235.patch deleted file mode 100644 index 1d4c186..0000000 --- a/SOURCES/ansible-freeipa-1.9.2-paclient-Fix-allow_repair-with-removed-krb5.conf-an_RHBZ#2189235.patch +++ /dev/null @@ -1,74 +0,0 @@ -From bfeefaf454e3e705e509ed13b2e650ddfd487fa2 Mon Sep 17 00:00:00 2001 -From: Thomas Woerner -Date: Wed, 8 Feb 2023 13:38:12 +0100 -Subject: [PATCH] ipaclient: Fix allow_repair with removed krb5.conf and DNS - lookup - -The test in ipaclient_test_keytab is at first trying to use an existing -krb5.conf to test if the host keytab can be used. With working DNS lookup -an absent krb5.conf is not reported as an error as DNS lookup is -silently used instead. - -A temporary krb5.conf is now used in this test that forces to deactivate -DNS lookups and also to load /etc/krb5.conf. A missing krb5.conf is now -detected properly as the kinit call fails now properly. Thanks to Julien -Rische for this proposal. - -ipaclient_test_keytab is now properly returning the state of usable or -not usable krb5.conf in krb5_conf_ok. This fixes the handling of this -case later on in the role. ---- - .../library/ipaclient_test_keytab.py | 27 +++++++++++++++++-- - 1 file changed, 25 insertions(+), 2 deletions(-) - -diff --git a/roles/ipaclient/library/ipaclient_test_keytab.py b/roles/ipaclient/library/ipaclient_test_keytab.py -index a86b237..3f1c69d 100644 ---- a/roles/ipaclient/library/ipaclient_test_keytab.py -+++ b/roles/ipaclient/library/ipaclient_test_keytab.py -@@ -159,11 +159,29 @@ def main(): - ca_crt_exists = os.path.exists(paths.IPA_CA_CRT) - env = {'PATH': SECURE_PATH, 'KRB5CCNAME': paths.IPA_DNS_CCACHE} - -- # First try: Validate krb5 keytab with system krb5 configuraiton -+ # First try: Validate with temporary test krb5.conf that forces -+ # 1) no DNS lookups and -+ # 2) to load /etc/krb5.conf: -+ # -+ # [libdefaults] -+ # dns_lookup_realm = false -+ # dns_lookup_kdc = false -+ # include /etc/krb5.conf -+ # - try: -+ (krb_fd, krb_name) = tempfile.mkstemp() -+ os.close(krb_fd) -+ content = "\n".join([ -+ "[libdefaults]", -+ "dns_lookup_realm = false", -+ "dns_lookup_kdc = false", -+ "include /etc/krb5.conf" -+ ]) -+ with open(krb_name, "w") as outf: -+ outf.write(content) - kinit_keytab(host_principal, paths.KRB5_KEYTAB, - paths.IPA_DNS_CCACHE, -- config=paths.KRB5_CONF, -+ config=krb_name, - attempts=kinit_attempts) - krb5_keytab_ok = True - krb5_conf_ok = True -@@ -177,6 +195,11 @@ def main(): - pass - except GSSError: - pass -+ finally: -+ try: -+ os.remove(krb_name) -+ except OSError: -+ module.fail_json(msg="Could not remove %s" % krb_name) - - # Second try: Validate krb5 keytab with temporary krb5 - # configuration --- -2.39.2 - diff --git a/SPECS/ansible-freeipa.spec b/SPECS/ansible-freeipa.spec index 7a1c0e4..6159a70 100644 --- a/SPECS/ansible-freeipa.spec +++ b/SPECS/ansible-freeipa.spec @@ -7,14 +7,11 @@ Summary: Roles and playbooks to deploy FreeIPA servers, replicas and clients Name: ansible-freeipa -Version: 1.9.2 -Release: 2%{?dist} +Version: 1.12.1 +Release: 1%{?dist} URL: https://github.com/freeipa/ansible-freeipa -License: GPLv3+ +License: GPL-3.0-or-later Source: https://github.com/freeipa/ansible-freeipa/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz -Patch1: ansible-freeipa-1.9.2-paclient-Fix-allow_repair-with-removed-krb5.conf-an_RHBZ#2189235.patch -Patch2: ansible-freeipa-1.9.2-ipaclient-Defer-creating-the-final-krb5.conf-on-clients_RHBZ#2189238.patch -Patch3: ansible-freeipa-1.9.2-ipaclient-Defer-krb5-configuration-fix_RHBZ#2189238.patch BuildArch: noarch %description @@ -38,6 +35,7 @@ Features - Modules for automount key management - Modules for automount location management - Modules for automount map management +- Modules for certificate management - Modules for config management - Modules for delegation management - Modules for dns config management @@ -50,7 +48,11 @@ Features - Modules for hbacsvcgroup management - Modules for host management - Modules for hostgroup management +- Modules for idoverridegroup management +- Modules for idoverrideuser management +- Modules for idp management - Modules for idrange management +- Modules for idview management - Modules for location management - Modules for netgroup management - Modules for permission management @@ -88,7 +90,7 @@ Supported Distributions Requirements Controller - - Ansible version: 2.8+ (ansible-freeipa is an Ansible Collection) + - Ansible version: 2.13+ Node - Supported FreeIPA version (see above) @@ -116,9 +118,6 @@ to get the needed requrements to run the tests. %prep %setup -q # Do not create backup files with patches -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 # Fix python modules and module utils: # - Remove shebang @@ -126,12 +125,14 @@ to get the needed requrements to run the tests. for i in roles/ipa*/library/*.py roles/ipa*/module_utils/*.py plugins/*/*.py; do sed -i '1{/\/usr\/bin\/python*/d;}' $i + sed -i '1{/\/usr\/bin\/env python*/d;}' $i chmod a-x $i done for i in utils/*.py utils/new_module utils/changelog utils/ansible-doc-test; do sed -i '{s@/usr/bin/python*@%{python}@}' $i + sed -i '{s@/usr/bin/env python*@%{python}@}' $i done @@ -182,11 +183,98 @@ cp -rp tests %{buildroot}%{_datadir}/ansible-freeipa/ %{_datadir}/ansible-freeipa/requirements-tests.txt %changelog -* Mon Apr 24 2023 Thomas Woerner - 1.9.2-2 +* Mon Feb 12 2024 Thomas Woerner - 1.12.1-1 +- Update to version 1.12.1 + https://github.com/freeipa/ansible-freeipa/releases/tag/v1.12.1 + Resolves: RHEL-13746 +- ipauser module lacks the "rename" field. + Resolves: RHEL-4963 +- Add missing support for rename in ipagroup module + Resolves: RHEL-13759 +- The IDP module does not support the modification of IDP options + Resolves: RHEL-17955 +- The IDP module does not support resetting IDP options + Resolves: RHEL-17958 +- ipauser is not idempotent when random is defined + Resolves: RHEL-4934 +- ipasudorule: Allow setting groups for runasuser + Resolves: RHEL-19129 +- Idempotency fixes + Resolves: RHEL-13755 +- ipadnszone: Add support for per-zone privilege delegation + Resolves: RHEL-19133 +- Handle data type or empty string in module_utils + Resolves: RHEL-19135 +- ipa-server installation failing + Resolves: RHEL-23633 + +* Tue Nov 28 2023 Thomas Woerner - 1.12.0-2 +- Fix test_pwpolicy for https://pagure.io/freeipa/issue/9297 + Related: RHEL-13746 + +* Mon Nov 27 2023 Thomas Woerner - 1.12.0-1 +- Update to version 1.12.0 + https://github.com/freeipa/ansible-freeipa/releases/tag/v1.12.0 + Resolves: RHEL-13746 +- New idoverridegroup management module. + Resolves: RHEL-16935 +- New idoverrideuser management module. + Resolves: RHEL-16941 +- New idview management module. + Resolves: RHEL-16933 +- New idp management module. + Resolves: RHEL-16938 +- idoverride{user,group}: Fix delete_continue with state absent + Resolves: RHEL-16682 + +* Mon Jul 24 2023 Thomas Woerner - 1.11.1-1 +- Update to version 1.11.1 + https://github.com/freeipa/ansible-freeipa/releases/tag/v1.11.1 + Resolves: RHBZ#2170371 +- ipaautomountmap: add support for indirect maps + Resolves: RHBZ#2050158 +- ipauser: Add support to modify GECOS field + Resolves: RHBZ#2168022 +- ipauser: Add support for parameter "street" + Resolves: RHBZ#2215532 +- ipauser: Add support for SMB attributes + Resolves: RHBZ#2215534 +- ipauser: Support for External IdP attributes + Resolves: RHBZ#2215539 +- Fix handling of ipapwpolicy attributes usercheck and dictcheck + Resolves: RHBZ#2215543 +- Update authtypes authind + Resolves: RHBZ#2215540 + +* Mon Jun 12 2023 Thomas Woerner - 1.11.0-1 +- Update to version 1.11.0 + https://github.com/freeipa/ansible-freeipa/releases/tag/v1.11.0 + Resolves: RHBZ#2170371 +- Multiple service management + Resolves: RHBZ#2175769 +- New ipacert module + Resolves: RHBZ#2127906 +- Fix maxsequence handling in ipapwpolicy module + Resolves: RHBZ#2214295 + +* Wed Apr 5 2023 Thomas Woerner - 1.10.0-1 +- Update to version 1.10.0 + https://github.com/freeipa/ansible-freeipa/releases/tag/v1.10.0 + Resolves: RHBZ#2170371 +- ipareplica/server: Enable removal from domain with undeployment + Resolves: RHBZ#2127901 +- ipagroup: Allow multiple group management + Resolves: RHBZ#2175762 +- ipaserver: Allow deployments with random serial numbers + Resolves: RHBZ#2127904 +- ipagroup: Fix ensuring external group members (without trust-ad) + Resolves: RHBZ#2183820 +- ipaclient: Add subid option to select the sssd profile with-subid + Resolves: RHBZ#2175766 - ipaclient: Fix allow_repair with removed krb5.conf and DNS lookup - Resolves: RHBZ#2189235 -- ipaclient: Defer creating the final krb5.conf on clients - Resolves: RHBZ#2189238 + Resolves: RHBZ#1759785 +- ipaclient: Keep server affinity while deploying as long as possible + Resolves: RHBZ#2175755 * Tue Jan 31 2023 Thomas Woerner - 1.9.2-1 - Update to version 1.9.2