mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Allow to install the KRA on a promoted server
Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-By: Martin Babinsky <mbabinsk@redhat.com> Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
parent
a0b8415236
commit
bc39cc9f81
@ -29,7 +29,7 @@ from ipaserver.install import certs
|
|||||||
from ipaserver.install.installutils import create_replica_config
|
from ipaserver.install.installutils import create_replica_config
|
||||||
from ipaserver.install.installutils import check_creds, ReplicaConfig
|
from ipaserver.install.installutils import check_creds, ReplicaConfig
|
||||||
from ipaserver.install import dsinstance, ca
|
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 dogtag
|
||||||
from ipapython import version
|
from ipapython import version
|
||||||
from ipalib import api
|
from ipalib import api
|
||||||
@ -162,7 +162,8 @@ def install_replica(safe_options, options, filename):
|
|||||||
config.subject_base = attrs.get('ipacertificatesubjectbase')[0]
|
config.subject_base = attrs.get('ipacertificatesubjectbase')[0]
|
||||||
|
|
||||||
if config.master_host_name is None:
|
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
|
config.master_host_name = config.ca_host_name
|
||||||
else:
|
else:
|
||||||
config.ca_host_name = config.master_host_name
|
config.ca_host_name = config.master_host_name
|
||||||
|
@ -269,32 +269,6 @@ def is_step_one_done():
|
|||||||
return False
|
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.
|
|
||||||
"""
|
|
||||||
dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
|
|
||||||
query_filter = conn.make_filter({'objectClass': 'ipaConfigObject',
|
|
||||||
'ipaConfigString': 'enabledService',
|
|
||||||
'cn': 'CA'}, 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
|
|
||||||
|
|
||||||
|
|
||||||
def is_ca_installed_locally():
|
def is_ca_installed_locally():
|
||||||
"""Check if CA is installed locally by checking for existence of CS.cfg
|
"""Check if CA is installed locally by checking for existence of CS.cfg
|
||||||
:return:True/False
|
:return:True/False
|
||||||
@ -1540,83 +1514,6 @@ class CAInstance(DogtagInstance):
|
|||||||
# Activate Topology for o=ipaca segments
|
# Activate Topology for o=ipaca segments
|
||||||
self.__update_topology()
|
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):
|
def __client_auth_to_db(self):
|
||||||
self.enable_client_auth_to_db(self.dogtag_constants.CS_CFG_PATH)
|
self.enable_client_auth_to_db(self.dogtag_constants.CS_CFG_PATH)
|
||||||
|
|
||||||
@ -1651,6 +1548,7 @@ class CAInstance(DogtagInstance):
|
|||||||
else:
|
else:
|
||||||
self.ca_type = 'generic'
|
self.ca_type = 'generic'
|
||||||
|
|
||||||
|
self.admin_groups = ADMIN_GROUPS
|
||||||
self.pkcs12_info = ca_cert_bundle
|
self.pkcs12_info = ca_cert_bundle
|
||||||
self.no_db_setup = True
|
self.no_db_setup = True
|
||||||
self.clone = True
|
self.clone = True
|
||||||
@ -1664,7 +1562,7 @@ class CAInstance(DogtagInstance):
|
|||||||
self.step("creating certificate server db", self.__create_ds_db)
|
self.step("creating certificate server db", self.__create_ds_db)
|
||||||
self.step("setting up initial replication", self.__setup_replication)
|
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
|
# Setup instance
|
||||||
self.step("setting up certificate server", self.__spawn_instance)
|
self.step("setting up certificate server", self.__spawn_instance)
|
||||||
@ -1675,7 +1573,7 @@ class CAInstance(DogtagInstance):
|
|||||||
self.step("enable PKIX certificate path discovery and validation",
|
self.step("enable PKIX certificate path discovery and validation",
|
||||||
self.enable_pkix)
|
self.enable_pkix)
|
||||||
self.step("set up client auth to db", self.__client_auth_to_db)
|
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("starting instance", self.start_instance)
|
||||||
|
|
||||||
self.step("importing CA chain to RA certificate database",
|
self.step("importing CA chain to RA certificate database",
|
||||||
|
@ -78,13 +78,12 @@ class CustodiaInstance(SimpleServiceInstance):
|
|||||||
cli = CustodiaClient(self.fqdn, master_host_name, self.realm)
|
cli = CustodiaClient(self.fqdn, master_host_name, self.realm)
|
||||||
cli.fetch_key('dm/DMHash')
|
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
|
# Fecth all needed certs one by one, then combine them in a single
|
||||||
# p12 file
|
# p12 file
|
||||||
certlist = ['caSigningCert cert-pki-ca',
|
|
||||||
'ocspSigningCert cert-pki-ca',
|
prefix = data['prefix']
|
||||||
'auditSigningCert cert-pki-ca',
|
certlist = data['list']
|
||||||
'subsystemCert cert-pki-ca']
|
|
||||||
|
|
||||||
cli = CustodiaClient(self.fqdn, ca_host, self.realm)
|
cli = CustodiaClient(self.fqdn, ca_host, self.realm)
|
||||||
|
|
||||||
@ -104,7 +103,7 @@ class CustodiaInstance(SimpleServiceInstance):
|
|||||||
f.flush()
|
f.flush()
|
||||||
|
|
||||||
for nickname in certlist:
|
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)
|
v = json_decode(value)
|
||||||
pk12pwfile = os.path.join(tmpnssdir, 'pk12pwfile')
|
pk12pwfile = os.path.join(tmpnssdir, 'pk12pwfile')
|
||||||
with open(pk12pwfile, 'w+') as f:
|
with open(pk12pwfile, 'w+') as f:
|
||||||
@ -129,6 +128,24 @@ class CustodiaInstance(SimpleServiceInstance):
|
|||||||
finally:
|
finally:
|
||||||
shutil.rmtree(tmpnssdir)
|
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):
|
def __start(self):
|
||||||
super(CustodiaInstance, self).__start()
|
super(CustodiaInstance, self).__start()
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
|
import binascii
|
||||||
|
import ldap
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import tempfile
|
import tempfile
|
||||||
@ -28,6 +30,8 @@ import pwd
|
|||||||
from pki.client import PKIConnection
|
from pki.client import PKIConnection
|
||||||
import pki.system
|
import pki.system
|
||||||
|
|
||||||
|
from ipalib import errors
|
||||||
|
|
||||||
from ipaplatform import services
|
from ipaplatform import services
|
||||||
from ipaplatform.paths import paths
|
from ipaplatform.paths import paths
|
||||||
from ipapython import certmonger
|
from ipapython import certmonger
|
||||||
@ -37,6 +41,7 @@ from ipapython import ipautil
|
|||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
from ipaserver.install import service
|
from ipaserver.install import service
|
||||||
from ipaserver.install import installutils
|
from ipaserver.install import installutils
|
||||||
|
from ipaserver.install import replication
|
||||||
from ipaserver.install.installutils import stopped_service
|
from ipaserver.install.installutils import stopped_service
|
||||||
from ipapython.ipa_log_manager import log_mgr
|
from ipapython.ipa_log_manager import log_mgr
|
||||||
|
|
||||||
@ -144,7 +149,10 @@ class DogtagInstance(service.Service):
|
|||||||
self.clone = False
|
self.clone = False
|
||||||
|
|
||||||
self.basedn = DN(('o', 'ipa%s' % subsystem.lower()))
|
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.agent_db = tempfile.mkdtemp(prefix="tmp-")
|
||||||
self.ds_port = DEFAULT_DSPORT
|
self.ds_port = DEFAULT_DSPORT
|
||||||
self.server_root = dogtag_constants.SERVER_ROOT
|
self.server_root = dogtag_constants.SERVER_ROOT
|
||||||
@ -435,12 +443,10 @@ class DogtagInstance(service.Service):
|
|||||||
conn = None
|
conn = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
conn = ipaldap.IPAdmin(self.fqdn, self.ds_port)
|
conn = ipaldap.IPAdmin(self.fqdn, ldapi=True, realm=self.realm)
|
||||||
conn.do_simple_bind(
|
conn.do_external_bind('root')
|
||||||
DN(('cn', 'Directory Manager')),
|
|
||||||
self.dm_password)
|
|
||||||
|
|
||||||
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]
|
admin_cert = entry_attrs.get('usercertificate')[0]
|
||||||
|
|
||||||
# TODO(edewata) Add check to warn if there is more than one cert.
|
# TODO(edewata) Add check to warn if there is more than one cert.
|
||||||
@ -462,3 +468,76 @@ class DogtagInstance(service.Service):
|
|||||||
self.log.critical(" %s" % log)
|
self.log.critical(" %s" % log)
|
||||||
|
|
||||||
raise RuntimeError("%s configuration failed." % self.subsystem)
|
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)
|
||||||
|
54
ipaserver/install/ipa_kra_install.py
Normal file → Executable file
54
ipaserver/install/ipa_kra_install.py
Normal file → Executable file
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import tempfile
|
||||||
|
|
||||||
from textwrap import dedent
|
from textwrap import dedent
|
||||||
from ipalib import api
|
from ipalib import api
|
||||||
from ipaplatform import services
|
from ipaplatform import services
|
||||||
@ -28,11 +30,14 @@ from ipapython import admintool
|
|||||||
from ipapython import dogtag
|
from ipapython import dogtag
|
||||||
from ipapython import ipautil
|
from ipapython import ipautil
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
|
from ipaserver.install import service
|
||||||
from ipaserver.install import krainstance
|
from ipaserver.install import krainstance
|
||||||
|
from ipaserver.install import dsinstance
|
||||||
from ipaserver.install import installutils
|
from ipaserver.install import installutils
|
||||||
from ipaserver.install.installutils import create_replica_config
|
from ipaserver.install.installutils import create_replica_config
|
||||||
from ipaserver.install import dogtaginstance
|
from ipaserver.install import dogtaginstance
|
||||||
from ipaserver.install import kra
|
from ipaserver.install import kra
|
||||||
|
from ipaserver.install.installutils import ReplicaConfig
|
||||||
|
|
||||||
|
|
||||||
class KRAInstall(admintool.AdminTool):
|
class KRAInstall(admintool.AdminTool):
|
||||||
@ -129,8 +134,14 @@ class KRAInstaller(KRAInstall):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.installing_replica = dogtaginstance.is_installing_replica("KRA")
|
self.installing_replica = dogtaginstance.is_installing_replica("KRA")
|
||||||
|
self.options.promote = False
|
||||||
|
|
||||||
if self.installing_replica:
|
if self.installing_replica:
|
||||||
|
domain_level = dsinstance.get_domain_level(api)
|
||||||
|
if domain_level > 0:
|
||||||
|
self.options.promote = True
|
||||||
|
return
|
||||||
|
|
||||||
if not self.args:
|
if not self.args:
|
||||||
self.option_parser.error("A replica file is required.")
|
self.option_parser.error("A replica file is required.")
|
||||||
if len(self.args) > 1:
|
if len(self.args) > 1:
|
||||||
@ -160,29 +171,48 @@ class KRAInstaller(KRAInstall):
|
|||||||
super(KRAInstaller, self).run()
|
super(KRAInstaller, self).run()
|
||||||
print(dedent(self.INSTALLER_START_MESSAGE))
|
print(dedent(self.INSTALLER_START_MESSAGE))
|
||||||
|
|
||||||
if not self.installing_replica:
|
self.options.dm_password = self.options.password
|
||||||
replica_config = None
|
self.options.setup_ca = False
|
||||||
|
|
||||||
|
conn = api.Backend.ldap2
|
||||||
|
conn.connect(bind_dn=DN(('cn', 'Directory Manager')),
|
||||||
|
bind_pw=self.options.password)
|
||||||
|
|
||||||
|
config = None
|
||||||
|
if self.installing_replica:
|
||||||
|
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:
|
else:
|
||||||
replica_config = create_replica_config(
|
config = create_replica_config(
|
||||||
self.options.password,
|
self.options.password,
|
||||||
self.replica_file,
|
self.replica_file,
|
||||||
self.options)
|
self.options)
|
||||||
|
|
||||||
self.options.dm_password = self.options.password
|
if config.subject_base is None:
|
||||||
self.options.setup_ca = False
|
attrs = conn.get_ipa_config()
|
||||||
|
config.subject_base = attrs.get('ipacertificatesubjectbase')[0]
|
||||||
|
|
||||||
api.Backend.ldap2.connect(bind_dn=DN('cn=Directory Manager'),
|
if config.master_host_name is None:
|
||||||
bind_pw=self.options.dm_password)
|
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:
|
try:
|
||||||
kra.install_check(api, replica_config, self.options)
|
kra.install_check(api, config, self.options)
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
raise admintool.ScriptError(str(e))
|
raise admintool.ScriptError(str(e))
|
||||||
|
|
||||||
kra.install(api, replica_config, self.options)
|
kra.install(api, config, self.options)
|
||||||
|
|
||||||
# Restart apache for new proxy config file
|
|
||||||
services.knownservices.httpd.restart(capture_output=True)
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
try:
|
try:
|
||||||
|
@ -2,11 +2,15 @@
|
|||||||
# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
from ipalib import api, errors
|
from ipalib import api, errors
|
||||||
|
from ipaplatform import services
|
||||||
from ipapython import certdb
|
from ipapython import certdb
|
||||||
from ipapython import dogtag
|
from ipapython import dogtag
|
||||||
from ipapython import ipautil
|
from ipapython import ipautil
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
|
from ipaserver.install import custodiainstance
|
||||||
from ipaserver.install import cainstance
|
from ipaserver.install import cainstance
|
||||||
from ipaserver.install import krainstance
|
from ipaserver.install import krainstance
|
||||||
from ipaserver.install import dsinstance
|
from ipaserver.install import dsinstance
|
||||||
@ -36,6 +40,9 @@ def install_check(api, replica_config, options):
|
|||||||
if not api.Command.kra_is_enabled()['result']:
|
if not api.Command.kra_is_enabled()['result']:
|
||||||
raise RuntimeError("KRA is not installed on the master system")
|
raise RuntimeError("KRA is not installed on the master system")
|
||||||
|
|
||||||
|
if options.promote:
|
||||||
|
return
|
||||||
|
|
||||||
with certdb.NSSDatabase() as tmpdb:
|
with certdb.NSSDatabase() as tmpdb:
|
||||||
pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
|
pw = ipautil.write_tmp_file(ipautil.ipa_generate_password())
|
||||||
tmpdb.create_db(pw.name)
|
tmpdb.create_db(pw.name)
|
||||||
@ -61,6 +68,25 @@ def install(api, replica_config, options):
|
|||||||
kra.configure_instance(
|
kra.configure_instance(
|
||||||
api.env.realm, api.env.host, options.dm_password,
|
api.env.realm, api.env.host, options.dm_password,
|
||||||
options.dm_password, subject_base=subject)
|
options.dm_password, subject_base=subject)
|
||||||
|
else:
|
||||||
|
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:
|
else:
|
||||||
kra = krainstance.install_replica_kra(replica_config)
|
kra = krainstance.install_replica_kra(replica_config)
|
||||||
|
|
||||||
@ -72,6 +98,9 @@ def install(api, replica_config, options):
|
|||||||
|
|
||||||
kra.enable_client_auth_to_db(kra.dogtag_constants.KRA_CS_CFG_PATH)
|
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):
|
def uninstall(standalone):
|
||||||
dogtag_constants = dogtag.configured_constants(api)
|
dogtag_constants = dogtag.configured_constants(api)
|
||||||
|
@ -47,6 +47,11 @@ from ipapython.ipa_log_manager import log_mgr
|
|||||||
# replicas with KRA configured
|
# replicas with KRA configured
|
||||||
IPA_KRA_RECORD = "ipa-kra"
|
IPA_KRA_RECORD = "ipa-kra"
|
||||||
|
|
||||||
|
ADMIN_GROUPS = [
|
||||||
|
'Enterprise CA Administrators',
|
||||||
|
'Enterprise KRA Administrators',
|
||||||
|
'Security Domain Administrators'
|
||||||
|
]
|
||||||
|
|
||||||
class KRAInstance(DogtagInstance):
|
class KRAInstance(DogtagInstance):
|
||||||
"""
|
"""
|
||||||
@ -147,7 +152,7 @@ class KRAInstance(DogtagInstance):
|
|||||||
# Security Domain Authentication
|
# Security Domain Authentication
|
||||||
config.set("KRA", "pki_security_domain_https_port", "443")
|
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_password", self.admin_password)
|
||||||
config.set("KRA", "pki_security_domain_user", "admin")
|
config.set("KRA", "pki_security_domain_user", self.admin_user)
|
||||||
|
|
||||||
# issuing ca
|
# issuing ca
|
||||||
config.set("KRA", "pki_issuing_ca_uri", "https://%s" %
|
config.set("KRA", "pki_issuing_ca_uri", "https://%s" %
|
||||||
@ -166,8 +171,8 @@ class KRAInstance(DogtagInstance):
|
|||||||
config.set("KRA", "pki_client_pkcs12_password", self.admin_password)
|
config.set("KRA", "pki_client_pkcs12_password", self.admin_password)
|
||||||
|
|
||||||
# Administrator
|
# Administrator
|
||||||
config.set("KRA", "pki_admin_name", "admin")
|
config.set("KRA", "pki_admin_name", self.admin_user)
|
||||||
config.set("KRA", "pki_admin_uid", "admin")
|
config.set("KRA", "pki_admin_uid", self.admin_user)
|
||||||
config.set("KRA", "pki_admin_email", "root@localhost")
|
config.set("KRA", "pki_admin_email", "root@localhost")
|
||||||
config.set("KRA", "pki_admin_password", self.admin_password)
|
config.set("KRA", "pki_admin_password", self.admin_password)
|
||||||
config.set("KRA", "pki_admin_nickname", "ipa-ca-agent")
|
config.set("KRA", "pki_admin_nickname", "ipa-ca-agent")
|
||||||
@ -227,15 +232,16 @@ class KRAInstance(DogtagInstance):
|
|||||||
pent = pwd.getpwnam(PKI_USER)
|
pent = pwd.getpwnam(PKI_USER)
|
||||||
os.chown(p12_tmpfile_name, pent.pw_uid, pent.pw_gid)
|
os.chown(p12_tmpfile_name, pent.pw_uid, pent.pw_gid)
|
||||||
|
|
||||||
# create admin cert file if it does not exist
|
# FIXME
|
||||||
cert = DogtagInstance.get_admin_cert(self)
|
# # create admin cert file if it does not exist
|
||||||
with open(paths.ADMIN_CERT_PATH, "w") as admin_path:
|
# cert = DogtagInstance.get_admin_cert(self)
|
||||||
admin_path.write(cert)
|
# with open(paths.ADMIN_CERT_PATH, "w") as admin_path:
|
||||||
|
# admin_path.write(cert)
|
||||||
|
|
||||||
# Security domain registration
|
# Security domain registration
|
||||||
config.set("KRA", "pki_security_domain_hostname", self.master_host)
|
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_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",
|
config.set("KRA", "pki_security_domain_password",
|
||||||
self.admin_password)
|
self.admin_password)
|
||||||
|
|
||||||
@ -342,6 +348,54 @@ class KRAInstance(DogtagInstance):
|
|||||||
dogtag.configured_constants().KRA_CS_CFG_PATH,
|
dogtag.configured_constants().KRA_CS_CFG_PATH,
|
||||||
dogtag_constants)
|
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):
|
def install_replica_kra(config, postinstall=False):
|
||||||
"""
|
"""
|
||||||
|
@ -28,8 +28,8 @@ import ipaclient.ipachangeconf
|
|||||||
import ipaclient.ntpconf
|
import ipaclient.ntpconf
|
||||||
from ipaserver.install import (
|
from ipaserver.install import (
|
||||||
bindinstance, ca, cainstance, certs, dns, dsinstance, httpinstance,
|
bindinstance, ca, cainstance, certs, dns, dsinstance, httpinstance,
|
||||||
installutils, kra, krbinstance, memcacheinstance, ntpinstance,
|
installutils, kra, krainstance, krbinstance, memcacheinstance,
|
||||||
otpdinstance, custodiainstance, service)
|
ntpinstance, otpdinstance, custodiainstance, service)
|
||||||
from ipaserver.install.installutils import create_replica_config
|
from ipaserver.install.installutils import create_replica_config
|
||||||
from ipaserver.install.installutils import ReplicaConfig
|
from ipaserver.install.installutils import ReplicaConfig
|
||||||
from ipaserver.install.replication import (
|
from ipaserver.install.replication import (
|
||||||
@ -772,10 +772,6 @@ def promote_check(installer):
|
|||||||
|
|
||||||
installer._top_dir = tempfile.mkdtemp("ipa")
|
installer._top_dir = tempfile.mkdtemp("ipa")
|
||||||
|
|
||||||
# FIXME: to implement yet
|
|
||||||
if options.setup_kra:
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
tasks.check_selinux_status()
|
tasks.check_selinux_status()
|
||||||
|
|
||||||
client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||||
@ -922,7 +918,7 @@ def promote_check(installer):
|
|||||||
config.subject_base = DN(subject_base)
|
config.subject_base = DN(subject_base)
|
||||||
|
|
||||||
# Find if any server has a CA
|
# 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:
|
if ca_host is not None:
|
||||||
config.ca_host_name = ca_host
|
config.ca_host_name = ca_host
|
||||||
ca_enabled = True
|
ca_enabled = True
|
||||||
@ -932,6 +928,13 @@ def promote_check(installer):
|
|||||||
"installed, can't proceed without certs")
|
"installed, can't proceed without certs")
|
||||||
sys.exit(3)
|
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 options.setup_ca:
|
||||||
if not ca_enabled:
|
if not ca_enabled:
|
||||||
root_logger.error("The remote master does not have a CA "
|
root_logger.error("The remote master does not have a CA "
|
||||||
@ -1083,7 +1086,17 @@ def promote(installer):
|
|||||||
ca_cert_bundle=ca_data)
|
ca_cert_bundle=ca_data)
|
||||||
|
|
||||||
if options.setup_kra:
|
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()
|
ds.replica_populate()
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ import traceback
|
|||||||
from ipapython import sysrestore, ipautil, dogtag, ipaldap
|
from ipapython import sysrestore, ipautil, dogtag, ipaldap
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
from ipapython.ipa_log_manager import *
|
from ipapython.ipa_log_manager import *
|
||||||
from ipalib import errors, certstore
|
from ipalib import api, errors, certstore
|
||||||
from ipaplatform import services
|
from ipaplatform import services
|
||||||
from ipaplatform.paths import paths
|
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
|
# If there are no changes just pass
|
||||||
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):
|
class Service(object):
|
||||||
def __init__(self, service_name, service_desc=None, sstore=None,
|
def __init__(self, service_name, service_desc=None, sstore=None,
|
||||||
dm_password=None, ldapi=True, autobind=ipaldap.AUTOBIND_AUTO,
|
dm_password=None, ldapi=True, autobind=ipaldap.AUTOBIND_AUTO,
|
||||||
|
Loading…
Reference in New Issue
Block a user