summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2015-08-07 15:14:58 -0400
committerSimo Sorce <simo@redhat.com>2015-10-01 16:20:49 -0400
commitbbd4a394f8dddd6f07730a91b6e4583f51473cce (patch)
tree37f9bed3463c99334f998cea88b96c955ff9bc93
parent7142caf4351a025a72051577775e3cf8969562aa (diff)
downloadfreeipa-bbd4a394f8dddd6f07730a91b6e4583f51473cce.tar.gz
freeipa-bbd4a394f8dddd6f07730a91b6e4583f51473cce.tar.xz
freeipa-bbd4a394f8dddd6f07730a91b6e4583f51473cce.zip
Allow to setup the CA when promoting a replica
This patch makes --setup-ca work to set upa clone CA while creating a new replica. The standalone ipa-ca-install script is not converted yet though. Signed-off-by: Simo Sorce <simo@redhat.com>
-rw-r--r--install/share/ca-topology.uldif5
-rw-r--r--ipaserver/install/ca.py11
-rw-r--r--ipaserver/install/cainstance.py231
-rw-r--r--ipaserver/install/dogtaginstance.py1
-rw-r--r--ipaserver/install/replication.py88
-rw-r--r--ipaserver/install/server/replicainstall.py58
6 files changed, 332 insertions, 62 deletions
diff --git a/install/share/ca-topology.uldif b/install/share/ca-topology.uldif
index 3da9eaee1..8c9998cbc 100644
--- a/install/share/ca-topology.uldif
+++ b/install/share/ca-topology.uldif
@@ -11,5 +11,10 @@ default: ipaReplTopoConfRoot: o=ipaca
default: cn: ipaca
# Update CA replication settings
+dn: cn=o\3Dipaca,cn=mapping tree,cn=config
+add: aci: (targetattr=*)(version 3.0;acl "permission:Add Replication Agreements";allow (add) groupdn = "ldap:///cn=Add Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
+add: aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5Replica)(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement)(objectClass=nsMappingTree))")(version 3.0; acl "permission:Modify Replication Agreements"; allow (read, write, search) groupdn = "ldap:///cn=Modify Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
+add: aci: (targetattr=*)(targetfilter="(|(objectclass=nsds5replicationagreement)(objectclass=nsDSWindowsReplicationAgreement))")(version 3.0;acl "permission:Remove Replication Agreements";allow (delete) groupdn = "ldap:///cn=Remove Replication Agreements,cn=permissions,cn=pbac,$SUFFIX";)
+
dn: cn=replica,cn=o\3Dipaca,cn=mapping tree,cn=config
onlyifexist: nsds5replicabinddngroup: cn=replication managers,cn=sysaccounts,cn=etc,$SUFFIX
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index 3c36e1b66..03500b1ef 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -31,16 +31,21 @@ def install_check(standalone, replica_config, options):
if standalone and api.env.ra_plugin == 'selfsign':
sys.exit('A selfsign CA can not be added')
- if not ipautil.file_exists(replica_config.dir + "/cacert.p12"):
+ if ((not options.promote
+ and not ipautil.file_exists(replica_config.dir + "/cacert.p12"))):
print('CA cannot be installed in CA-less setup.')
sys.exit(1)
if standalone and not options.skip_conncheck:
+ principal = options.principal
+ if principal is None:
+ principal = "admin"
replica_conn_check(
replica_config.master_host_name, host_name, realm_name, True,
- replica_config.ca_ds_port, options.admin_password)
+ replica_config.ca_ds_port, options.admin_password,
+ principal=principal)
- if options.skip_schema_check:
+ if options.skip_schema_check or options.promote:
root_logger.info("Skipping CA DS schema check")
else:
cainstance.replica_ca_install_check(replica_config)
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index fefcb8e76..ff906cea5 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -64,6 +64,7 @@ from ipaserver.install import certs
from ipaserver.install import dsinstance
from ipaserver.install import installutils
from ipaserver.install import ldapupdate
+from ipaserver.install import replication
from ipaserver.install import service
from ipaserver.install.dogtaginstance import DogtagInstance
from ipaserver.install.dogtaginstance import PKI_USER, DEFAULT_DSPORT
@@ -92,6 +93,13 @@ ConfigFile = /usr/share/pki/ca/conf/database.ldif
"""
+ADMIN_GROUPS = [
+ 'Enterprise CA Administrators',
+ 'Enterprise KRA Administrators',
+ 'Security Domain Administrators'
+]
+
+
def check_port():
"""
Check that dogtag port (8443) is available.
@@ -410,6 +418,7 @@ class CAInstance(DogtagInstance):
self.ra_cert = None
self.requestId = None
self.log = log_mgr.get_logger(self)
+ self.no_db_setup = False
def configure_instance(self, host_name, dm_password,
admin_password, ds_port=DEFAULT_DSPORT,
@@ -431,6 +440,7 @@ class CAInstance(DogtagInstance):
"""
self.fqdn = host_name
self.dm_password = dm_password
+ self.admin_user = "admin"
self.admin_password = admin_password
self.ds_port = ds_port
self.pkcs12_info = pkcs12_info
@@ -537,8 +547,8 @@ class CAInstance(DogtagInstance):
config.set("CA", "pki_client_pkcs12_password", self.admin_password)
# Administrator
- config.set("CA", "pki_admin_name", "admin")
- config.set("CA", "pki_admin_uid", "admin")
+ config.set("CA", "pki_admin_name", self.admin_user)
+ config.set("CA", "pki_admin_uid", self.admin_user)
config.set("CA", "pki_admin_email", "root@localhost")
config.set("CA", "pki_admin_password", self.admin_password)
config.set("CA", "pki_admin_nickname", "ipa-ca-agent")
@@ -575,6 +585,12 @@ class CAInstance(DogtagInstance):
config.set("CA", "pki_ca_signing_key_algorithm", self.ca_signing_algorithm)
if self.clone:
+
+ if self.no_db_setup:
+ config.set("CA", "pki_ds_create_new_db", "False")
+ config.set("CA", "pki_clone_setup_replication", "False")
+ config.set("CA", "pki_clone_reindex_data", "True")
+
cafile = self.pkcs12_info[0]
shutil.copy(cafile, paths.TMP_CA_P12)
pent = pwd.getpwnam(PKI_USER)
@@ -583,7 +599,7 @@ class CAInstance(DogtagInstance):
# Security domain registration
config.set("CA", "pki_security_domain_hostname", self.master_host)
config.set("CA", "pki_security_domain_https_port", "443")
- config.set("CA", "pki_security_domain_user", "admin")
+ config.set("CA", "pki_security_domain_user", self.admin_user)
config.set("CA", "pki_security_domain_password", self.admin_password)
# Clone
@@ -692,7 +708,7 @@ class CAInstance(DogtagInstance):
"-client_certdb_pwd", self.admin_password,
"-preop_pin" , preop_pin,
"-domain_name", self.security_domain_name,
- "-admin_user", "admin",
+ "-admin_user", self.admin_user,
"-admin_email", "root@localhost",
"-admin_password", self.admin_password,
"-agent_name", "ipa-ca-agent",
@@ -760,7 +776,7 @@ class CAInstance(DogtagInstance):
args.append("-sd_admin_port")
args.append("443")
args.append("-sd_admin_name")
- args.append("admin")
+ args.append(self.admin_user)
args.append("-sd_admin_password")
args.append(self.admin_password)
args.append("-clone_master_port")
@@ -1469,6 +1485,211 @@ class CAInstance(DogtagInstance):
dogtag.configured_constants().CS_CFG_PATH,
dogtag_constants)
+ def __create_ds_db(self):
+ '''
+ Create PKI database. Is needed when pkispawn option
+ pki_ds_create_new_db is set to False
+ '''
+
+ if not self.admin_conn:
+ self.ldap_connect()
+
+ backend = 'ipaca'
+ suffix = DN(('o', 'ipaca'))
+
+ # replication
+ dn = DN(('cn', str(suffix)), ('cn', 'mapping tree'), ('cn', 'config'))
+ entry = self.admin_conn.make_entry(
+ dn,
+ objectclass=["top", "extensibleObject", "nsMappingTree"],
+ cn=[suffix],
+ )
+ entry['nsslapd-state'] = ['Backend']
+ entry['nsslapd-backend'] = [backend]
+ self.admin_conn.add_entry(entry)
+
+ # database
+ dn = DN(('cn', 'ipaca'), ('cn', 'ldbm database'), ('cn', 'plugins'),
+ ('cn', 'config'))
+ entry = self.admin_conn.make_entry(
+ dn,
+ objectclass=["top", "extensibleObject", "nsBackendInstance"],
+ cn=[backend],
+ )
+ entry['nsslapd-suffix'] = [suffix]
+ self.admin_conn.add_entry(entry)
+
+ def __setup_replication(self):
+
+ repl = replication.CAReplicationManager(self.realm, self.fqdn)
+ repl.setup_cs_replication(self.master_host)
+
+ # 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)
+
+ def __restart_http_instance(self):
+ # We need to restart apache as we drop a new config file in there
+ services.knownservices.httpd.restart(capture_output=True)
+
+ def __enable_instance(self):
+ basedn = ipautil.realm_to_suffix(self.realm)
+ self.ldap_enable('CA', self.fqdn, None, basedn, ['caRenewalMaster'])
+
+ def configure_replica(self, master_host, subject_base=None,
+ ca_cert_bundle=None, ca_signing_algorithm=None,
+ ca_type=None):
+ """Creates a replica CA, creating a local DS backend and using
+ the topology plugin to manage replication.
+ Requires domain_level >=1 and custodia on the master.
+ """
+ self.ds_port = DEFAULT_DSPORT
+ self.master_host = master_host
+ self.master_replication_port = DEFAULT_DSPORT
+ if subject_base is None:
+ self.subject_base = DN(('O', self.realm))
+ else:
+ self.subject_base = subject_base
+ if ca_signing_algorithm is None:
+ self.ca_signing_algorithm = 'SHA256withRSA'
+ else:
+ self.ca_signing_algorithm = ca_signing_algorithm
+ if ca_type is not None:
+ self.ca_type = ca_type
+ else:
+ self.ca_type = 'generic'
+
+ self.pkcs12_info = ca_cert_bundle
+ self.no_db_setup = True
+ self.clone = True
+
+ # TODO: deal with "Externally signed CA setups"
+
+ # Set up steps
+ self.step("creating certificate server user", create_ca_user)
+
+ # Setup Database
+ 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)
+
+ # Setup instance
+ self.step("setting up certificate server", self.__spawn_instance)
+ self.step("stopping instance to update CS.cfg", self.stop_instance)
+ self.step("backing up CS.cfg", self.backup_config)
+ self.step("disabling nonces", self.__disable_nonce)
+ self.step("set up CRL publishing", self.__enable_crl_publish)
+ 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("starting instance", self.start_instance)
+
+ self.step("importing CA chain to RA certificate database",
+ self.__import_ca_chain)
+ self.step("fixing RA database permissions", self.fix_ra_perms)
+ self.step("setting up signing cert profile", self.__setup_sign_profile)
+ self.step("setting audit signing renewal to 2 years",
+ self.set_audit_renewal)
+
+ self.step("configure certmonger for renewals",
+ self.configure_certmonger_renewal)
+ self.step("configure certificate renewals",
+ self.configure_renewal)
+ self.step("configure RA certificate renewal",
+ self.configure_agent_renewal)
+ self.step("configure Server-Cert certificate renewal",
+ self.track_servercert)
+ self.step("Configure HTTP to proxy connections",
+ self.http_proxy)
+ self.step("Restart HTTP server to pick up changes",
+ self.__restart_http_instance)
+
+ self.step("enabling CA instance", self.__enable_instance)
+
+ self.start_creation(runtime=210)
+
+
def replica_ca_install_check(config):
if not config.setup_ca:
return
diff --git a/ipaserver/install/dogtaginstance.py b/ipaserver/install/dogtaginstance.py
index 0d60a19d0..3a269f973 100644
--- a/ipaserver/install/dogtaginstance.py
+++ b/ipaserver/install/dogtaginstance.py
@@ -116,7 +116,6 @@ class DogtagInstance(service.Service):
self.dogtag_constants = dogtag_constants
self.realm = realm
- self.dm_password = None
self.admin_password = None
self.fqdn = host_name
self.pkcs12_info = None
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index 45dea27bb..a09467897 100644
--- a/ipaserver/install/replication.py
+++ b/ipaserver/install/replication.py
@@ -40,6 +40,7 @@ WIN_USER_CONTAINER = DN(('cn', 'Users'))
# the default container used by IPA for user entries
IPA_USER_CONTAINER = DN(('cn', 'users'), ('cn', 'accounts'))
PORT = 636
+DEFAULT_PORT = 389
TIMEOUT = 120
REPL_MAN_DN = DN(('cn', 'replication manager'), ('cn', 'config'))
DNA_DN = DN(('cn', 'Posix IDs'), ('cn', 'Distributed Numeric Assignment Plugin'), ('cn', 'plugins'), ('cn', 'config'))
@@ -190,6 +191,8 @@ class ReplicationManager(object):
self.starttls = starttls
self.suffix = ipautil.realm_to_suffix(realm)
self.need_memberof_fixup = False
+ self.db_suffix = self.suffix
+ self.agreement_name_format = "meTo%s"
# The caller is allowed to pass in an existing IPAdmin connection.
# Open a new one if not provided
@@ -303,7 +306,7 @@ class ReplicationManager(object):
agreement_types_filters = []
if IPA_REPLICA in agreement_types:
agreement_types_filters.append('(&(objectclass=nsds5ReplicationAgreement)(nsDS5ReplicaRoot=%s))'
- % self.suffix)
+ % self.db_suffix)
if WINSYNC in agreement_types:
agreement_types_filters.append('(objectclass=nsDSWindowsReplicationAgreement)')
if len(agreement_types_filters) > 1:
@@ -415,7 +418,8 @@ class ReplicationManager(object):
return "2"
def replica_dn(self):
- return DN(('cn','replica'),('cn',self.suffix),('cn','mapping tree'),('cn','config'))
+ return DN(('cn', 'replica'), ('cn', self.db_suffix),
+ ('cn', 'mapping tree'), ('cn', 'config'))
def replica_config(self, conn, replica_id, replica_binddn):
assert isinstance(replica_binddn, DN)
@@ -446,7 +450,7 @@ class ReplicationManager(object):
dn,
objectclass=["top", "nsds5replica", "extensibleobject"],
cn=["replica"],
- nsds5replicaroot=[str(self.suffix)],
+ nsds5replicaroot=[str(self.db_suffix)],
nsds5replicaid=[str(replica_id)],
nsds5replicatype=[replica_type],
nsds5flags=["1"],
@@ -496,7 +500,7 @@ class ReplicationManager(object):
'objectclass': [
'top', 'extensibleObject', 'nsBackendInstance'],
'cn': [cn],
- 'nsslapd-suffix': [str(self.suffix)],
+ 'nsslapd-suffix': [str(self.db_suffix)],
'nsfarmserverurl': urls,
'nsmultiplexorbinddn': [self.repl_man_dn],
'nsmultiplexorcredentials': [self.repl_man_passwd],
@@ -517,22 +521,23 @@ class ReplicationManager(object):
def setup_chaining_farm(self, conn):
try:
- conn.modify_s(self.suffix, [(ldap.MOD_ADD, 'aci',
+ conn.modify_s(self.db_suffix, [(ldap.MOD_ADD, 'aci',
[ "(targetattr = \"*\")(version 3.0; acl \"Proxied authorization for database links\"; allow (proxy) userdn = \"ldap:///%s\";)" % self.repl_man_dn ])])
except ldap.TYPE_OR_VALUE_EXISTS:
- root_logger.debug("proxy aci already exists in suffix %s on %s" % (self.suffix, conn.host))
+ root_logger.debug("proxy aci already exists in suffix %s on %s"
+ % (self.db_suffix, conn.host))
def get_mapping_tree_entry(self):
try:
entries = self.conn.get_entries(
DN(('cn', 'mapping tree'), ('cn', 'config')),
ldap.SCOPE_ONELEVEL,
- "(cn=\"%s\")" % (self.suffix))
+ "(cn=\"%s\")" % (self.db_suffix))
# TODO: Check we got only one entry
return entries[0]
except errors.NotFound:
root_logger.debug(
- "failed to find mapping tree entry for %s", self.suffix)
+ "failed to find mapping tree entry for %s", self.db_suffix)
raise
@@ -554,7 +559,8 @@ class ReplicationManager(object):
try:
self.conn.modify_s(dn, mod)
except ldap.TYPE_OR_VALUE_EXISTS:
- root_logger.debug("chainOnUpdate already enabled for %s" % self.suffix)
+ root_logger.debug("chainOnUpdate already enabled for %s"
+ % self.db_suffix)
def setup_chain_on_update(self, other_conn):
chainbe = self.setup_chaining_backend(other_conn)
@@ -623,7 +629,7 @@ class ReplicationManager(object):
master is not used for IPA agreements but for dogtag it will
tell which side we want.
"""
- cn = "meTo%s" % (hostname)
+ cn = self.agreement_name_format % (hostname)
dn = DN(('cn', cn), self.replica_dn())
return (cn, dn)
@@ -656,7 +662,7 @@ class ReplicationManager(object):
nsds5replicahost=[b_hostname],
nsds5replicaport=[str(port)],
nsds5replicatimeout=[str(TIMEOUT)],
- nsds5replicaroot=[str(self.suffix)],
+ nsds5replicaroot=[str(self.db_suffix)],
description=["me to %s" % b_hostname],
)
if master is None:
@@ -841,10 +847,12 @@ class ReplicationManager(object):
return self.conn.delete_entry(dn)
def delete_referral(self, hostname):
- dn = DN(('cn', self.suffix), ('cn', 'mapping tree'), ('cn', 'config'))
+ dn = DN(('cn', self.db_suffix),
+ ('cn', 'mapping tree'), ('cn', 'config'))
# TODO: should we detect proto/port somehow ?
mod = [(ldap.MOD_DELETE, 'nsslapd-referral',
- 'ldap://%s/%s' % (ipautil.format_netloc(hostname, 389), self.suffix))]
+ 'ldap://%s/%s' % (ipautil.format_netloc(hostname, 389),
+ self.db_suffix))]
try:
self.conn.modify_s(dn, mod)
@@ -1709,8 +1717,8 @@ class CSReplicationManager(ReplicationManager):
def __init__(self, realm, hostname, dirman_passwd, port):
super(CSReplicationManager, self).__init__(
- realm, hostname, dirman_passwd, port, starttls=True)
- self.suffix = DN(('o', 'ipaca'))
+ realm, hostname, dirman_passwd, port)
+ self.db_suffix = DN(('o', 'ipaca'))
self.hostnames = [] # set before calling or agreement_dn() will fail
def agreement_dn(self, hostname, master=None):
@@ -1755,24 +1763,27 @@ class CSReplicationManager(ReplicationManager):
raise errors.NotFound(reason='No agreement found for %s' % hostname)
def delete_referral(self, hostname, port):
- dn = DN(('cn', self.suffix), ('cn', 'mapping tree'), ('cn', 'config'))
+ dn = DN(('cn', self.db_suffix),
+ ('cn', 'mapping tree'), ('cn', 'config'))
entry = self.conn.get_entry(dn)
try:
# TODO: should we detect proto somehow ?
- entry['nsslapd-referral'].remove('ldap://%s/%s' %
- (ipautil.format_netloc(hostname, port), self.suffix))
+ entry['nsslapd-referral'].remove(
+ 'ldap://%s/%s' %
+ (ipautil.format_netloc(hostname, port), self.db_suffix))
self.conn.update_entry(entry)
except Exception as e:
root_logger.debug("Failed to remove referral value: %s" % e)
def has_ipaca(self):
try:
- entry = self.conn.get_entry(self.suffix)
+ entry = self.conn.get_entry(self.db_suffix)
except errors.NotFound:
return False
else:
return True
+
def get_cs_replication_manager(realm, host, dirman_passwd):
"""Get a CSReplicationManager for a remote host
@@ -1801,3 +1812,42 @@ def get_cs_replication_manager(realm, host, dirman_passwd):
root_logger.debug('PKI tree not found on %s:%s' % (host, port))
raise errors.NotFound(reason='Cannot reach PKI DS at %s on ports %s' % (host, ports))
+
+
+class CAReplicationManager(ReplicationManager):
+ """ReplicationManager specific to CA agreements for domain level 1 and
+ above servers.
+ """
+
+ def __init__(self, realm, hostname):
+ # Always connect to self over ldapi
+ conn = ipaldap.IPAdmin(hostname, ldapi=True, realm=realm)
+ conn.do_external_bind('root')
+ super(CAReplicationManager, self).__init__(
+ realm, hostname, None, port=DEFAULT_PORT, conn=conn)
+ self.db_suffix = DN(('o', 'ipaca'))
+ self.agreement_name_format = "caTo%s"
+
+ def setup_cs_replication(self, r_hostname):
+ """
+ Assumes a promote replica with working GSSAPI for replication
+ and unified DS instance.
+ """
+ r_conn = ipaldap.IPAdmin(r_hostname, port=389, protocol='ldap')
+ r_conn.do_sasl_gssapi_bind()
+
+ # Setup the first half
+ l_id = self._get_replica_id(self.conn, r_conn)
+ self.basic_replication_setup(self.conn, l_id, self.repl_man_dn, None)
+
+ # Now setup the other half
+ r_id = self._get_replica_id(r_conn, r_conn)
+ self.basic_replication_setup(r_conn, r_id, self.repl_man_dn, None)
+
+ self.setup_agreement(r_conn, self.conn.host, isgssapi=True)
+ self.setup_agreement(self.conn, r_hostname, isgssapi=True)
+
+ # Finally start replication
+ ret = self.start_replication(r_conn, master=False)
+ if ret != 0:
+ raise RuntimeError("Failed to start replication")
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index dcfaaedc2..363ada675 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -771,9 +771,9 @@ def install(installer):
def promote_check(installer):
options = installer
+ installer._top_dir = tempfile.mkdtemp("ipa")
+
# FIXME: to implement yet
- if options.setup_ca:
- raise NotImplementedError
if options.setup_kra:
raise NotImplementedError
@@ -814,8 +814,10 @@ def promote_check(installer):
config.host_name = api.env.host
config.domain_name = api.env.domain
config.master_host_name = api.env.server
+ config.ca_host_name = api.env.ca_host
config.setup_ca = options.setup_ca
config.setup_kra = options.setup_kra
+ config.dir = installer._top_dir
installutils.verify_fqdn(config.host_name, options.no_host_dns)
installutils.verify_fqdn(config.master_host_name, options.no_host_dns)
@@ -1117,14 +1119,6 @@ def promote(installer):
config.realm_name)
custodia.create_replica(config.master_host_name)
- if config.setup_ca:
- options.realm_name = config.realm_name
- options.domain_name = config.domain_name
- options.host_name = config.host_name
- options.dm_password = config.dirman_password
-
- ca.install(False, config, options)
-
krb = install_krb(config,
setup_pkinit=not options.no_pkinit,
promote=True)
@@ -1133,37 +1127,33 @@ def promote(installer):
auto_redirect=not options.no_ui_redirect,
promote=True)
- otpd = otpdinstance.OtpdInstance()
- otpd.create_instance('OTPD', config.host_name, config.dirman_password,
- ipautil.realm_to_suffix(config.realm_name))
-
- CA = cainstance.CAInstance(
- config.realm_name, certs.NSS_DIR,
- dogtag_constants=dogtag_constants)
- CA.dm_password = config.dirman_password
- CA.configure_certmonger_renewal()
- CA.fix_ra_perms()
-
# Apply any LDAP updates. Needs to be done after the replica is synced-up
service.print_msg("Applying LDAP updates")
ds.apply_updates()
- if options.setup_kra:
- kra.install(api, config, options)
- else:
- service.print_msg("Restarting the directory server")
- ds.restart()
-
- service.print_msg("Restarting the KDC")
- krb.restart()
+ otpd = otpdinstance.OtpdInstance()
+ otpd.create_instance('OTPD', config.host_name, config.dirman_password,
+ ipautil.realm_to_suffix(config.realm_name))
if config.setup_ca:
- dogtag_service = services.knownservices[dogtag_constants.SERVICE_NAME]
- dogtag_service.restart(dogtag_constants.PKI_INSTANCE_NAME)
+ options.realm_name = config.realm_name
+ options.domain_name = config.domain_name
+ options.host_name = config.host_name
+ options.dm_password = config.dirman_password
+ ca_data = (os.path.join(config.dir, 'cacert.p12'),
+ config.dirman_password)
+ custodia.get_ca_keys(config.ca_host_name, ca_data[0], ca_data[1])
+
+ ca = cainstance.CAInstance(config.realm_name, certs.NSS_DIR,
+ dogtag_constants=dogtag.install_constants,
+ host_name=config.host_name,
+ dm_password=config.dirman_password)
+ ca.configure_replica(config.ca_host_name,
+ subject_base=config.subject_base,
+ ca_cert_bundle=ca_data)
- # Restart httpd to pick up the new IPA configuration
- service.print_msg("Restarting the web server")
- http.restart()
+ if options.setup_kra:
+ kra.install(api, config, options)
ds.replica_populate()