pgreco / rpms / ipa

Forked from forks/areguera/rpms/ipa 4 years ago
Clone

Blame SOURCES/0047-Use-single-Custodia-instance-in-installers.patch

7bbb43
From 11e597217fe6f1dcee3a918eef0bc3a0d2928e6d Mon Sep 17 00:00:00 2001
7bbb43
From: Christian Heimes <cheimes@redhat.com>
7bbb43
Date: Thu, 26 Apr 2018 12:06:36 +0200
7bbb43
Subject: [PATCH] Use single Custodia instance in installers
7bbb43
7bbb43
Installers now pass a single CustodiaInstance object around, instead of
7bbb43
creating new instances on demand. In case of replica promotion with CA,
7bbb43
the instance gets all secrets from a master with CA present. Before, an
7bbb43
installer created multiple instances and may have requested CA key
7bbb43
material from a different machine than DM password hash.
7bbb43
7bbb43
In case of Domain Level 1 and replica promotion, the CustodiaInstance no
7bbb43
longer adds the keys to the local instance and waits for replication to
7bbb43
other replica. Instead the installer directly uploads the new public
7bbb43
keys to the remote 389-DS instance.
7bbb43
7bbb43
Without promotion, new Custodia public keys are still added to local
7bbb43
389-DS over LDAPI.
7bbb43
7bbb43
Fixes: https://pagure.io/freeipa/issue/7518
7bbb43
Signed-off-by: Christian Heimes <cheimes@redhat.com>
7bbb43
Reviewed-By: Simo Sorce <ssorce@redhat.com>
7bbb43
Reviewed-By: Simo Sorce <ssorce@redhat.com>
7bbb43
---
7bbb43
 install/tools/ipa-ca-install               |  13 ++-
7bbb43
 ipaserver/install/ca.py                    |  26 +++--
7bbb43
 ipaserver/install/cainstance.py            |   9 +-
7bbb43
 ipaserver/install/custodiainstance.py      | 150 ++++++++++++++++++++++-------
7bbb43
 ipaserver/install/ipa_kra_install.py       |  10 +-
7bbb43
 ipaserver/install/kra.py                   |   6 +-
7bbb43
 ipaserver/install/server/install.py        |  14 +--
7bbb43
 ipaserver/install/server/replicainstall.py |  15 +--
7bbb43
 8 files changed, 165 insertions(+), 78 deletions(-)
7bbb43
7bbb43
diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
7bbb43
index f84b4749a3e2a80aca002a2aa057b200e6187f18..a3694007e5815d1c44f642057c749879d336dfc5 100755
7bbb43
--- a/install/tools/ipa-ca-install
7bbb43
+++ b/install/tools/ipa-ca-install
7bbb43
@@ -31,6 +31,7 @@ from ipaserver.install.installutils import create_replica_config
7bbb43
 from ipaserver.install.installutils import check_creds, ReplicaConfig
7bbb43
 from ipaserver.install import dsinstance, ca
7bbb43
 from ipaserver.install import cainstance, service
7bbb43
+from ipaserver.install import custodiainstance
7bbb43
 from ipapython import version
7bbb43
 from ipalib import api
7bbb43
 from ipalib.constants import DOMAIN_LEVEL_0
7bbb43
@@ -193,13 +194,17 @@ def install_replica(safe_options, options, filename):
7bbb43
     options.domain_name = config.domain_name
7bbb43
     options.dm_password = config.dirman_password
7bbb43
     options.host_name = config.host_name
7bbb43
+    options.ca_host_name = config.ca_host_name
7bbb43
     if os.path.exists(cafile):
7bbb43
         options.ca_cert_file = cafile
7bbb43
     else:
7bbb43
         options.ca_cert_file = None
7bbb43
 
7bbb43
     ca.install_check(True, config, options)
7bbb43
-    ca.install(True, config, options)
7bbb43
+
7bbb43
+    custodia = custodiainstance.get_custodia_instance(
7bbb43
+        options, custodiainstance.CustodiaModes.CA_PEER)
7bbb43
+    ca.install(True, config, options, custodia=custodia)
7bbb43
 
7bbb43
 
7bbb43
 def install_master(safe_options, options):
7bbb43
@@ -228,7 +233,11 @@ def install_master(safe_options, options):
7bbb43
         sys.exit("CA subject: {}".format(e.message))
7bbb43
 
7bbb43
     ca.install_check(True, None, options)
7bbb43
-    ca.install(True, None, options)
7bbb43
+
7bbb43
+    # No CA peer available yet.
7bbb43
+    custodia = custodiainstance.get_custodia_instance(
7bbb43
+        options, custodiainstance.CustodiaModes.STANDALONE)
7bbb43
+    ca.install(True, None, options, custodia=custodia)
7bbb43
 
7bbb43
 
7bbb43
 def install(safe_options, options, filename):
7bbb43
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
7bbb43
index 52cb20f1cb3612394544a6a41f10e9e939bc0657..2ac4382ccd24d217832950b94baddd113f7a8930 100644
7bbb43
--- a/ipaserver/install/ca.py
7bbb43
+++ b/ipaserver/install/ca.py
7bbb43
@@ -19,10 +19,7 @@ from ipalib.install.service import enroll_only, master_install_only, replica_ins
7bbb43
 from ipaserver.install import sysupgrade
7bbb43
 from ipapython.install import typing
7bbb43
 from ipapython.install.core import group, knob, extend_knob
7bbb43
-from ipaserver.install import (cainstance,
7bbb43
-                               custodiainstance,
7bbb43
-                               dsinstance,
7bbb43
-                               bindinstance)
7bbb43
+from ipaserver.install import cainstance, bindinstance, dsinstance
7bbb43
 from ipapython import ipautil, certdb
7bbb43
 from ipapython.admintool import ScriptError
7bbb43
 from ipaplatform import services
7bbb43
@@ -201,12 +198,12 @@ def install_check(standalone, replica_config, options):
7bbb43
                         "cannot continue." % (subject, db.secdir))
7bbb43
 
7bbb43
 
7bbb43
-def install(standalone, replica_config, options):
7bbb43
-    install_step_0(standalone, replica_config, options)
7bbb43
-    install_step_1(standalone, replica_config, options)
7bbb43
+def install(standalone, replica_config, options, custodia):
7bbb43
+    install_step_0(standalone, replica_config, options, custodia=custodia)
7bbb43
+    install_step_1(standalone, replica_config, options, custodia=custodia)
7bbb43
 
7bbb43
 
7bbb43
-def install_step_0(standalone, replica_config, options):
7bbb43
+def install_step_0(standalone, replica_config, options, custodia):
7bbb43
     realm_name = options.realm_name
7bbb43
     dm_password = options.dm_password
7bbb43
     host_name = options.host_name
7bbb43
@@ -237,9 +234,6 @@ def install_step_0(standalone, replica_config, options):
7bbb43
     else:
7bbb43
         cafile = os.path.join(replica_config.dir, 'cacert.p12')
7bbb43
         if options.promote:
7bbb43
-            custodia = custodiainstance.CustodiaInstance(
7bbb43
-                replica_config.host_name,
7bbb43
-                replica_config.realm_name)
7bbb43
             custodia.get_ca_keys(
7bbb43
                 replica_config.ca_host_name,
7bbb43
                 cafile,
7bbb43
@@ -266,7 +260,9 @@ def install_step_0(standalone, replica_config, options):
7bbb43
         'certmap.conf', 'subject_base', str(subject_base))
7bbb43
     dsinstance.write_certmap_conf(realm_name, ca_subject)
7bbb43
 
7bbb43
-    ca = cainstance.CAInstance(realm_name, host_name=host_name)
7bbb43
+    ca = cainstance.CAInstance(
7bbb43
+        realm=realm_name, host_name=host_name, custodia=custodia
7bbb43
+    )
7bbb43
     ca.configure_instance(host_name, dm_password, dm_password,
7bbb43
                           subject_base=subject_base,
7bbb43
                           ca_subject=ca_subject,
7bbb43
@@ -284,7 +280,7 @@ def install_step_0(standalone, replica_config, options):
7bbb43
                           use_ldaps=standalone)
7bbb43
 
7bbb43
 
7bbb43
-def install_step_1(standalone, replica_config, options):
7bbb43
+def install_step_1(standalone, replica_config, options, custodia):
7bbb43
     if replica_config is not None and not replica_config.setup_ca:
7bbb43
         return
7bbb43
 
7bbb43
@@ -293,7 +289,9 @@ def install_step_1(standalone, replica_config, options):
7bbb43
     subject_base = options._subject_base
7bbb43
     basedn = ipautil.realm_to_suffix(realm_name)
7bbb43
 
7bbb43
-    ca = cainstance.CAInstance(realm_name, host_name=host_name)
7bbb43
+    ca = cainstance.CAInstance(
7bbb43
+        realm=realm_name, host_name=host_name, custodia=custodia
7bbb43
+    )
7bbb43
 
7bbb43
     ca.stop('pki-tomcat')
7bbb43
 
7bbb43
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
7bbb43
index 20635eae22268ff72de73b8b9c430050114bb45b..eefc30b6e01dcf744703b8607cbe169fbec5d859 100644
7bbb43
--- a/ipaserver/install/cainstance.py
7bbb43
+++ b/ipaserver/install/cainstance.py
7bbb43
@@ -59,7 +59,6 @@ from ipapython.ipa_log_manager import log_mgr,\
7bbb43
 from ipaserver.secrets.kem import IPAKEMKeys
7bbb43
 
7bbb43
 from ipaserver.install import certs
7bbb43
-from ipaserver.install import custodiainstance
7bbb43
 from ipaserver.install import dsinstance
7bbb43
 from ipaserver.install import installutils
7bbb43
 from ipaserver.install import ldapupdate
7bbb43
@@ -285,7 +284,7 @@ class CAInstance(DogtagInstance):
7bbb43
                      'caSigningCert cert-pki-ca')
7bbb43
     server_cert_name = 'Server-Cert cert-pki-ca'
7bbb43
 
7bbb43
-    def __init__(self, realm=None, host_name=None):
7bbb43
+    def __init__(self, realm=None, host_name=None, custodia=None):
7bbb43
         super(CAInstance, self).__init__(
7bbb43
             realm=realm,
7bbb43
             subsystem="CA",
7bbb43
@@ -310,6 +309,8 @@ class CAInstance(DogtagInstance):
7bbb43
         self.no_db_setup = False
7bbb43
         self.keytab = os.path.join(
7bbb43
             paths.PKI_TOMCAT, self.service_prefix + '.keytab')
7bbb43
+        # Custodia instance for RA key retrieval
7bbb43
+        self._custodia = custodia
7bbb43
 
7bbb43
     def configure_instance(self, host_name, dm_password, admin_password,
7bbb43
                            pkcs12_info=None, master_host=None, csr_file=None,
7bbb43
@@ -711,9 +712,7 @@ class CAInstance(DogtagInstance):
7bbb43
         self.configure_agent_renewal()
7bbb43
 
7bbb43
     def __import_ra_key(self):
7bbb43
-        custodia = custodiainstance.CustodiaInstance(host_name=self.fqdn,
7bbb43
-                                                     realm=self.realm)
7bbb43
-        custodia.import_ra_key(self.master_host)
7bbb43
+        self._custodia.import_ra_key(self.master_host)
7bbb43
         self.__set_ra_cert_perms()
7bbb43
 
7bbb43
         self.configure_agent_renewal()
7bbb43
diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
7bbb43
index 0a90bb3954486b9773e3553e9981d2a8d0d4e44a..262ae5857c64719ff5cebde31b4b107e1245d458 100644
7bbb43
--- a/ipaserver/install/custodiainstance.py
7bbb43
+++ b/ipaserver/install/custodiainstance.py
7bbb43
@@ -1,5 +1,9 @@
7bbb43
 # Copyright (C) 2015 FreeIPa Project Contributors, see 'COPYING' for license.
7bbb43
 
7bbb43
+from __future__ import print_function, absolute_import
7bbb43
+
7bbb43
+import enum
7bbb43
+
7bbb43
 from ipaserver.secrets.kem import IPAKEMKeys, KEMLdap
7bbb43
 from ipaserver.secrets.client import CustodiaClient
7bbb43
 from ipaplatform.paths import paths
7bbb43
@@ -21,12 +25,84 @@ import time
7bbb43
 import pwd
7bbb43
 
7bbb43
 
7bbb43
+class CustodiaModes(enum.Enum):
7bbb43
+    # peer must have a CA
7bbb43
+    CA_PEER = 'Custodia CA peer'
7bbb43
+    # peer must have a CA, KRA preferred
7bbb43
+    KRA_PEER = 'Custodia KRA peer'
7bbb43
+    # any master will do
7bbb43
+    MASTER_PEER = 'Custodia master peer'
7bbb43
+    # standalone / local instance
7bbb43
+    STANDALONE = 'Custodia standalone'
7bbb43
+
7bbb43
+
7bbb43
+def get_custodia_instance(config, mode):
7bbb43
+    """Create Custodia instance
7bbb43
+
7bbb43
+    :param config: configuration/installer object
7bbb43
+    :param mode: CustodiaModes member
7bbb43
+    :return: CustodiaInstance object
7bbb43
+
7bbb43
+    The config object must have the following attribute
7bbb43
+
7bbb43
+    *host_name*
7bbb43
+      FQDN of the new replica/master
7bbb43
+    *realm_name*
7bbb43
+      Kerberos realm
7bbb43
+    *promote*
7bbb43
+      True, when instance will be promoted from client to replica
7bbb43
+    *master_host_name* (for *CustodiaModes.MASTER_PEER*)
7bbb43
+      hostname of a master (may not have a CA)
7bbb43
+    *ca_host_name* (for *CustodiaModes.CA_PEER*)
7bbb43
+      hostname of a master with CA
7bbb43
+    *kra_host_name* (for *CustodiaModes.KRA_PEER*)
7bbb43
+      hostname of a master with KRA or CA
7bbb43
+
7bbb43
+    For promotion, the instance will upload new keys and retrieve secrets
7bbb43
+    from the same host. Therefore it uses *ca_host_name* instead of
7bbb43
+    *master_host_name* to create a replica with CA.
7bbb43
+    """
7bbb43
+    assert isinstance(mode, CustodiaModes)
7bbb43
+    root_logger.info(
7bbb43
+        "Custodia client for '%r' with promotion %s.",
7bbb43
+        mode, 'yes' if config.promote else 'no'
7bbb43
+    )
7bbb43
+    if config.promote:
7bbb43
+        if mode == CustodiaModes.CA_PEER:
7bbb43
+            # In case we install replica with CA, prefer CA host as source for
7bbb43
+            # all Custodia secret material.
7bbb43
+            custodia_master = config.ca_host_name
7bbb43
+        elif mode == CustodiaModes.KRA_PEER:
7bbb43
+            custodia_master = config.kra_host_name
7bbb43
+        elif mode == CustodiaModes.MASTER_PEER:
7bbb43
+            custodia_master = config.master_host_name
7bbb43
+        elif mode == CustodiaModes.STANDALONE:
7bbb43
+            custodia_master = None
7bbb43
+    else:
7bbb43
+        custodia_master = None
7bbb43
+
7bbb43
+    if custodia_master is None:
7bbb43
+        # use ldapi with local dirsrv instance
7bbb43
+        root_logger.info("Custodia uses LDAPI.")
7bbb43
+        ldap_uri = None
7bbb43
+    else:
7bbb43
+        root_logger.info("Custodia uses '%s' as master peer.",
7bbb43
+                         custodia_master)
7bbb43
+        ldap_uri = 'ldap://{}'.format(custodia_master)
7bbb43
+
7bbb43
+    return CustodiaInstance(
7bbb43
+        host_name=config.host_name,
7bbb43
+        realm=config.realm_name,
7bbb43
+        ldap_uri=ldap_uri
7bbb43
+    )
7bbb43
+
7bbb43
+
7bbb43
 class CustodiaInstance(SimpleServiceInstance):
7bbb43
-    def __init__(self, host_name=None, realm=None):
7bbb43
+    def __init__(self, host_name=None, realm=None, ldap_uri=None):
7bbb43
         super(CustodiaInstance, self).__init__("ipa-custodia")
7bbb43
         self.config_file = paths.IPA_CUSTODIA_CONF
7bbb43
         self.server_keys = paths.IPA_CUSTODIA_KEYS
7bbb43
-        self.ldap_uri = None
7bbb43
+        self.ldap_uri = ldap_uri
7bbb43
         self.fqdn = host_name
7bbb43
         self.realm = realm
7bbb43
 
7bbb43
@@ -49,14 +125,19 @@ class CustodiaInstance(SimpleServiceInstance):
7bbb43
             ipautil.flush_sync(f)
7bbb43
 
7bbb43
     def create_instance(self):
7bbb43
-        suffix = ipautil.realm_to_suffix(self.realm)
7bbb43
+        if self.ldap_uri is None or self.ldap_uri.startswith('ldapi://'):
7bbb43
+            # local case, ensure container exists
7bbb43
+            self.step("Making sure custodia container exists",
7bbb43
+                      self.__create_container)
7bbb43
+
7bbb43
         self.step("Generating ipa-custodia config file", self.__config_file)
7bbb43
-        self.step("Making sure custodia container exists", self.__create_container)
7bbb43
         self.step("Generating ipa-custodia keys", self.__gen_keys)
7bbb43
-        super(CustodiaInstance, self).create_instance(gensvc_name='KEYS',
7bbb43
-                                                      fqdn=self.fqdn,
7bbb43
-                                                      ldap_suffix=suffix,
7bbb43
-                                                      realm=self.realm)
7bbb43
+        super(CustodiaInstance, self).create_instance(
7bbb43
+            gensvc_name='KEYS',
7bbb43
+            fqdn=self.fqdn,
7bbb43
+            ldap_suffix=ipautil.realm_to_suffix(self.realm),
7bbb43
+            realm=self.realm
7bbb43
+        )
7bbb43
         sysupgrade.set_upgrade_state('custodia', 'installed', True)
7bbb43
 
7bbb43
     def __gen_keys(self):
7bbb43
@@ -81,18 +162,6 @@ class CustodiaInstance(SimpleServiceInstance):
7bbb43
             root_logger.info("Secure server.keys mode")
7bbb43
             os.chmod(self.server_keys, 0o600)
7bbb43
 
7bbb43
-    def create_replica(self, master_host_name):
7bbb43
-        suffix = ipautil.realm_to_suffix(self.realm)
7bbb43
-        self.ldap_uri = 'ldap://%s' % master_host_name
7bbb43
-        self.master_host_name = master_host_name
7bbb43
-
7bbb43
-        self.step("Generating ipa-custodia config file", self.__config_file)
7bbb43
-        self.step("Generating ipa-custodia keys", self.__gen_keys)
7bbb43
-        super(CustodiaInstance, self).create_instance(gensvc_name='KEYS',
7bbb43
-                                                      fqdn=self.fqdn,
7bbb43
-                                                      ldap_suffix=suffix,
7bbb43
-                                                      realm=self.realm)
7bbb43
-
7bbb43
     def __create_container(self):
7bbb43
         """
7bbb43
         Runs the custodia update file to ensure custodia container is present.
7bbb43
@@ -106,7 +175,7 @@ class CustodiaInstance(SimpleServiceInstance):
7bbb43
         updater.update([os.path.join(paths.UPDATES_DIR, '73-custodia.update')])
7bbb43
 
7bbb43
     def import_ra_key(self, master_host_name):
7bbb43
-        cli = self.__CustodiaClient(server=master_host_name)
7bbb43
+        cli = self._get_custodia_client(server=master_host_name)
7bbb43
         # please note that ipaCert part has to stay here for historical
7bbb43
         # reasons (old servers expect you to ask for ra/ipaCert during
7bbb43
         # replication as they store the RA agent cert in an NSS database
7bbb43
@@ -114,14 +183,14 @@ class CustodiaInstance(SimpleServiceInstance):
7bbb43
         cli.fetch_key('ra/ipaCert')
7bbb43
 
7bbb43
     def import_dm_password(self, master_host_name):
7bbb43
-        cli = self.__CustodiaClient(server=master_host_name)
7bbb43
+        cli = self._get_custodia_client(server=master_host_name)
7bbb43
         cli.fetch_key('dm/DMHash')
7bbb43
 
7bbb43
-    def __wait_keys(self, host, timeout=300):
7bbb43
+    def _wait_keys(self, host, timeout=300):
7bbb43
         ldap_uri = 'ldap://%s' % host
7bbb43
         deadline = int(time.time()) + timeout
7bbb43
-        root_logger.info("Waiting up to {} seconds to see our keys "
7bbb43
-                         "appear on host: {}".format(timeout, host))
7bbb43
+        root_logger.info("Waiting up to %s seconds to see our keys "
7bbb43
+                         "appear on host: %s", timeout, host)
7bbb43
 
7bbb43
         konn = KEMLdap(ldap_uri)
7bbb43
         saved_e = None
7bbb43
@@ -129,6 +198,12 @@ class CustodiaInstance(SimpleServiceInstance):
7bbb43
             try:
7bbb43
                 return konn.check_host_keys(self.fqdn)
7bbb43
             except Exception as e:
7bbb43
+                # Print message to console only once for first error.
7bbb43
+                if saved_e is None:
7bbb43
+                    # FIXME: Change once there's better way to show this
7bbb43
+                    # message in installer output,
7bbb43
+                    print("  Waiting for keys to appear on host: {}, please "
7bbb43
+                          "wait until this has completed.".format(host))
7bbb43
                 # log only once for the same error
7bbb43
                 if not isinstance(e, type(saved_e)):
7bbb43
                     root_logger.debug(
7bbb43
@@ -138,22 +213,23 @@ class CustodiaInstance(SimpleServiceInstance):
7bbb43
                     raise RuntimeError("Timed out trying to obtain keys.")
7bbb43
                 time.sleep(1)
7bbb43
 
7bbb43
-    def __CustodiaClient(self, server):
7bbb43
+    def _get_custodia_client(self, server):
7bbb43
         # Before we attempt to fetch keys from this host, make sure our public
7bbb43
         # keys have been replicated there.
7bbb43
-        self.__wait_keys(server)
7bbb43
-
7bbb43
-        return CustodiaClient('host@%s' % self.fqdn, self.server_keys,
7bbb43
-                              paths.KRB5_KEYTAB, server, realm=self.realm)
7bbb43
+        self._wait_keys(server)
7bbb43
 
7bbb43
-    def __get_keys(self, ca_host, cacerts_file, cacerts_pwd, data):
7bbb43
-        # Fecth all needed certs one by one, then combine them in a single
7bbb43
-        # p12 file
7bbb43
+        return CustodiaClient(
7bbb43
+            client_service='host@{}'.format(self.fqdn),
7bbb43
+            keyfile=self.server_keys, keytab=paths.KRB5_KEYTAB,
7bbb43
+            server=server, realm=self.realm
7bbb43
+        )
7bbb43
 
7bbb43
+    def _get_keys(self, ca_host, cacerts_file, cacerts_pwd, data):
7bbb43
+        # Fetch all needed certs one by one, then combine them in a single
7bbb43
+        # PKCS12 file
7bbb43
         prefix = data['prefix']
7bbb43
         certlist = data['list']
7bbb43
-
7bbb43
-        cli = self.__CustodiaClient(server=ca_host)
7bbb43
+        cli = self._get_custodia_client(server=ca_host)
7bbb43
 
7bbb43
         # Temporary nssdb
7bbb43
         tmpnssdir = tempfile.mkdtemp(dir=paths.TMP)
7bbb43
@@ -203,7 +279,7 @@ class CustodiaInstance(SimpleServiceInstance):
7bbb43
                     'subsystemCert cert-pki-ca']
7bbb43
         data = {'prefix': 'ca',
7bbb43
                 'list': certlist}
7bbb43
-        self.__get_keys(ca_host, cacerts_file, cacerts_pwd, data)
7bbb43
+        self._get_keys(ca_host, cacerts_file, cacerts_pwd, data)
7bbb43
 
7bbb43
     def get_kra_keys(self, ca_host, cacerts_file, cacerts_pwd):
7bbb43
         certlist = ['auditSigningCert cert-pki-kra',
7bbb43
@@ -212,7 +288,7 @@ class CustodiaInstance(SimpleServiceInstance):
7bbb43
                     'transportCert cert-pki-kra']
7bbb43
         data = {'prefix': 'ca',
7bbb43
                 'list': certlist}
7bbb43
-        self.__get_keys(ca_host, cacerts_file, cacerts_pwd, data)
7bbb43
+        self._get_keys(ca_host, cacerts_file, cacerts_pwd, data)
7bbb43
 
7bbb43
     def __start(self):
7bbb43
         super(CustodiaInstance, self).__start()
7bbb43
diff --git a/ipaserver/install/ipa_kra_install.py b/ipaserver/install/ipa_kra_install.py
7bbb43
index 3e08f4da94651b49876e1427daddbd957f0027ae..9ebabe057513141ee76d238a3f20e76a27dd932e 100644
7bbb43
--- a/ipaserver/install/ipa_kra_install.py
7bbb43
+++ b/ipaserver/install/ipa_kra_install.py
7bbb43
@@ -32,6 +32,7 @@ from ipapython import admintool
7bbb43
 from ipapython import ipautil
7bbb43
 from ipaserver.install import service
7bbb43
 from ipaserver.install import cainstance
7bbb43
+from ipaserver.install import custodiainstance
7bbb43
 from ipaserver.install import krainstance
7bbb43
 from ipaserver.install import dsinstance
7bbb43
 from ipaserver.install import installutils
7bbb43
@@ -176,7 +177,6 @@ class KRAInstaller(KRAInstall):
7bbb43
 
7bbb43
         api.Backend.ldap2.connect()
7bbb43
 
7bbb43
-        config = None
7bbb43
         if self.installing_replica:
7bbb43
             if self.options.promote:
7bbb43
                 config = ReplicaConfig()
7bbb43
@@ -196,6 +196,7 @@ class KRAInstaller(KRAInstall):
7bbb43
                 config.kra_host_name = config.master_host_name
7bbb43
 
7bbb43
             config.setup_kra = True
7bbb43
+            config.promote = self.options.promote
7bbb43
 
7bbb43
             if config.subject_base is None:
7bbb43
                 attrs = api.Backend.ldap2.get_ipa_config()
7bbb43
@@ -204,6 +205,11 @@ class KRAInstaller(KRAInstall):
7bbb43
             if config.kra_host_name is None:
7bbb43
                 config.kra_host_name = service.find_providing_server(
7bbb43
                     'KRA', api.Backend.ldap2, api.env.ca_host)
7bbb43
+            custodia = custodiainstance.get_custodia_instance(
7bbb43
+                config, custodiainstance.CustodiaModes.KRA_PEER)
7bbb43
+        else:
7bbb43
+            config = None
7bbb43
+            custodia = None
7bbb43
 
7bbb43
         try:
7bbb43
             kra.install_check(api, config, self.options)
7bbb43
@@ -213,7 +219,7 @@ class KRAInstaller(KRAInstall):
7bbb43
         print(dedent(self.INSTALLER_START_MESSAGE))
7bbb43
 
7bbb43
         try:
7bbb43
-            kra.install(api, config, self.options)
7bbb43
+            kra.install(api, config, self.options, custodia=custodia)
7bbb43
         except:
7bbb43
             self.log.error(dedent(self.FAIL_MESSAGE))
7bbb43
             raise
7bbb43
diff --git a/ipaserver/install/kra.py b/ipaserver/install/kra.py
7bbb43
index 3545b301a977f4b7e7801ca1ef87d594bb3ba54f..3333970e8af9e36d6b7614286cc1e774f6eb9b25 100644
7bbb43
--- a/ipaserver/install/kra.py
7bbb43
+++ b/ipaserver/install/kra.py
7bbb43
@@ -16,7 +16,6 @@ from ipaplatform.paths import paths
7bbb43
 from ipapython import certdb
7bbb43
 from ipapython import ipautil
7bbb43
 from ipapython.install.core import group
7bbb43
-from ipaserver.install import custodiainstance
7bbb43
 from ipaserver.install import cainstance
7bbb43
 from ipaserver.install import krainstance
7bbb43
 from ipaserver.install import dsinstance
7bbb43
@@ -68,7 +67,7 @@ def install_check(api, replica_config, options):
7bbb43
                                    "new replica file.")
7bbb43
 
7bbb43
 
7bbb43
-def install(api, replica_config, options):
7bbb43
+def install(api, replica_config, options, custodia):
7bbb43
     if replica_config is None:
7bbb43
         if not options.setup_kra:
7bbb43
             return
7bbb43
@@ -91,9 +90,6 @@ def install(api, replica_config, options):
7bbb43
                     'host/{env.host}@{env.realm}'.format(env=api.env),
7bbb43
                     paths.KRB5_KEYTAB,
7bbb43
                     ccache)
7bbb43
-                custodia = custodiainstance.CustodiaInstance(
7bbb43
-                    replica_config.host_name,
7bbb43
-                    replica_config.realm_name)
7bbb43
                 custodia.get_kra_keys(
7bbb43
                     replica_config.kra_host_name,
7bbb43
                     krafile,
7bbb43
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
7bbb43
index 422474fa915b4876530f304ef9424f6b31cf26cc..f4338ed0428f7f44decd004f6a183258bef7f795 100644
7bbb43
--- a/ipaserver/install/server/install.py
7bbb43
+++ b/ipaserver/install/server/install.py
7bbb43
@@ -709,6 +709,7 @@ def install(installer):
7bbb43
     host_name = options.host_name
7bbb43
     ip_addresses = options.ip_addresses
7bbb43
     setup_ca = options.setup_ca
7bbb43
+    options.promote = False  # first master, no promotion
7bbb43
 
7bbb43
     # Installation has started. No IPA sysrestore items are restored in case of
7bbb43
     # failure to enable root cause investigation
7bbb43
@@ -789,6 +790,10 @@ def install(installer):
7bbb43
                       setup_pkinit=not options.no_pkinit,
7bbb43
                       subject_base=options.subject_base)
7bbb43
 
7bbb43
+    custodia = custodiainstance.get_custodia_instance(
7bbb43
+        options, custodiainstance.CustodiaModes.MASTER_PEER)
7bbb43
+    custodia.create_instance()
7bbb43
+
7bbb43
     if setup_ca:
7bbb43
         if not options.external_cert_files and options.external_ca:
7bbb43
             # stage 1 of external CA installation
7bbb43
@@ -803,7 +808,7 @@ def install(installer):
7bbb43
                           if n in options.__dict__}
7bbb43
             write_cache(cache_vars)
7bbb43
 
7bbb43
-        ca.install_step_0(False, None, options)
7bbb43
+        ca.install_step_0(False, None, options, custodia=custodia)
7bbb43
     else:
7bbb43
         # Put the CA cert where other instances expect it
7bbb43
         x509.write_certificate(http_ca_cert, paths.IPA_CA_CRT)
7bbb43
@@ -823,15 +828,12 @@ def install(installer):
7bbb43
     ds.enable_ssl()
7bbb43
 
7bbb43
     if setup_ca:
7bbb43
-        ca.install_step_1(False, None, options)
7bbb43
+        ca.install_step_1(False, None, options, custodia=custodia)
7bbb43
 
7bbb43
     otpd = otpdinstance.OtpdInstance()
7bbb43
     otpd.create_instance('OTPD', host_name,
7bbb43
                          ipautil.realm_to_suffix(realm_name))
7bbb43
 
7bbb43
-    custodia = custodiainstance.CustodiaInstance(host_name, realm_name)
7bbb43
-    custodia.create_instance()
7bbb43
-
7bbb43
     # Create a HTTP instance
7bbb43
     http = httpinstance.HTTPInstance(fstore)
7bbb43
     if options.http_cert_files:
7bbb43
@@ -863,7 +865,7 @@ def install(installer):
7bbb43
     krb.restart()
7bbb43
 
7bbb43
     if options.setup_kra:
7bbb43
-        kra.install(api, None, options)
7bbb43
+        kra.install(api, None, options, custodia=custodia)
7bbb43
 
7bbb43
     if options.setup_dns:
7bbb43
         dns.install(False, False, options)
7bbb43
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
7bbb43
index 42e4615ad2dc1f604f5d8d14f8e57e3e4674bcb9..2ecc0abe0c5918cf5aefccc1bd6f09e70503baab 100644
7bbb43
--- a/ipaserver/install/server/replicainstall.py
7bbb43
+++ b/ipaserver/install/server/replicainstall.py
7bbb43
@@ -1357,6 +1357,7 @@ def install(installer):
7bbb43
     fstore = installer._fstore
7bbb43
     sstore = installer._sstore
7bbb43
     config = installer._config
7bbb43
+    config.promote = installer.promote
7bbb43
     promote = installer.promote
7bbb43
     cafile = installer._ca_file
7bbb43
     dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
7bbb43
@@ -1483,19 +1484,19 @@ def install(installer):
7bbb43
     otpd.create_instance('OTPD', config.host_name,
7bbb43
                          ipautil.realm_to_suffix(config.realm_name))
7bbb43
 
7bbb43
-    custodia = custodiainstance.CustodiaInstance(config.host_name,
7bbb43
-                                                 config.realm_name)
7bbb43
-    if promote:
7bbb43
-        custodia.create_replica(config.master_host_name)
7bbb43
+    if ca_enabled:
7bbb43
+        mode = custodiainstance.CustodiaModes.CA_PEER
7bbb43
     else:
7bbb43
-        custodia.create_instance()
7bbb43
+        mode = custodiainstance.CustodiaModes.MASTER_PEER
7bbb43
+    custodia = custodiainstance.get_custodia_instance(config, mode)
7bbb43
+    custodia.create_instance()
7bbb43
 
7bbb43
     if ca_enabled:
7bbb43
         options.realm_name = config.realm_name
7bbb43
         options.domain_name = config.domain_name
7bbb43
         options.host_name = config.host_name
7bbb43
         options.dm_password = config.dirman_password
7bbb43
-        ca.install(False, config, options)
7bbb43
+        ca.install(False, config, options, custodia=custodia)
7bbb43
 
7bbb43
     # configure PKINIT now that all required services are in place
7bbb43
     krb.enable_ssl()
7bbb43
@@ -1505,7 +1506,7 @@ def install(installer):
7bbb43
     ds.apply_updates()
7bbb43
 
7bbb43
     if kra_enabled:
7bbb43
-        kra.install(api, config, options)
7bbb43
+        kra.install(api, config, options, custodia=custodia)
7bbb43
 
7bbb43
     service.print_msg("Restarting the KDC")
7bbb43
     krb.restart()
7bbb43
-- 
7bbb43
2.14.3
7bbb43