summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2015-08-25 15:42:25 -0400
committerSimo Sorce <simo@redhat.com>2015-10-01 16:20:49 -0400
commit78c59858cddec7f5fec176eacaf318e2d77d2045 (patch)
treeb9c4a4738aba35a3014584d3f6ea694639c0f5fa
parent7af795f3a2b314475ca24aae344544be91738607 (diff)
downloadfreeipa-custodia-review.tar.gz
freeipa-custodia-review.tar.xz
freeipa-custodia-review.zip
Allow to install the KRA on a promoted servercustodia-review
Signed-off-by: Simo Sorce <simo@redhat.com>
-rwxr-xr-xinstall/tools/ipa-ca-install5
-rw-r--r--ipaserver/install/cainstance.py106
-rw-r--r--ipaserver/install/custodiainstance.py29
-rw-r--r--ipaserver/install/dogtaginstance.py91
-rwxr-xr-x[-rw-r--r--]ipaserver/install/ipa_kra_install.py55
-rw-r--r--ipaserver/install/kra.py31
-rw-r--r--ipaserver/install/krainstance.py70
-rw-r--r--ipaserver/install/server/replicainstall.py29
-rw-r--r--ipaserver/install/service.py30
9 files changed, 299 insertions, 147 deletions
diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
index 46fb36aa2..82896867c 100755
--- a/install/tools/ipa-ca-install
+++ b/install/tools/ipa-ca-install
@@ -29,7 +29,7 @@ from ipaserver.install import certs
from ipaserver.install.installutils import create_replica_config
from ipaserver.install.installutils import check_creds, ReplicaConfig
from ipaserver.install import dsinstance, ca
-from ipaserver.install import cainstance, custodiainstance
+from ipaserver.install import cainstance, custodiainstance, service
from ipapython import dogtag
from ipapython import version
from ipalib import api
@@ -175,7 +175,8 @@ def install_replica(safe_options, options, filename):
config.subject_base = attrs.get('ipacertificatesubjectbase')[0]
if config.master_host_name is None:
- config.ca_host_name = cainstance.find_ca_server(api.env.ca_host, conn)
+ config.ca_host_name = \
+ service.find_providing_server('CA', conn, api.env.ca_host)
config.master_host_name = config.ca_host_name
else:
config.ca_host_name = config.master_host_name
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index ff906cea5..da0a6893a 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -262,30 +262,6 @@ def is_step_one_done():
return False
-def find_ca_server(host_name, conn, api=api):
- """
- :param host_name: the preferred server
- :param conn: a connection to the LDAP server
- :return: the selected host name
-
- Find a server that is a CA.
- """
- base_dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'),
- api.env.basedn)
- query_filter = conn.make_filter({'objectClass': 'ipaConfigObject',
- 'ipaConfigString': 'enabledService',
- 'cn': 'CA'}, rules='&')
- entries, trunc = conn.find_entries(filter=query_filter, base_dn=base_dn)
- if len(entries):
- if host_name is not None:
- for entry in entries:
- if entry.dn[1].value == host_name:
- return host_name
- # if the preferred is not found, return the first in the list
- return entries[0].dn[1].value
- return None
-
-
def is_ca_installed_locally():
"""Check if CA is installed locally by checking for existence of CS.cfg
:return:True/False
@@ -1527,83 +1503,6 @@ class CAInstance(DogtagInstance):
# Activate Topology for o=ipaca segments
self.__update_topology()
- def __add_admin_to_group(self, group):
- dn = DN(('cn', group), ('ou', 'groups'), ('o', 'ipaca'))
- entry = self.admin_conn.get_entry(dn)
- members = entry.get('uniqueMember', [])
- members.append(self.admin_dn)
- mod = [(ldap.MOD_REPLACE, 'uniqueMember', members)]
- try:
- self.admin_conn.modify_s(dn, mod)
- except ldap.TYPE_OR_VALUE_EXISTS:
- # already there
- pass
-
- def __setup_admin(self):
- self.admin_user = "admin-%s" % self.fqdn
- self.admin_password = binascii.hexlify(os.urandom(16))
-
- if not self.admin_conn:
- self.ldap_connect()
-
- self.admin_dn = DN(('uid', self.admin_user),
- ('ou', 'people'), ('o', 'ipaca'))
-
- # remove user if left-over exists
- try:
- entry = self.admin_conn.delete_entry(self.admin_dn)
- except errors.NotFound:
- pass
-
- # add user
- entry = self.admin_conn.make_entry(
- self.admin_dn,
- objectclass=["top", "person", "organizationalPerson",
- "inetOrgPerson", "cmsuser"],
- uid=[self.admin_user],
- cn=[self.admin_user],
- sn=[self.admin_user],
- usertype=['adminType'],
- mail=['root@localhost'],
- userPassword=[self.admin_password],
- userstate=['1']
- )
- self.admin_conn.add_entry(entry)
-
- for group in ADMIN_GROUPS:
- self.__add_admin_to_group(group)
-
- # Now wait until the other server gets replicated this data
- master_conn = ipaldap.IPAdmin(self.master_host,
- port=replication.DEFAULT_PORT,
- protocol='ldap')
- master_conn.do_sasl_gssapi_bind()
- replication.wait_for_entry(master_conn, entry)
- del master_conn
-
- def __remove_admin_from_group(self, group):
- dn = DN(('cn', group), ('ou', 'groups'), ('o', 'ipaca'))
- entry = self.admin_conn.get_entry(dn)
- mod = [(ldap.MOD_DELETE, 'uniqueMember', self.admin_dn)]
- try:
- self.admin_conn.modify_s(dn, mod)
- except ldap.NO_SUCH_ATTRIBUTE:
- # already removed
- pass
-
- def __teardown_admin(self):
-
- if not self.admin_conn:
- self.ldap_connect()
-
- for group in ADMIN_GROUPS:
- self.__remove_admin_from_group(group)
- self.admin_conn.delete_entry(self.admin_dn)
-
- def __restart_ds_instance(self):
- self.ldap_disconnect()
- services.knownservices.dirsrv.restart()
-
def __client_auth_to_db(self):
self.enable_client_auth_to_db(self.dogtag_constants.CS_CFG_PATH)
@@ -1638,6 +1537,7 @@ class CAInstance(DogtagInstance):
else:
self.ca_type = 'generic'
+ self.admin_groups = ADMIN_GROUPS
self.pkcs12_info = ca_cert_bundle
self.no_db_setup = True
self.clone = True
@@ -1651,7 +1551,7 @@ class CAInstance(DogtagInstance):
self.step("creating certificate server db", self.__create_ds_db)
self.step("setting up initial replication", self.__setup_replication)
- self.step("creating installation admin user", self.__setup_admin)
+ self.step("creating installation admin user", self.setup_admin)
# Setup instance
self.step("setting up certificate server", self.__spawn_instance)
@@ -1662,7 +1562,7 @@ class CAInstance(DogtagInstance):
self.step("enable PKIX certificate path discovery and validation",
self.enable_pkix)
self.step("set up client auth to db", self.__client_auth_to_db)
- self.step("destroying installation admin user", self.__teardown_admin)
+ self.step("destroying installation admin user", self.teardown_admin)
self.step("starting instance", self.start_instance)
self.step("importing CA chain to RA certificate database",
diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py
index 6f4afb3a9..eb9512bf1 100644
--- a/ipaserver/install/custodiainstance.py
+++ b/ipaserver/install/custodiainstance.py
@@ -78,13 +78,12 @@ class CustodiaInstance(SimpleServiceInstance):
cli = CustodiaClient(self.fqdn, master_host_name, self.realm)
cli.fetch_key('dm/DMHash')
- def get_ca_keys(self, ca_host, cacerts_file, cacerts_pwd):
+ def __get_keys(self, ca_host, cacerts_file, cacerts_pwd, data):
# Fecth all needed certs one by one, then combine them in a single
# p12 file
- certlist = ['caSigningCert cert-pki-ca',
- 'ocspSigningCert cert-pki-ca',
- 'auditSigningCert cert-pki-ca',
- 'subsystemCert cert-pki-ca']
+
+ prefix = data['prefix']
+ certlist = data['list']
cli = CustodiaClient(self.fqdn, ca_host, self.realm)
@@ -104,7 +103,7 @@ class CustodiaInstance(SimpleServiceInstance):
f.flush()
for nickname in certlist:
- value = cli.fetch_key(os.path.join('ca', nickname), False)
+ value = cli.fetch_key(os.path.join(prefix, nickname), False)
v = json_decode(value)
pk12pwfile = os.path.join(tmpnssdir, 'pk12pwfile')
with open(pk12pwfile, 'w+') as f:
@@ -129,6 +128,24 @@ class CustodiaInstance(SimpleServiceInstance):
finally:
shutil.rmtree(tmpnssdir)
+ def get_ca_keys(self, ca_host, cacerts_file, cacerts_pwd):
+ certlist = ['caSigningCert cert-pki-ca',
+ 'ocspSigningCert cert-pki-ca',
+ 'auditSigningCert cert-pki-ca',
+ 'subsystemCert cert-pki-ca']
+ data = {'prefix': 'ca',
+ 'list': certlist}
+ self.__get_keys(ca_host, cacerts_file, cacerts_pwd, data)
+
+ def get_kra_keys(self, ca_host, cacerts_file, cacerts_pwd):
+ certlist = ['auditSigningCert cert-pki-kra',
+ 'storageCert cert-pki-kra',
+ 'subsystemCert cert-pki-ca',
+ 'transportCert cert-pki-kra']
+ data = {'prefix': 'ca',
+ 'list': certlist}
+ self.__get_keys(ca_host, cacerts_file, cacerts_pwd, data)
+
def __start(self):
super(CustodiaInstance, self).__start()
diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py
index 3a269f973..34308107b 100644
--- a/ipaserver/install/dogtaginstance.py
+++ b/ipaserver/install/dogtaginstance.py
@@ -18,6 +18,8 @@
#
import base64
+import binascii
+import ldap
import os
import shutil
import tempfile
@@ -27,6 +29,8 @@ import dbus
from pki.client import PKIConnection
import pki.system
+from ipalib import errors
+
from ipaplatform import services
from ipaplatform.paths import paths
from ipapython import certmonger
@@ -36,6 +40,7 @@ from ipapython import ipautil
from ipapython.dn import DN
from ipaserver.install import service
from ipaserver.install import installutils
+from ipaserver.install import replication
from ipaserver.install.installutils import stopped_service
from ipapython.ipa_log_manager import log_mgr
@@ -122,7 +127,10 @@ class DogtagInstance(service.Service):
self.clone = False
self.basedn = DN(('o', 'ipa%s' % subsystem.lower()))
- self.admin_user = DN(('uid', 'admin'), ('ou', 'people'), ('o', 'ipaca'))
+ self.admin_user = "admin"
+ self.admin_dn = DN(('uid', self.admin_user),
+ ('ou', 'people'), ('o', 'ipaca'))
+ self.admin_groups = None
self.agent_db = tempfile.mkdtemp(prefix="tmp-")
self.ds_port = DEFAULT_DSPORT
self.server_root = dogtag_constants.SERVER_ROOT
@@ -413,12 +421,10 @@ class DogtagInstance(service.Service):
conn = None
try:
- conn = ipaldap.IPAdmin(self.fqdn, self.ds_port)
- conn.do_simple_bind(
- DN(('cn', 'Directory Manager')),
- self.dm_password)
+ conn = ipaldap.IPAdmin(self.fqdn, ldapi=True, realm=self.realm)
+ conn.do_external_bind('root')
- entry_attrs = conn.get_entry(self.admin_user, ['usercertificate'])
+ entry_attrs = conn.get_entry(self.admin_dn, ['usercertificate'])
admin_cert = entry_attrs.get('usercertificate')[0]
# TODO(edewata) Add check to warn if there is more than one cert.
@@ -440,3 +446,76 @@ class DogtagInstance(service.Service):
self.log.critical(" %s" % log)
raise RuntimeError("%s configuration failed." % self.subsystem)
+
+ def __add_admin_to_group(self, group):
+ dn = DN(('cn', group), ('ou', 'groups'), ('o', 'ipaca'))
+ entry = self.admin_conn.get_entry(dn)
+ members = entry.get('uniqueMember', [])
+ members.append(self.admin_dn)
+ mod = [(ldap.MOD_REPLACE, 'uniqueMember', members)]
+ try:
+ self.admin_conn.modify_s(dn, mod)
+ except ldap.TYPE_OR_VALUE_EXISTS:
+ # already there
+ pass
+
+ def setup_admin(self):
+ self.admin_user = "admin-%s" % self.fqdn
+ self.admin_password = binascii.hexlify(os.urandom(16))
+
+ if not self.admin_conn:
+ self.ldap_connect()
+
+ self.admin_dn = DN(('uid', self.admin_user),
+ ('ou', 'people'), ('o', 'ipaca'))
+
+ # remove user if left-over exists
+ try:
+ entry = self.admin_conn.delete_entry(self.admin_dn)
+ except errors.NotFound:
+ pass
+
+ # add user
+ entry = self.admin_conn.make_entry(
+ self.admin_dn,
+ objectclass=["top", "person", "organizationalPerson",
+ "inetOrgPerson", "cmsuser"],
+ uid=[self.admin_user],
+ cn=[self.admin_user],
+ sn=[self.admin_user],
+ usertype=['adminType'],
+ mail=['root@localhost'],
+ userPassword=[self.admin_password],
+ userstate=['1']
+ )
+ self.admin_conn.add_entry(entry)
+
+ for group in self.admin_groups:
+ self.__add_admin_to_group(group)
+
+ # Now wait until the other server gets replicated this data
+ master_conn = ipaldap.IPAdmin(self.master_host,
+ port=DEFAULT_DSPORT,
+ protocol='ldap')
+ master_conn.do_sasl_gssapi_bind()
+ replication.wait_for_entry(master_conn, entry)
+ del master_conn
+
+ def __remove_admin_from_group(self, group):
+ dn = DN(('cn', group), ('ou', 'groups'), ('o', 'ipaca'))
+ entry = self.admin_conn.get_entry(dn)
+ mod = [(ldap.MOD_DELETE, 'uniqueMember', self.admin_dn)]
+ try:
+ self.admin_conn.modify_s(dn, mod)
+ except ldap.NO_SUCH_ATTRIBUTE:
+ # already removed
+ pass
+
+ def teardown_admin(self):
+
+ if not self.admin_conn:
+ self.ldap_connect()
+
+ for group in self.admin_groups:
+ self.__remove_admin_from_group(group)
+ self.admin_conn.delete_entry(self.admin_dn)
diff --git a/ipaserver/install/ipa_kra_install.py b/ipaserver/install/ipa_kra_install.py
index ef2b2f985..7e7f60ef2 100644..100755
--- a/ipaserver/install/ipa_kra_install.py
+++ b/ipaserver/install/ipa_kra_install.py
@@ -20,6 +20,8 @@
from __future__ import print_function
+import tempfile
+
from textwrap import dedent
from ipalib import api
from ipaplatform import services
@@ -28,11 +30,14 @@ from ipapython import admintool
from ipapython import dogtag
from ipapython import ipautil
from ipapython.dn import DN
+from ipaserver.install import service
from ipaserver.install import krainstance
+from ipaserver.install import dsinstance
from ipaserver.install import installutils
from ipaserver.install.installutils import create_replica_config
from ipaserver.install import dogtaginstance
from ipaserver.install import kra
+from ipaserver.install.installutils import ReplicaConfig
class KRAInstall(admintool.AdminTool):
@@ -129,8 +134,14 @@ class KRAInstaller(KRAInstall):
)
self.installing_replica = dogtaginstance.is_installing_replica("KRA")
+ self.options.promote = False
if self.installing_replica:
+ domain_level = dsinstance.get_domain_level(api)
+ if domain_level > 0:
+ self.options.promote = True
+ return
+
if not self.args:
self.option_parser.error("A replica file is required.")
if len(self.args) > 1:
@@ -161,28 +172,48 @@ class KRAInstaller(KRAInstall):
print(dedent(self.INSTALLER_START_MESSAGE))
if not self.installing_replica:
- replica_config = None
+ config = None
else:
- replica_config = create_replica_config(
- self.options.password,
- self.replica_file,
- self.options)
+ if self.options.promote:
+ config = ReplicaConfig()
+ config.master_host_name = None
+ config.realm_name = api.env.realm
+ config.host_name = api.env.host
+ config.domain_name = api.env.domain
+ config.dirman_password = self.options.password
+ config.ca_ds_port = dogtag.install_constants.DS_PORT
+ config.top_dir = tempfile.mkdtemp("ipa")
+ config.dir = config.top_dir
+ else:
+ config = create_replica_config(
+ self.options.password,
+ self.replica_file,
+ self.options)
self.options.dm_password = self.options.password
self.options.setup_ca = False
- api.Backend.ldap2.connect(bind_dn=DN('cn=Directory Manager'),
- bind_pw=self.options.dm_password)
+ conn = api.Backend.ldap2
+ conn.connect(bind_dn=DN(('cn', 'Directory Manager')),
+ bind_pw=self.options.password)
+
+ if config.subject_base is None:
+ attrs = conn.get_ipa_config()
+ config.subject_base = attrs.get('ipacertificatesubjectbase')[0]
+
+ if config.master_host_name is None:
+ config.kra_host_name = \
+ service.find_providing_server('KRA', conn, api.env.ca_host)
+ config.master_host_name = config.kra_host_name
+ else:
+ config.kra_host_name = config.master_host_name
try:
- kra.install_check(api, replica_config, self.options)
+ kra.install_check(api, config, self.options)
except RuntimeError as e:
raise admintool.ScriptError(str(e))
- kra.install(api, replica_config, self.options)
-
- # Restart apache for new proxy config file
- services.knownservices.httpd.restart(capture_output=True)
+ kra.install(api, config, self.options)
def run(self):
try:
diff --git a/ipaserver/install/kra.py b/ipaserver/install/kra.py
index f3a0fe5c6..40c283e6d 100644
--- a/ipaserver/install/kra.py
+++ b/ipaserver/install/kra.py
@@ -2,11 +2,15 @@
# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
#
+import os
+
from ipalib import api, errors
+from ipaplatform import services
from ipapython import certdb
from ipapython import dogtag
from ipapython import ipautil
from ipapython.dn import DN
+from ipaserver.install import custodiainstance
from ipaserver.install import cainstance
from ipaserver.install import krainstance
from ipaserver.install import dsinstance
@@ -36,6 +40,9 @@ def install_check(api, replica_config, options):
if not api.Command.kra_is_enabled()['result']:
raise RuntimeError("KRA is not installed on the master system")
+ if options.promote:
+ return
+
with certdb.NSSDatabase() as tmpdb:
pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
tmpdb.create_db(pw.name)
@@ -62,7 +69,26 @@ def install(api, replica_config, options):
api.env.realm, api.env.host, options.dm_password,
options.dm_password, subject_base=subject)
else:
- kra = krainstance.install_replica_kra(replica_config)
+ if options.promote:
+ ca_data = (os.path.join(replica_config.dir, 'kracert.p12'),
+ replica_config.dirman_password)
+
+ custodia = custodiainstance.CustodiaInstance(
+ replica_config.host_name, replica_config.realm_name)
+ custodia.get_kra_keys(replica_config.kra_host_name,
+ ca_data[0], ca_data[1])
+
+ kra = krainstance.KRAInstance(
+ replica_config.realm_name,
+ dogtag_constants=dogtag.install_constants)
+ kra.configure_replica(replica_config.host_name,
+ replica_config.kra_host_name,
+ replica_config.dirman_password,
+ kra_cert_bundle=ca_data)
+ return
+
+ else:
+ kra = krainstance.install_replica_kra(replica_config)
service.print_msg("Restarting the directory server")
ds = dsinstance.DsInstance()
@@ -72,6 +98,9 @@ def install(api, replica_config, options):
kra.enable_client_auth_to_db(kra.dogtag_constants.KRA_CS_CFG_PATH)
+ # Restart apache for new proxy config file
+ services.knownservices.httpd.restart(capture_output=True)
+
def uninstall(standalone):
dogtag_constants = dogtag.configured_constants(api)
diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
index ba6606ba4..e3cc17990 100644
--- a/ipaserver/install/krainstance.py
+++ b/ipaserver/install/krainstance.py
@@ -46,6 +46,11 @@ from ipapython.ipa_log_manager import log_mgr
# replicas with KRA configured
IPA_KRA_RECORD = "ipa-kra"
+ADMIN_GROUPS = [
+ 'Enterprise CA Administrators',
+ 'Enterprise KRA Administrators',
+ 'Security Domain Administrators'
+]
class KRAInstance(DogtagInstance):
"""
@@ -146,7 +151,7 @@ class KRAInstance(DogtagInstance):
# Security Domain Authentication
config.set("KRA", "pki_security_domain_https_port", "443")
config.set("KRA", "pki_security_domain_password", self.admin_password)
- config.set("KRA", "pki_security_domain_user", "admin")
+ config.set("KRA", "pki_security_domain_user", self.admin_user)
# issuing ca
config.set("KRA", "pki_issuing_ca_uri", "https://%s" %
@@ -165,8 +170,8 @@ class KRAInstance(DogtagInstance):
config.set("KRA", "pki_client_pkcs12_password", self.admin_password)
# Administrator
- config.set("KRA", "pki_admin_name", "admin")
- config.set("KRA", "pki_admin_uid", "admin")
+ config.set("KRA", "pki_admin_name", self.admin_user)
+ config.set("KRA", "pki_admin_uid", self.admin_user)
config.set("KRA", "pki_admin_email", "root@localhost")
config.set("KRA", "pki_admin_password", self.admin_password)
config.set("KRA", "pki_admin_nickname", "ipa-ca-agent")
@@ -226,15 +231,16 @@ class KRAInstance(DogtagInstance):
pent = pwd.getpwnam(PKI_USER)
os.chown(p12_tmpfile_name, pent.pw_uid, pent.pw_gid)
- # create admin cert file if it does not exist
- cert = DogtagInstance.get_admin_cert(self)
- with open(paths.ADMIN_CERT_PATH, "w") as admin_path:
- admin_path.write(cert)
+ # FIXME
+ # # create admin cert file if it does not exist
+ # cert = DogtagInstance.get_admin_cert(self)
+ # with open(paths.ADMIN_CERT_PATH, "w") as admin_path:
+ # admin_path.write(cert)
# Security domain registration
config.set("KRA", "pki_security_domain_hostname", self.master_host)
config.set("KRA", "pki_security_domain_https_port", "443")
- config.set("KRA", "pki_security_domain_user", "admin")
+ config.set("KRA", "pki_security_domain_user", self.admin_user)
config.set("KRA", "pki_security_domain_password",
self.admin_password)
@@ -349,6 +355,54 @@ class KRAInstance(DogtagInstance):
dogtag.configured_constants().KRA_CS_CFG_PATH,
dogtag_constants)
+ def __enable_instance(self):
+ self.ldap_enable('KRA', self.fqdn, None, self.suffix)
+
+ def configure_replica(self, host_name, master_host, dm_password,
+ kra_cert_bundle=None, subject_base=None):
+ """Create a KRA instance.
+
+ To create a clone, pass in pkcs12_info.
+ """
+ self.fqdn = host_name
+ self.dm_password = dm_password
+ self.ds_port = DEFAULT_DSPORT
+ self.master_host = master_host
+ if subject_base is None:
+ self.subject_base = DN(('O', self.realm))
+ else:
+ self.subject_base = subject_base
+ self.suffix = ipautil.realm_to_suffix(self.realm)
+
+ self.pkcs12_info = kra_cert_bundle
+ self.clone = True
+ self.admin_groups = ADMIN_GROUPS
+
+ # Confirm that a KRA does not already exist
+ if self.is_installed():
+ raise RuntimeError(
+ "KRA already installed.")
+ # Confirm that a Dogtag 10 CA instance already exists
+ ca = cainstance.CAInstance(self.realm, certs.NSS_DIR,
+ dogtag_constants=dogtag.Dogtag10Constants)
+ if not ca.is_installed():
+ raise RuntimeError(
+ "KRA configuration failed. "
+ "A Dogtag CA must be installed first")
+
+ self.step("creating installation admin user", self.setup_admin)
+ self.step("configuring KRA instance", self.__spawn_instance)
+ self.step("destroying installation admin user", self.teardown_admin)
+ self.step("restarting KRA", self.restart_instance)
+ self.step("configure certmonger for renewals",
+ self.configure_certmonger_renewal)
+ self.step("configure certificate renewals", self.configure_renewal)
+ self.step("add vault container", self.__add_vault_container)
+
+ self.step("enabling KRA instance", self.__enable_instance)
+
+ self.start_creation(runtime=126)
+
def install_replica_kra(config, postinstall=False):
"""
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index 8b2bfd3e1..225c896e4 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -28,8 +28,8 @@ import ipaclient.ipachangeconf
import ipaclient.ntpconf
from ipaserver.install import (
bindinstance, ca, cainstance, certs, dns, dsinstance, httpinstance,
- installutils, kra, krbinstance, memcacheinstance, ntpinstance,
- otpdinstance, custodiainstance, service)
+ installutils, kra, krainstance, krbinstance, memcacheinstance,
+ ntpinstance, otpdinstance, custodiainstance, service)
from ipaserver.install.installutils import create_replica_config
from ipaserver.install.installutils import ReplicaConfig
from ipaserver.install.replication import (
@@ -771,10 +771,6 @@ def promote_check(installer):
installer._top_dir = tempfile.mkdtemp("ipa")
- # FIXME: to implement yet
- if options.setup_kra:
- raise NotImplementedError
-
tasks.check_selinux_status()
client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
@@ -921,7 +917,7 @@ def promote_check(installer):
config.subject_base = DN(subject_base)
# Find if any server has a CA
- ca_host = cainstance.find_ca_server(api.env.server, conn)
+ ca_host = service.find_providing_server('CA', conn, api.env.server)
if ca_host is not None:
config.ca_host_name = ca_host
ca_enabled = True
@@ -931,6 +927,13 @@ def promote_check(installer):
"installed, can't proceed without certs")
sys.exit(3)
+ config.kra_host_name = service.find_providing_server('KRA', conn,
+ api.env.server)
+ if options.setup_kra and config.kra_host_name is None:
+ root_logger.error("There is no KRA server in the domain, can't "
+ "setup a KRA clone")
+ sys.exit(3)
+
if options.setup_ca:
if not ca_enabled:
root_logger.error("The remote master does not have a CA "
@@ -1082,7 +1085,17 @@ def promote(installer):
ca_cert_bundle=ca_data)
if options.setup_kra:
- kra.install(api, config, options)
+ ca_data = (os.path.join(config.dir, 'kracert.p12'),
+ config.dirman_password)
+ custodia.get_kra_keys(config.kra_host_name, ca_data[0], ca_data[1])
+
+ constants = dogtag.install_constants
+ kra = krainstance.KRAInstance(config.realm_name,
+ dogtag_constants=constants)
+ kra.configure_replica(config.host_name, config.kra_host_name,
+ config.dirman_password,
+ kra_cert_bundle=ca_data)
+
ds.replica_populate()
diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
index b2d111cdf..7b7b68c15 100644
--- a/ipaserver/install/service.py
+++ b/ipaserver/install/service.py
@@ -27,7 +27,7 @@ import traceback
from ipapython import sysrestore, ipautil, dogtag, ipaldap
from ipapython.dn import DN
from ipapython.ipa_log_manager import *
-from ipalib import errors, certstore
+from ipalib import api, errors, certstore
from ipaplatform import services
from ipaplatform.paths import paths
@@ -100,6 +100,34 @@ def add_principals_to_group(admin_conn, group, member_attr, principals):
# If there are no changes just pass
pass
+
+def find_providing_server(svcname, conn, host_name=None, api=api):
+ """
+ :param svcname: The service to find
+ :param conn: a connection to the LDAP server
+ :param host_name: the preferred server
+ :return: the selected host name
+
+ Find a server that is a CA.
+ """
+ dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
+ query_filter = conn.make_filter({'objectClass': 'ipaConfigObject',
+ 'ipaConfigString': 'enabledService',
+ 'cn': svcname}, rules='&')
+ try:
+ entries, trunc = conn.find_entries(filter=query_filter, base_dn=dn)
+ except errors.NotFound:
+ return None
+ if len(entries):
+ if host_name is not None:
+ for entry in entries:
+ if entry.dn[1].value == host_name:
+ return host_name
+ # if the preferred is not found, return the first in the list
+ return entries[0].dn[1].value
+ return None
+
+
class Service(object):
def __init__(self, service_name, service_desc=None, sstore=None,
dm_password=None, ldapi=True, autobind=ipaldap.AUTOBIND_AUTO,