Allow full customisability of IPA CA subject DN

Currently only the "subject base" of the IPA CA subject DN can be
customised, via the installer's --subject-base option.  The RDN
"CN=Certificate Authority" is appended to form the subject DN, and
this composition is widely assumed.

Some administrators need more control over the CA subject DN,
especially to satisfy expectations of external CAs when the IPA CA
is to be externally signed.

This patch adds full customisability of the CA subject DN.
Specifically:

- Add the --ca-subject option for specifying the full IPA CA subject
  DN.  Defaults to "CN=Certificate Authority, O=$SUBJECT_BASE".

- ipa-ca-install, when installing a CA in a previous CA-less
  topology, updates DS certmap.conf with the new new CA subject DN.

- DsInstance.find_subject_base no longer looks in certmap.conf,
  because the CA subject DN can be unrelated to the subject base.

Fixes: https://fedorahosted.org/freeipa/ticket/2614
Reviewed-By: Jan Cholasta <jcholast@redhat.com>
This commit is contained in:
Fraser Tweedale 2016-11-16 20:49:36 +10:00 committed by Jan Cholasta
parent 09a65df684
commit 3d01ec14c6
13 changed files with 198 additions and 98 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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)

View File

@ -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,

View File

@ -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:

View File

@ -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