summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xinstall/tools/ipa-ca-install18
-rw-r--r--install/tools/man/ipa-ca-install.16
-rw-r--r--install/tools/man/ipa-server-install.13
-rw-r--r--ipaserver/install/ca.py123
-rw-r--r--ipaserver/install/cainstance.py14
-rw-r--r--ipaserver/install/certs.py20
-rw-r--r--ipaserver/install/dsinstance.py67
-rw-r--r--ipaserver/install/installutils.py4
-rw-r--r--ipaserver/install/ipa_cacert_manage.py4
-rw-r--r--ipaserver/install/krainstance.py7
-rw-r--r--ipaserver/install/server/__init__.py3
-rw-r--r--ipaserver/install/server/install.py8
-rw-r--r--ipaserver/install/server/replicainstall.py19
13 files changed, 198 insertions, 98 deletions
diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
index 3451a8e0a..29952a420 100755
--- a/install/tools/ipa-ca-install
+++ b/install/tools/ipa-ca-install
@@ -81,6 +81,11 @@ def parse_options():
help=(
"The certificate subject base "
"(default O=<realm-name>)"))
+ parser.add_option("--ca-subject", dest="ca_subject",
+ default=None,
+ help=(
+ "The CA certificate subject DN "
+ "(default CN=Certificate Authority,O=<realm-name>)"))
options, args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
@@ -177,7 +182,6 @@ def install_replica(safe_options, options, filename):
options.domain_name = config.domain_name
options.dm_password = config.dirman_password
options.host_name = config.host_name
- options.subject_base = config.subject_base
if os.path.exists(cafile):
options.ca_cert_file = cafile
else:
@@ -206,6 +210,18 @@ def install_master(safe_options, options):
if not options.subject_base:
options.subject_base = installutils.default_subject_base(api.env.realm)
+ if not options.ca_subject:
+ options.ca_subject = installutils.default_ca_subject_dn(
+ options.subject_base)
+
+ try:
+ ca.subject_validator(ca.VALID_SUBJECT_BASE_ATTRS, options.subject_base)
+ except ValueError as e:
+ sys.exit("Subject base: {}".format(e.message))
+ try:
+ ca.subject_validator(ca.VALID_SUBJECT_ATTRS, options.ca_subject)
+ except ValueError as e:
+ sys.exit("CA subject: {}".format(e.message))
ca.install_check(True, None, options)
ca.install(True, None, options)
diff --git a/install/tools/man/ipa-ca-install.1 b/install/tools/man/ipa-ca-install.1
index aa186987a..16e5431b6 100644
--- a/install/tools/man/ipa-ca-install.1
+++ b/install/tools/man/ipa-ca-install.1
@@ -46,6 +46,12 @@ Type of the external CA. Possible values are "generic", "ms-cs". Default value i
\fB\-\-external\-cert\-file\fR=\fIFILE\fR
File containing the IPA CA certificate and the external CA certificate chain. The file is accepted in PEM and DER certificate and PKCS#7 certificate chain formats. This option may be used multiple times.
.TP
+\fB\-\-ca\-subject\fR=\fISUBJECT\fR
+The CA certificate subject DN (default CN=Certificate Authority,O=REALM.NAME)
+.TP
+\fB\-\-subject\-base\fR=\fISUBJECT\fR
+The subject base for certificates issued by IPA (default O=REALM.NAME)
+.TP
\fB\-\-ca\-signing\-algorithm\fR=\fIALGORITHM\fR
Signing algorithm of the IPA CA certificate. Possible values are SHA1withRSA, SHA256withRSA, SHA512withRSA. Default value is SHA256withRSA. Use this option with --external-ca if the external CA does not support the default signing algorithm.
.TP
diff --git a/install/tools/man/ipa-server-install.1 b/install/tools/man/ipa-server-install.1
index 07f772ad4..9568888ff 100644
--- a/install/tools/man/ipa-server-install.1
+++ b/install/tools/man/ipa-server-install.1
@@ -122,6 +122,9 @@ Name of the Kerberos KDC SSL certificate to install
\fB\-\-ca\-cert\-file\fR=\fIFILE\fR
File containing the CA certificate of the CA which issued the Directory Server, Apache Server and Kerberos KDC certificates. The file is accepted in PEM and DER certificate and PKCS#7 certificate chain formats. This option may be used multiple times. Use this option if the CA certificate is not present in the certificate files.
.TP
+\fB\-\-ca\-subject\fR=\fISUBJECT\fR
+The CA certificate subject DN (default CN=Certificate Authority,O=REALM.NAME)
+.TP
\fB\-\-subject\-base\fR=\fISUBJECT\fR
The subject base for certificates issued by IPA (default O=REALM.NAME)
.TP
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index 7b67110e2..cc52b9053 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -13,6 +13,7 @@ import os.path
import six
+from ipalib.constants import IPA_CA_CN
from ipalib.install import certstore
from ipalib.install.service import enroll_only, master_install_only, replica_install_only
from ipaserver.install import sysupgrade
@@ -28,7 +29,7 @@ from ipaplatform import services
from ipaplatform.paths import paths
from ipaserver.install import installutils, certs
from ipaserver.install.replication import replica_conn_check
-from ipalib import api, x509
+from ipalib import api, errors, x509
from ipapython.dn import DN
from ipapython.ipa_log_manager import root_logger
@@ -37,18 +38,53 @@ from . import conncheck, dogtag
if six.PY3:
unicode = str
-VALID_SUBJECT_ATTRS = ['st', 'o', 'ou', 'dnqualifier', 'c',
- 'serialnumber', 'l', 'title', 'sn', 'givenname',
- 'initials', 'generationqualifier', 'dc', 'mail',
- 'uid', 'postaladdress', 'postalcode', 'postofficebox',
- 'houseidentifier', 'e', 'street', 'pseudonym',
- 'incorporationlocality', 'incorporationstate',
- 'incorporationcountry', 'businesscategory']
+VALID_SUBJECT_BASE_ATTRS = {
+ 'st', 'o', 'ou', 'dnqualifier', 'c', 'serialnumber', 'l', 'title', 'sn',
+ 'givenname', 'initials', 'generationqualifier', 'dc', 'mail', 'uid',
+ 'postaladdress', 'postalcode', 'postofficebox', 'houseidentifier', 'e',
+ 'street', 'pseudonym', 'incorporationlocality', 'incorporationstate',
+ 'incorporationcountry', 'businesscategory',
+}
+VALID_SUBJECT_ATTRS = {'cn'} | VALID_SUBJECT_BASE_ATTRS
external_cert_file = None
external_ca_file = None
+def subject_validator(valid_attrs, value):
+ v = unicode(value, 'utf-8')
+ if any(ord(c) < 0x20 for c in v):
+ raise ValueError("must not contain control characters")
+ if '&' in v:
+ raise ValueError("must not contain an ampersand (\"&\")")
+ try:
+ dn = DN(v)
+ for rdn in dn:
+ if rdn.attr.lower() not in valid_attrs:
+ raise ValueError("invalid attribute: \"%s\"" % rdn.attr)
+ except ValueError as e:
+ raise ValueError("invalid DN: %s" % e)
+
+
+def lookup_ca_subject(api, subject_base):
+ dn = DN(('cn', IPA_CA_CN), api.env.container_ca, api.env.basedn)
+ try:
+ # we do not use api.Command.ca_show because it attempts to
+ # talk to the CA (to read certificate / chain), but the RA
+ # backend may be unavailable (ipa-replica-install) or unusable
+ # due to RA Agent cert not yet created (ipa-ca-install).
+ ca_subject = api.Backend.ldap2.get_entry(dn)['ipacasubjectdn'][0]
+ except errors.NotFound:
+ # if the entry doesn't exist, we are dealing with a pre-v4.4
+ # installation, where the default CA subject was always based
+ # on the subject_base.
+ #
+ # installutils.default_ca_subject_dn is NOT used here in
+ # case the default changes in the future.
+ ca_subject = DN(('CN', 'Certificate Authority'), subject_base)
+ return six.text_type(ca_subject)
+
+
def set_subject_base_in_config(subject_base):
entry_attrs = api.Backend.ldap2.get_ipa_config()
entry_attrs['ipacertificatesubjectbase'] = [str(subject_base)]
@@ -62,12 +98,23 @@ def install_check(standalone, replica_config, options):
global external_cert_file
global external_ca_file
- if replica_config is not None and not replica_config.setup_ca:
- return
-
realm_name = options.realm_name
host_name = options.host_name
- subject_base = options.subject_base
+
+ if replica_config is None:
+ options._subject_base = options.subject_base
+ options._ca_subject = options.ca_subject
+ else:
+ # during replica install, this gets invoked before local DS is
+ # available, so use the remote api.
+ _api = api if standalone else options._remote_api
+
+ # for replica-install the knobs cannot be written, hence leading '_'
+ options._subject_base = six.text_type(replica_config.subject_base)
+ options._ca_subject = lookup_ca_subject(_api, options._subject_base)
+
+ if replica_config is not None and not replica_config.setup_ca:
+ return
if replica_config is not None:
if standalone and api.env.ra_plugin == 'selfsign':
@@ -110,9 +157,7 @@ def install_check(standalone, replica_config, options):
"--external-ca.")
external_cert_file, external_ca_file = installutils.load_external_cert(
- options.external_cert_files,
- DN(('CN', 'Certificate Authority'), options.subject_base)
- )
+ options.external_cert_files, options._ca_subject)
elif options.external_ca:
if cainstance.is_step_one_done():
raise ScriptError(
@@ -132,8 +177,9 @@ def install_check(standalone, replica_config, options):
if standalone:
dirname = dsinstance.config_dirname(
installutils.realm_to_serverid(realm_name))
- cadb = certs.CertDB(realm_name, subject_base=subject_base)
- dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base)
+ cadb = certs.CertDB(realm_name, subject_base=options._subject_base)
+ dsdb = certs.CertDB(
+ realm_name, nssdir=dirname, subject_base=options._subject_base)
for db in (cadb, dsdb):
for nickname, _trust_flags in db.list_certs():
@@ -147,8 +193,8 @@ def install_check(standalone, replica_config, options):
if not cert:
continue
subject = DN(x509.load_certificate(cert).subject)
- if subject in (DN('CN=Certificate Authority', subject_base),
- DN('CN=IPA RA', subject_base)):
+ if subject in (DN(options._ca_subject),
+ DN('CN=IPA RA', options._subject_base)):
raise ScriptError(
"Certificate with subject %s is present in %s, "
"cannot continue." % (subject, db.secdir))
@@ -163,10 +209,10 @@ def install_step_0(standalone, replica_config, options):
realm_name = options.realm_name
dm_password = options.dm_password
host_name = options.host_name
+ ca_subject = options._ca_subject
+ subject_base = options._subject_base
if replica_config is None:
- subject_base = options.subject_base
-
ca_signing_algorithm = options.ca_signing_algorithm
if options.external_ca:
ca_type = options.external_ca_type
@@ -198,8 +244,6 @@ def install_step_0(standalone, replica_config, options):
cafile,
replica_config.dirman_password)
- subject_base = replica_config.subject_base
-
ca_signing_algorithm = None
ca_type = None
csr_file = None
@@ -214,16 +258,18 @@ def install_step_0(standalone, replica_config, options):
promote = options.promote
# if upgrading from CA-less to CA-ful, need to rewrite
- # subject_base configuration
+ # certmap.conf and subject_base configuration
#
set_subject_base_in_config(subject_base)
sysupgrade.set_upgrade_state(
'certmap.conf', 'subject_base', str(subject_base))
+ dsinstance.write_certmap_conf(realm_name, ca_subject)
ca = cainstance.CAInstance(realm_name, certs.NSS_DIR,
host_name=host_name)
ca.configure_instance(host_name, dm_password, dm_password,
subject_base=subject_base,
+ ca_subject=ca_subject,
ca_signing_algorithm=ca_signing_algorithm,
ca_type=ca_type,
csr_file=csr_file,
@@ -244,8 +290,7 @@ def install_step_1(standalone, replica_config, options):
realm_name = options.realm_name
host_name = options.host_name
- subject_base = options.subject_base
-
+ subject_base = options._subject_base
basedn = ipautil.realm_to_suffix(realm_name)
ca = cainstance.CAInstance(realm_name, certs.NSS_DIR, host_name=host_name)
@@ -396,18 +441,20 @@ class CAInstallInterface(dogtag.DogtagInstallInterface,
@subject_base.validator
def subject_base(self, value):
- v = unicode(value, 'utf-8')
- if any(ord(c) < 0x20 for c in v):
- raise ValueError("must not contain control characters")
- if '&' in v:
- raise ValueError("must not contain an ampersand (\"&\")")
- try:
- dn = DN(v)
- for rdn in dn:
- if rdn.attr.lower() not in VALID_SUBJECT_ATTRS:
- raise ValueError("invalid attribute: \"%s\"" % rdn.attr)
- except ValueError as e:
- raise ValueError("invalid subject base format: %s" % e)
+ subject_validator(VALID_SUBJECT_BASE_ATTRS, value)
+
+ ca_subject = knob(
+ str, None,
+ description=(
+ "The CA certificate subject DN "
+ "(default CN=Certificate Authority,O=<realm-name>)"
+ ),
+ )
+ ca_subject = master_install_only(ca_subject)
+
+ @ca_subject.validator
+ def ca_subject(self, value):
+ subject_validator(VALID_SUBJECT_ATTRS, value)
ca_signing_algorithm = knob(
CASigningAlgorithm, None,
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 4f01f83e4..f933479df 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -330,7 +330,8 @@ class CAInstance(DogtagInstance):
pkcs12_info=None, master_host=None, csr_file=None,
cert_file=None, cert_chain_file=None,
master_replication_port=None,
- subject_base=None, ca_signing_algorithm=None,
+ subject_base=None, ca_subject=None,
+ ca_signing_algorithm=None,
ca_type=None, ra_p12=None, ra_only=False,
promote=False, use_ldaps=False):
"""Create a CA instance.
@@ -355,6 +356,8 @@ class CAInstance(DogtagInstance):
self.subject_base = \
subject_base or installutils.default_subject_base(self.realm)
+ self.ca_subject = \
+ ca_subject or installutils.default_ca_subject_dn(self.subject_base)
if ca_signing_algorithm is None:
self.ca_signing_algorithm = 'SHA256withRSA'
@@ -514,8 +517,9 @@ class CAInstance(DogtagInstance):
str(DN(('cn', self.fqdn), self.subject_base)))
config.set("CA", "pki_audit_signing_subject_dn",
str(DN(('cn', 'CA Audit'), self.subject_base)))
- config.set("CA", "pki_ca_signing_subject_dn",
- str(DN(('cn', 'Certificate Authority'), self.subject_base)))
+ config.set(
+ "CA", "pki_ca_signing_subject_dn",
+ str(self.ca_subject))
# Certificate nicknames
config.set("CA", "pki_subsystem_nickname", "subsystemCert cert-pki-ca")
@@ -701,7 +705,7 @@ class CAInstance(DogtagInstance):
userCertificate=[cert_data],
description=['2;%s;%s;%s' % (
cert.serial,
- DN(('CN', 'Certificate Authority'), self.subject_base),
+ DN(self.ca_subject),
DN(('CN', 'IPA RA'), self.subject_base))])
conn.add_entry(entry)
@@ -754,7 +758,7 @@ class CAInstance(DogtagInstance):
# Ok, now we have all the certificates in certs, walk through it
# and pull out each certificate and add it to our database
- ca_dn = DN(('CN','Certificate Authority'), self.subject_base)
+ ca_dn = DN(self.ca_subject)
for cert in certlist:
try:
chain_fd, chain_name = tempfile.mkstemp()
diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
index 85c2d06c0..80918d431 100644
--- a/ipaserver/install/certs.py
+++ b/ipaserver/install/certs.py
@@ -70,9 +70,19 @@ class CertDB(object):
This class knows IPA-specific details such as nssdir location, or the
CA cert name.
+
+ ``subject_base``
+ Realm subject base DN. This argument is required when creating
+ server or object signing certs.
+ ``ca_subject``
+ IPA CA subject DN. This argument is required when importing
+ CA certificates into the certificate database.
+
"""
# TODO: Remove all selfsign code
- def __init__(self, realm, nssdir=NSS_DIR, fstore=None, host_name=None, subject_base=None):
+ def __init__(
+ self, realm, nssdir=NSS_DIR, fstore=None, host_name=None,
+ subject_base=None, ca_subject=None):
self.nssdb = NSSDatabase(nssdir)
self.secdir = nssdir
@@ -91,15 +101,13 @@ class CertDB(object):
self.certreq_fname = None
self.certder_fname = None
self.host_name = host_name
+ self.ca_subject = ca_subject
self.subject_base = subject_base
try:
self.cwd = os.getcwd()
except OSError as e:
raise RuntimeError("Unable to determine the current directory: %s" % str(e))
- if not subject_base:
- self.subject_base = DN(('O', 'IPA'))
-
self.cacert_name = get_ca_nickname(self.realm)
self.valid_months = "120"
self.keysize = "1024"
@@ -118,6 +126,7 @@ class CertDB(object):
else:
self.fstore = sysrestore.FileStore(paths.SYSRESTORE)
+ ca_subject = ipautil.dn_attribute_property('_ca_subject')
subject_base = ipautil.dn_attribute_property('_subject_base')
def __del__(self):
@@ -248,13 +257,12 @@ class CertDB(object):
certs = fd.read()
fd.close()
- ca_dn = DN(('CN','Certificate Authority'), self.subject_base)
st = 0
while True:
try:
(cert, st) = find_cert_from_txt(certs, st)
_rdn, subject_dn = get_cert_nickname(cert)
- if subject_dn == ca_dn:
+ if subject_dn == self.ca_subject:
nick = get_ca_nickname(self.realm)
else:
nick = str(subject_dn)
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index d23a2aa6f..6e7019a08 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -241,6 +241,7 @@ class DsInstance(service.Service):
self.dercert = None
self.idstart = None
self.idmax = None
+ self.ca_subject = None
self.subject_base = None
self.open_ports = []
self.run_init_memberof = True
@@ -301,7 +302,8 @@ class DsInstance(service.Service):
self.step("configuring directory to start on boot", self.__enable)
def init_info(self, realm_name, fqdn, domain_name, dm_password,
- subject_base, idstart, idmax, pkcs12_info, ca_file=None):
+ subject_base, ca_subject,
+ idstart, idmax, pkcs12_info, ca_file=None):
self.realm = realm_name.upper()
self.serverid = installutils.realm_to_serverid(self.realm)
self.suffix = ipautil.realm_to_suffix(self.realm)
@@ -309,6 +311,7 @@ class DsInstance(service.Service):
self.dm_password = dm_password
self.domain = domain_name
self.subject_base = subject_base
+ self.ca_subject = ca_subject
self.idstart = idstart
self.idmax = idmax
self.pkcs12_info = pkcs12_info
@@ -320,11 +323,13 @@ class DsInstance(service.Service):
def create_instance(self, realm_name, fqdn, domain_name,
dm_password, pkcs12_info=None,
- idstart=1100, idmax=999999, subject_base=None,
+ idstart=1100, idmax=999999,
+ subject_base=None, ca_subject=None,
hbac_allow=True, ca_file=None):
self.init_info(
realm_name, fqdn, domain_name, dm_password,
- subject_base, idstart, idmax, pkcs12_info, ca_file=ca_file)
+ subject_base, ca_subject,
+ idstart, idmax, pkcs12_info, ca_file=ca_file)
self.__common_setup()
self.step("restarting directory server", self.__restart_instance)
@@ -358,8 +363,9 @@ class DsInstance(service.Service):
self.start_creation(runtime=10)
def create_replica(self, realm_name, master_fqdn, fqdn,
- domain_name, dm_password, subject_base, api,
- pkcs12_info=None, ca_file=None,
+ domain_name, dm_password,
+ subject_base, ca_subject,
+ api, pkcs12_info=None, ca_file=None,
ca_is_configured=None, promote=False):
# idstart and idmax are configured so that the range is seen as
# depleted by the DNA plugin and the replica will go and get a
@@ -374,6 +380,7 @@ class DsInstance(service.Service):
domain_name=domain_name,
dm_password=dm_password,
subject_base=subject_base,
+ ca_subject=ca_subject,
idstart=idstart,
idmax=idmax,
pkcs12_info=pkcs12_info,
@@ -777,7 +784,12 @@ class DsInstance(service.Service):
def __enable_ssl(self):
dirname = config_dirname(self.serverid)
- dsdb = certs.CertDB(self.realm, nssdir=dirname, subject_base=self.subject_base)
+ dsdb = certs.CertDB(
+ self.realm,
+ nssdir=dirname,
+ subject_base=self.subject_base,
+ ca_subject=self.ca_subject,
+ )
if self.pkcs12_info:
if self.ca_is_configured:
trust_flags = 'CT,C,C'
@@ -920,8 +932,7 @@ class DsInstance(service.Service):
self._ldap_mod("indices.ldif")
def __certmap_conf(self):
- ca_subject = 'CN=Certificate Authority,' + str(self.subject_base)
- write_certmap_conf(self.realm, ca_subject)
+ write_certmap_conf(self.realm, self.ca_subject)
sysupgrade.set_upgrade_state(
'certmap.conf',
'subject_base',
@@ -1064,7 +1075,12 @@ class DsInstance(service.Service):
self.stop()
dirname = config_dirname(installutils.realm_to_serverid(self.realm))
- certdb = certs.CertDB(self.realm, nssdir=dirname, subject_base=self.subject_base)
+ certdb = certs.CertDB(
+ self.realm,
+ nssdir=dirname,
+ subject_base=self.subject_base,
+ ca_subject=self.ca_subject,
+ )
if not cacert_name or len(cacert_name) == 0:
cacert_name = "Imported CA"
# we can't pass in the nickname, so we set the instance variable
@@ -1163,8 +1179,7 @@ class DsInstance(service.Service):
Try to find the current value of certificate subject base.
1) Look in sysupgrade first
2) If no value is found there, look in DS (start DS if necessary)
- 3) Last resort, look in the certmap.conf itself
- 4) If all fails, log loudly and return None
+ 3) If all fails, log loudly and return None
Note that this method can only be executed AFTER the ipa server
is configured, the api is initialized elsewhere and
@@ -1206,27 +1221,6 @@ class DsInstance(service.Service):
root_logger.error('Cannot connect to DS to find certificate '
'subject base: %s', e)
- if not subject_base:
- root_logger.debug('Unable to find certificate subject base in DS')
- root_logger.debug('Trying to find certificate subject base in '
- 'certmap.conf')
-
- certmap_dir = config_dirname(
- installutils.realm_to_serverid(api.env.realm)
- )
- try:
- with open(os.path.join(certmap_dir, 'certmap.conf')) as f:
- for line in f:
- if line.startswith('certmap ipaca'):
- subject_base = line.strip().split(',')[-1]
- root_logger.debug(
- 'Found certificate subject base in certmap.conf: '
- '%s', subject_base)
-
- except IOError as e:
- root_logger.error('Cannot open certmap.conf to find certificate '
- 'subject base: %s', e.strerror)
-
if subject_base:
return subject_base
@@ -1248,10 +1242,13 @@ class DsInstance(service.Service):
replacevars=vardict)
def __get_ds_cert(self):
- subject = self.subject_base \
- or installutils.default_subject_base(self.realm)
nssdb_dir = config_dirname(self.serverid)
- db = certs.CertDB(self.realm, nssdir=nssdb_dir, subject_base=subject)
+ db = certs.CertDB(
+ self.realm,
+ nssdir=nssdb_dir,
+ subject_base=self.subject_base,
+ ca_subject=self.ca_subject,
+ )
db.create_from_cacert(paths.IPA_CA_CRT)
db.request_service_cert(self.nickname, self.principal, self.fqdn)
db.create_pin_file()
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index ca7a5d6ac..0d8a574ae 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -1480,3 +1480,7 @@ def restart_dirsrv(instance_name="", capture_output=True):
def default_subject_base(realm_name):
return DN(('O', realm_name))
+
+
+def default_ca_subject_dn(subject_base):
+ return DN(('CN', 'Certificate Authority'), subject_base)
diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
index 4082dfa4e..1d1ae2f21 100644
--- a/ipaserver/install/ipa_cacert_manage.py
+++ b/ipaserver/install/ipa_cacert_manage.py
@@ -201,9 +201,7 @@ class CACertManage(admintool.AdminTool):
)
cert_file, ca_file = installutils.load_external_cert(
- options.external_cert_files,
- DN(('CN', 'Certificate Authority'), x509.subject_base())
- )
+ options.external_cert_files, DN(old_cert_obj.subject))
with open(cert_file.name) as f:
new_cert_data = f.read()
diff --git a/ipaserver/install/krainstance.py b/ipaserver/install/krainstance.py
index 1d9c2b773..1f38c8636 100644
--- a/ipaserver/install/krainstance.py
+++ b/ipaserver/install/krainstance.py
@@ -77,7 +77,8 @@ class KRAInstance(DogtagInstance):
def configure_instance(self, realm_name, host_name, dm_password,
admin_password, pkcs12_info=None, master_host=None,
- subject_base=None, ra_only=False, promote=False):
+ subject_base=None, subject=None,
+ ra_only=False, promote=False):
"""Create a KRA instance.
To create a clone, pass in pkcs12_info.
@@ -93,6 +94,8 @@ class KRAInstance(DogtagInstance):
self.subject_base = \
subject_base or installutils.default_subject_base(realm_name)
+ self.subject = \
+ subject or installutils.default_ca_subject_dn(self.subject_base)
self.realm = realm_name
self.suffix = ipautil.realm_to_suffix(realm_name)
@@ -307,7 +310,7 @@ class KRAInstance(DogtagInstance):
userCertificate=[cert_data],
description=['2;%s;%s;%s' % (
cert.serial,
- DN(('CN', 'Certificate Authority'), self.subject_base),
+ DN(self.subject),
DN(('CN', 'IPA RA'), self.subject_base))])
conn.add_entry(entry)
diff --git a/ipaserver/install/server/__init__.py b/ipaserver/install/server/__init__.py
index 28cdd066a..86cb4a9ef 100644
--- a/ipaserver/install/server/__init__.py
+++ b/ipaserver/install/server/__init__.py
@@ -573,7 +573,8 @@ class ServerReplicaInstall(ServerReplicaInstallInterface):
Server replica installer
"""
- subject = None
+ subject_base = None
+ ca_subject = None
admin_password = knob(
bases=ServerReplicaInstallInterface.admin_password,
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index aae8d367a..db765d60b 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -467,6 +467,10 @@ def install_check(installer):
if not options.subject_base:
options.subject_base = installutils.default_subject_base(realm_name)
+ if not options.ca_subject:
+ options.ca_subject = \
+ installutils.default_ca_subject_dn(options.subject_base)
+
if options.http_cert_files:
if options.http_pin is None:
options.http_pin = installutils.read_password(
@@ -726,6 +730,7 @@ def install(installer):
dm_password, dirsrv_pkcs12_info,
idstart=options.idstart, idmax=options.idmax,
subject_base=options.subject_base,
+ ca_subject=options.ca_subject,
hbac_allow=not options.no_hbac_allow)
else:
ds = dsinstance.DsInstance(fstore=fstore,
@@ -736,6 +741,7 @@ def install(installer):
dm_password,
idstart=options.idstart, idmax=options.idmax,
subject_base=options.subject_base,
+ ca_subject=options.ca_subject,
hbac_allow=not options.no_hbac_allow)
ntpinstance.ntp_ldap_enable(host_name, ds.suffix, realm_name)
@@ -747,7 +753,7 @@ def install(installer):
installer._ds = ds
ds.init_info(
realm_name, host_name, domain_name, dm_password,
- options.subject_base, 1101, 1100, None)
+ options.subject_base, options.ca_subject, 1101, 1100, None)
if setup_ca:
if not options.external_cert_files and options.external_ca:
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index 16352a5c8..18222c80e 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -78,8 +78,7 @@ def install_http_certs(host_name, realm_name, subject_base):
principal = 'HTTP/%s@%s' % (host_name, realm_name)
# Obtain certificate for the HTTP service
nssdir = certs.NSS_DIR
- subject = subject_base or installutils.default_subject_base(realm_name)
- db = certs.CertDB(realm_name, nssdir=nssdir, subject_base=subject)
+ db = certs.CertDB(realm_name, nssdir=nssdir, subject_base=subject_base)
db.request_service_cert('Server-Cert', principal, host_name, True)
@@ -94,6 +93,11 @@ def install_replica_ds(config, options, ca_is_configured, remote_api,
pkcs12_info = make_pkcs12_info(config.dir, "dscert.p12",
"dirsrv_pin.txt")
+ if ca_is_configured:
+ ca_subject = ca.lookup_ca_subject(remote_api, config.subject_base)
+ else:
+ ca_subject = installutils.default_ca_subject_dn(config.subject_base)
+
ds = dsinstance.DsInstance(
config_ldif=options.dirsrv_config_file)
ds.create_replica(
@@ -103,6 +107,7 @@ def install_replica_ds(config, options, ca_is_configured, remote_api,
domain_name=config.domain_name,
dm_password=config.dirman_password,
subject_base=config.subject_base,
+ ca_subject=ca_subject,
pkcs12_info=pkcs12_info,
ca_is_configured=ca_is_configured,
ca_file=ca_file,
@@ -703,6 +708,10 @@ def install_check(installer):
raise RuntimeError("CA cert file is not available. Please run "
"ipa-replica-prepare to create a new replica file.")
+ # look up CA subject name (needed for DS certmap.conf)
+ options.ca_subject = unicode(
+ DN(x509.load_certificate_from_file(cafile).subject))
+
for pkcs12_name, pin_name in (('dscert.p12', 'dirsrv_pin.txt'),
('httpcert.p12', 'http_pin.txt')):
pkcs12_info = make_pkcs12_info(config.dir, pkcs12_name, pin_name)
@@ -737,6 +746,7 @@ def install_check(installer):
confdir=paths.ETC_IPA,
ldap_uri=ldapuri)
remote_api.finalize()
+ installer._remote_api = remote_api
conn = remote_api.Backend.ldap2
replman = None
try:
@@ -796,7 +806,6 @@ def install_check(installer):
if ca_enabled:
options.realm_name = config.realm_name
options.host_name = config.host_name
- options.subject_base = config.subject_base
ca.install_check(False, config, options)
if kra_enabled:
@@ -855,7 +864,6 @@ def install_check(installer):
installer._ca_enabled = ca_enabled
installer._kra_enabled = kra_enabled
installer._ca_file = cafile
- installer._remote_api = remote_api
installer._fstore = fstore
installer._sstore = sstore
@@ -1067,6 +1075,7 @@ def promote_check(installer):
ldap_uri=ldapuri,
xmlrpc_uri=xmlrpc_uri)
remote_api.finalize()
+ installer._remote_api = remote_api
check_remote_version(remote_api)
@@ -1203,7 +1212,6 @@ def promote_check(installer):
if ca_enabled:
options.realm_name = config.realm_name
options.host_name = config.host_name
- options.subject_base = config.subject_base
ca.install_check(False, config, options)
if kra_enabled:
@@ -1263,7 +1271,6 @@ def promote_check(installer):
installer._fstore = fstore
installer._sstore = sstore
installer._config = config
- installer._remote_api = remote_api
installer._add_to_ipaservers = add_to_ipaservers
installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file
installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info