From eba457d5ff34a1dfc3a584228fa044205f45ea18 Mon Sep 17 00:00:00 2001
From: Thomas Woerner <twoerner@redhat.com>
Date: Wed, 27 Jul 2022 13:09:50 +0200
Subject: [PATCH] ipaserver/ipareplica: Always generate SIDs

The SID is always generated in the command line installers in newer IPA
versions. This also needs to be done in the ipaserver and ipareplica roles.

For the IPA versions that are supporting this, the adtrust setup is always
executed to generated the SIDs, but only configures AD trust if
ipaserver_setup_adtrust or ipareplica_setup_adtrust is also enabled. A
check has been added to ipaserver_test and ipareplica_test to only enable
the SID generation for the IPA versions supporting this.

This is related to https://pagure.io/freeipa/8995

Fixes:
- https://bugzilla.redhat.com/show_bug.cgi?id=2110478
- https://bugzilla.redhat.com/show_bug.cgi?id=2110491
---
 .../ipareplica/library/ipareplica_prepare.py  |  8 ++++++-
 .../library/ipareplica_setup_adtrust.py       |  5 ++++
 roles/ipareplica/library/ipareplica_test.py   | 11 ++++++++-
 .../module_utils/ansible_ipa_replica.py       |  4 +++-
 roles/ipareplica/tasks/install.yml            |  4 +++-
 roles/ipaserver/library/ipaserver_prepare.py  |  8 ++++++-
 roles/ipaserver/library/ipaserver_test.py     | 24 ++++++++++++-------
 roles/ipaserver/tasks/install.yml             |  4 +++-
 8 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/roles/ipareplica/library/ipareplica_prepare.py b/roles/ipareplica/library/ipareplica_prepare.py
index a875d6d5..d93b5686 100644
--- a/roles/ipareplica/library/ipareplica_prepare.py
+++ b/roles/ipareplica/library/ipareplica_prepare.py
@@ -182,6 +182,9 @@ options:
   skip_conncheck:
     description: Skip connection check to remote master
     required: yes
+  sid_generation_always:
+    description: Enable SID generation always
+    required: yes
 author:
     - Thomas Woerner
 '''
@@ -275,6 +278,8 @@ def main():
             # additional
             server=dict(required=True),
             skip_conncheck=dict(required=False, type='bool'),
+            sid_generation_always=dict(required=False, type='bool',
+                                       default=False),
         ),
         supports_check_mode=True,
     )
@@ -350,6 +355,7 @@ def main():
     #     '_hostname_overridden')
     options.server = ansible_module.params.get('server')
     options.skip_conncheck = ansible_module.params.get('skip_conncheck')
+    sid_generation_always = ansible_module.params.get('sid_generation_always')
 
     # random serial numbers are master_only, therefore setting to False
     options.random_serial_numbers = False
@@ -761,7 +767,7 @@ def main():
 
         ansible_log.debug("-- CHECK ADTRUST --")
 
-        if options.setup_adtrust:
+        if options.setup_adtrust or sid_generation_always:
             adtrust.install_check(False, options, remote_api)
 
     except errors.ACIError:
diff --git a/roles/ipareplica/library/ipareplica_setup_adtrust.py b/roles/ipareplica/library/ipareplica_setup_adtrust.py
index 0c99a285..3532bb1a 100644
--- a/roles/ipareplica/library/ipareplica_setup_adtrust.py
+++ b/roles/ipareplica/library/ipareplica_setup_adtrust.py
@@ -71,6 +71,9 @@ options:
   setup_ca:
     description: Configure a dogtag CA
     required: no
+  setup_adtrust:
+    description: Configure AD trust capability
+    required: yes
   config_master_host_name:
     description: The config master_host_name setting
     required: no
@@ -112,6 +115,7 @@ def main():
             ccache=dict(required=True),
             _top_dir=dict(required=True),
             setup_ca=dict(required=True, type='bool'),
+            setup_adtrust=dict(required=True, type='bool'),
             config_master_host_name=dict(required=True),
         ),
         supports_check_mode=True,
@@ -140,6 +144,7 @@ def main():
     os.environ['KRB5CCNAME'] = ccache
     options._top_dir = ansible_module.params.get('_top_dir')
     options.setup_ca = ansible_module.params.get('setup_ca')
+    options.setup_adtrust = ansible_module.params.get('setup_adtrust')
     config_master_host_name = ansible_module.params.get(
         'config_master_host_name')
     adtrust.netbios_name = ansible_module.params.get('adtrust_netbios_name')
diff --git a/roles/ipareplica/library/ipareplica_test.py b/roles/ipareplica/library/ipareplica_test.py
index 7ec6fb16..f34f3ed7 100644
--- a/roles/ipareplica/library/ipareplica_test.py
+++ b/roles/ipareplica/library/ipareplica_test.py
@@ -143,7 +143,7 @@ from ansible.module_utils.ansible_ipa_replica import (
     ansible_module_get_parsed_ip_addresses, service,
     redirect_stdout, create_ipa_conf, ipautil,
     x509, validate_domain_name, common_check,
-    IPA_PYTHON_VERSION, getargspec
+    IPA_PYTHON_VERSION, getargspec, adtrustinstance
 )
 
 
@@ -270,6 +270,14 @@ def main():
     #    #  options.setup_adtrust = False
     #    #  ansible_module.warn(msg="adtrust is not supported, disabling")
 
+    sid_generation_always = False
+    if not options.setup_adtrust:
+        # pylint: disable=deprecated-method
+        argspec = getargspec(adtrustinstance.ADTRUSTInstance.__init__)
+        # pylint: enable=deprecated-method
+        if "fulltrust" in argspec.args:
+            sid_generation_always = True
+
     # if options.setup_kra and not kra_imported:
     #    # if "kra" not in options._allow_missing:
     #    ansible_module.fail_json(msg="kra can not be imported")
@@ -471,6 +479,7 @@ def main():
         # additional
         client_enrolled=client_enrolled,
         change_master_for_certmonger=change_master_for_certmonger,
+        sid_generation_always=sid_generation_always
     )
 
 
diff --git a/roles/ipareplica/module_utils/ansible_ipa_replica.py b/roles/ipareplica/module_utils/ansible_ipa_replica.py
index 5b687231..0e4e7388 100644
--- a/roles/ipareplica/module_utils/ansible_ipa_replica.py
+++ b/roles/ipareplica/module_utils/ansible_ipa_replica.py
@@ -46,7 +46,8 @@ __all__ = ["contextlib", "dnsexception", "dnsresolver", "dnsreversename",
            "common_check", "current_domain_level",
            "check_domain_level_is_supported", "promotion_check_ipa_domain",
            "SSSDConfig", "CalledProcessError", "timeconf", "ntpinstance",
-           "dnsname", "kernel_keyring", "krbinstance", "getargspec"]
+           "dnsname", "kernel_keyring", "krbinstance", "getargspec",
+           "adtrustinstance"]
 
 import sys
 
@@ -127,6 +128,7 @@ else:
             adtrust, bindinstance, ca, certs, dns, dsinstance, httpinstance,
             installutils, kra, krbinstance,
             otpdinstance, custodiainstance, service, upgradeinstance)
+        from ipaserver.install import adtrustinstance
         try:
             from ipaserver.masters import (
                 find_providing_servers, find_providing_server)
diff --git a/roles/ipareplica/tasks/install.yml b/roles/ipareplica/tasks/install.yml
index 0a9d7e9d..0e5f840e 100644
--- a/roles/ipareplica/tasks/install.yml
+++ b/roles/ipareplica/tasks/install.yml
@@ -749,13 +749,15 @@
       ccache: "{{ result_ipareplica_prepare.ccache }}"
       _top_dir: "{{ result_ipareplica_prepare._top_dir }}"
       setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
+      setup_adtrust: "{{ result_ipareplica_test.setup_adtrust }}"
       config_master_host_name:
         "{{ result_ipareplica_prepare.config_master_host_name }}"
       adtrust_netbios_name:
         "{{ result_ipareplica_prepare.adtrust_netbios_name }}"
       adtrust_reset_netbios_name:
         "{{ result_ipareplica_prepare.adtrust_reset_netbios_name }}"
-    when: result_ipareplica_test.setup_adtrust
+    when: result_ipareplica_test.setup_adtrust or
+          result_ipareplica_test.sid_generation_always
 
   - name: Install - Enable IPA
     ipareplica_enable_ipa:
diff --git a/roles/ipaserver/library/ipaserver_prepare.py b/roles/ipaserver/library/ipaserver_prepare.py
index f7590be8..c9da872d 100644
--- a/roles/ipaserver/library/ipaserver_prepare.py
+++ b/roles/ipaserver/library/ipaserver_prepare.py
@@ -141,6 +141,9 @@ options:
   setup_ca:
     description: Configure a dogtag CA
     required: yes
+  sid_generation_always:
+    description: Enable SID generation always
+    required: yes
   _hostname_overridden:
     description: The installer _hostname_overridden setting
     required: yes
@@ -215,6 +218,8 @@ def main():
             setup_ca=dict(required=False, type='bool', default=False),
             random_serial_numbers=dict(required=False, type='bool',
                                        default=False),
+            sid_generation_always=dict(required=False, type='bool',
+                                       default=False),
             _hostname_overridden=dict(required=False, type='bool',
                                       default=False),
         ),
@@ -285,6 +290,7 @@ def main():
         'random_serial_numbers')
     options._host_name_overridden = ansible_module.params.get(
         '_hostname_overridden')
+    sid_generation_always = ansible_module.params.get('sid_generation_always')
     options.kasp_db_file = None
 
     # init ##################################################################
@@ -377,7 +383,7 @@ def main():
             logger.debug('Starting Directory Server')
             services.knownservices.dirsrv.start(instance_name)
 
-        if options.setup_adtrust:
+        if options.setup_adtrust or sid_generation_always:
             with redirect_stdout(ansible_log):
                 adtrust.install_check(False, options, api)
 
diff --git a/roles/ipaserver/library/ipaserver_test.py b/roles/ipaserver/library/ipaserver_test.py
index d619add0..db108b77 100644
--- a/roles/ipaserver/library/ipaserver_test.py
+++ b/roles/ipaserver/library/ipaserver_test.py
@@ -225,7 +225,7 @@ from ansible.module_utils.ansible_ipa_server import (
     read_cache, ca, tasks, check_ldap_conf, timeconf, httpinstance,
     check_dirsrv, ScriptError, get_fqdn, verify_fqdn, BadHostError,
     validate_domain_name, load_pkcs12, IPA_PYTHON_VERSION,
-    encode_certificate, check_available_memory, getargspec
+    encode_certificate, check_available_memory, getargspec, adtrustinstance
 )
 from ansible.module_utils import six
 
@@ -394,12 +394,16 @@ def main():
 
     # version specific ######################################################
 
-    if options.setup_adtrust and not adtrust_imported:
-        # if "adtrust" not in options._allow_missing:
-        ansible_module.fail_json(msg="adtrust can not be imported")
-        # else:
-        #   options.setup_adtrust = False
-        #   ansible_module.warn(msg="adtrust is not supported, disabling")
+    sid_generation_always = False
+    if not options.setup_adtrust:
+        # pylint: disable=deprecated-method
+        argspec = getargspec(adtrustinstance.ADTRUSTInstance.__init__)
+        # pylint: enable=deprecated-method
+        if "fulltrust" in argspec.args:
+            sid_generation_always = True
+    else:
+        if not adtrust_imported:
+            ansible_module.fail_json(msg="adtrust can not be imported")
 
     if options.setup_kra and not kra_imported:
         # if "kra" not in options._allow_missing:
@@ -521,7 +525,8 @@ def main():
                     "You cannot specify an --enable-compat option without the "
                     "--setup-adtrust option")
 
-            if self.netbios_name:
+            # Deactivate test for new IPA SID generation
+            if self.netbios_name and not sid_generation_always:
                 raise RuntimeError(
                     "You cannot specify a --netbios-name option without the "
                     "--setup-adtrust option")
@@ -1078,7 +1083,8 @@ def main():
                              ntp_pool=options.ntp_pool,
                              # additional
                              _installation_cleanup=_installation_cleanup,
-                             domainlevel=options.domainlevel)
+                             domainlevel=options.domainlevel,
+                             sid_generation_always=sid_generation_always)
 
 
 if __name__ == '__main__':
diff --git a/roles/ipaserver/tasks/install.yml b/roles/ipaserver/tasks/install.yml
index 8bd808d4..70ca4b6d 100644
--- a/roles/ipaserver/tasks/install.yml
+++ b/roles/ipaserver/tasks/install.yml
@@ -191,6 +191,7 @@
       secondary_rid_base: "{{ ipaserver_secondary_rid_base | default(omit) }}"
       ### additional ###
       setup_ca: "{{ result_ipaserver_test.setup_ca }}"
+      sid_generation_always: "{{ result_ipaserver_test.sid_generation_always }}"
       random_serial_numbers: no
       _hostname_overridden: "{{ result_ipaserver_test._hostname_overridden }}"
     register: result_ipaserver_prepare
@@ -394,7 +395,8 @@
         adtrust_netbios_name: "{{ result_ipaserver_prepare.adtrust_netbios_name }}"
         adtrust_reset_netbios_name:
           "{{ result_ipaserver_prepare.adtrust_reset_netbios_name }}"
-      when: result_ipaserver_test.setup_adtrust
+      when: result_ipaserver_test.setup_adtrust or
+            result_ipaserver_test.sid_generation_always
 
     - name: Install - Set DS password
       ipaserver_set_ds_password:
-- 
GitLab