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>
161 lines
4.8 KiB
Python
161 lines
4.8 KiB
Python
#
|
|
# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
|
#
|
|
|
|
"""
|
|
KRA installer module
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
|
|
import logging
|
|
import os
|
|
|
|
from ipalib import api
|
|
from ipalib.install.kinit import kinit_keytab
|
|
from ipaplatform import services
|
|
from ipaplatform.paths import paths
|
|
from ipapython import ipautil
|
|
from ipapython.install.core import group
|
|
from ipaserver.install import ca, cainstance
|
|
from ipaserver.install import krainstance
|
|
from ipaserver.install import dsinstance
|
|
from ipaserver.install import service as _service
|
|
|
|
from . import dogtag
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def install_check(api, replica_config, options):
|
|
if replica_config is not None and not replica_config.setup_kra:
|
|
return
|
|
|
|
kra = krainstance.KRAInstance(api.env.realm)
|
|
if kra.is_installed():
|
|
raise RuntimeError("KRA is already installed.")
|
|
|
|
if not options.setup_ca:
|
|
if cainstance.is_ca_installed_locally():
|
|
if api.env.dogtag_version >= 10:
|
|
# correct dogtag version of CA installed
|
|
pass
|
|
else:
|
|
raise RuntimeError(
|
|
"Dogtag must be version 10.2 or above to install KRA")
|
|
else:
|
|
raise RuntimeError(
|
|
"Dogtag CA is not installed. Please install the CA first")
|
|
|
|
if replica_config is not None:
|
|
if not api.Command.kra_is_enabled()['result']:
|
|
raise RuntimeError(
|
|
"KRA is not installed on the master system. Please use "
|
|
"'ipa-kra-install' command to install the first instance.")
|
|
|
|
if api.env.ca_host is not None and api.env.ca_host != api.env.host:
|
|
raise RuntimeError(
|
|
"KRA can not be installed when 'ca_host' is overriden in "
|
|
"IPA configuration file.")
|
|
|
|
|
|
def install(api, replica_config, options, custodia):
|
|
if replica_config is None:
|
|
if not options.setup_kra:
|
|
return
|
|
realm_name = api.env.realm
|
|
dm_password = options.dm_password
|
|
host_name = api.env.host
|
|
subject_base = dsinstance.DsInstance().find_subject_base()
|
|
|
|
pkcs12_info = None
|
|
master_host = None
|
|
promote = False
|
|
else:
|
|
if not replica_config.setup_kra:
|
|
return
|
|
krafile = os.path.join(replica_config.dir, 'kracert.p12')
|
|
with ipautil.private_ccache():
|
|
ccache = os.environ['KRB5CCNAME']
|
|
kinit_keytab(
|
|
'host/{env.host}@{env.realm}'.format(env=api.env),
|
|
paths.KRB5_KEYTAB,
|
|
ccache)
|
|
custodia.get_kra_keys(
|
|
krafile,
|
|
replica_config.dirman_password)
|
|
|
|
realm_name = replica_config.realm_name
|
|
dm_password = replica_config.dirman_password
|
|
host_name = replica_config.host_name
|
|
subject_base = replica_config.subject_base
|
|
|
|
pkcs12_info = (krafile,)
|
|
master_host = replica_config.kra_host_name
|
|
promote = True
|
|
|
|
ca_subject = ca.lookup_ca_subject(api, subject_base)
|
|
|
|
kra = krainstance.KRAInstance(realm_name)
|
|
kra.configure_instance(
|
|
realm_name, host_name, dm_password, dm_password,
|
|
subject_base=subject_base,
|
|
ca_subject=ca_subject,
|
|
pkcs12_info=pkcs12_info,
|
|
master_host=master_host,
|
|
promote=promote,
|
|
pki_config_override=options.pki_config_override,
|
|
)
|
|
|
|
_service.print_msg("Restarting the directory server")
|
|
ds = dsinstance.DsInstance()
|
|
ds.restart()
|
|
kra.enable_client_auth_to_db()
|
|
|
|
# Restart apache for new proxy config file
|
|
services.knownservices.httpd.restart(capture_output=True)
|
|
# Restarted named to restore bind-dyndb-ldap operation, see
|
|
# https://pagure.io/freeipa/issue/5813
|
|
named = services.knownservices.named # alias for current named
|
|
if named.is_running():
|
|
named.restart(capture_output=True)
|
|
|
|
|
|
def uninstall_check(options):
|
|
"""IPA needs to be running so pkidestroy can unregister KRA"""
|
|
kra = krainstance.KRAInstance(api.env.realm)
|
|
if not kra.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 KRA from security domain")
|
|
ipautil.run([paths.IPACTL, 'start'])
|
|
except Exception:
|
|
logger.info("Re-starting IPA failed, continuing uninstall")
|
|
|
|
|
|
def uninstall():
|
|
kra = krainstance.KRAInstance(api.env.realm)
|
|
kra.stop_tracking_certificates()
|
|
if kra.is_installed():
|
|
kra.uninstall()
|
|
|
|
|
|
@group
|
|
class KRAInstallInterface(dogtag.DogtagInstallInterface):
|
|
"""
|
|
Interface of the KRA installer
|
|
|
|
Knobs defined here will be available in:
|
|
* ipa-server-install
|
|
* ipa-replica-prepare
|
|
* ipa-replica-install
|
|
* ipa-kra-install
|
|
"""
|
|
description = "KRA"
|