Hi *

attached you find a patch that adds new options --subject_cn and
--subject_mail to ipa-server-install that make the CA cert subject CN
customizable.

This patch has been tested by a customer in a PoC.
However, i assume additional testing in different environments is required.

It would be greatly appreciated if this patch would find its way into
the product very soon.

Beste Grüße / Best regards
  Sebastian Hetze
-- 
Senior Solution Architect
Red Hat GmbH. Niederlassung Berlin
Am Treptower Park 75 12435 Berlin
Tel: +49 30 678 1798-241 . Mobil: +49 173 8914205
Fax: +49 30 678 1798-111 . E-Mail: s...@redhat.com

diff -Nur freeipa-4.2.0-15.el7.17/install/share/60ipaconfig.ldif freeipa-4.2.0/install/share/60ipaconfig.ldif
--- freeipa-4.2.0-15.el7.17/install/share/60ipaconfig.ldif	2015-06-18 14:54:49.000000000 +0200
+++ freeipa-4.2.0/install/share/60ipaconfig.ldif	2016-07-05 17:06:49.433028447 +0200
@@ -43,11 +43,12 @@
 attributeTypes: (2.16.840.1.113730.3.8.3.16 NAME 'ipaConfigString' DESC 'Generic configuration stirng' EQUALITY caseIgnoreMatch ORDERING caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA v2' )
 attributeTypes: ( 2.16.840.1.113730.3.8.3.26 NAME 'ipaSELinuxUserMapDefault' DESC 'Default SELinux user' EQUALITY caseIgnoreMatch ORDERING caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v3')
 attributeTypes: ( 2.16.840.1.113730.3.8.3.27 NAME 'ipaSELinuxUserMapOrder' DESC 'Available SELinux user context ordering' EQUALITY caseIgnoreMatch ORDERING caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v3')
+attributeTypes: ( 2.16.840.1.113730.3.8.3.28 NAME 'ipaCertificateSubjectRdn' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
 ###############################################
 ##
 ## ObjectClasses
 ##
 ## ipaGuiConfig - GUI config parameters objectclass
-objectClasses: ( 2.16.840.1.113730.3.8.2.1 NAME 'ipaGuiConfig' AUXILIARY MAY ( ipaUserSearchFields $ ipaGroupSearchFields $ ipaSearchTimeLimit $ ipaSearchRecordsLimit $ ipaCustomFields $ ipaHomesRootDir $ ipaDefaultLoginShell $ ipaDefaultPrimaryGroup $ ipaMaxUsernameLength $ ipaPwdExpAdvNotify $ ipaUserObjectClasses $ ipaGroupObjectClasses $ ipaDefaultEmailDomain $ ipaMigrationEnabled $ ipaCertificateSubjectBase $ ipaSELinuxUserMapDefault $ ipaSELinuxUserMapOrder $ ipaKrbAuthzData ) )
+objectClasses: ( 2.16.840.1.113730.3.8.2.1 NAME 'ipaGuiConfig' AUXILIARY MAY ( ipaUserSearchFields $ ipaGroupSearchFields $ ipaSearchTimeLimit $ ipaSearchRecordsLimit $ ipaCustomFields $ ipaHomesRootDir $ ipaDefaultLoginShell $ ipaDefaultPrimaryGroup $ ipaMaxUsernameLength $ ipaPwdExpAdvNotify $ ipaUserObjectClasses $ ipaGroupObjectClasses $ ipaDefaultEmailDomain $ ipaMigrationEnabled $ ipaCertificateSubjectBase $ ipaSELinuxUserMapDefault $ ipaSELinuxUserMapOrder $ ipaKrbAuthzData $ ipaCertificateSubjectRdn ) )
 ## ipaConfigObject - Generic config strings object holder
 objectClasses: (2.16.840.1.113730.3.8.4.13 NAME 'ipaConfigObject' DESC 'generic config object for IPA' AUXILIARY MAY ( ipaConfigString ) X-ORIGIN 'IPA v2' )
diff -Nur freeipa-4.2.0-15.el7.17/install/share/certmap.conf.template freeipa-4.2.0/install/share/certmap.conf.template
--- freeipa-4.2.0-15.el7.17/install/share/certmap.conf.template	2015-06-18 14:54:49.000000000 +0200
+++ freeipa-4.2.0/install/share/certmap.conf.template	2016-07-05 17:06:49.433028447 +0200
@@ -41,6 +41,6 @@
 #default:InitFn         <Init function's name>
 default:DNComps
 default:FilterComps     uid
-certmap ipaca           CN=Certificate Authority,$SUBJECT_BASE
+certmap ipaca           $SUBJECT_RDN,$SUBJECT_BASE
 ipaca:CmapLdapAttr      seeAlso
 ipaca:verifycert        on
diff -Nur freeipa-4.2.0-15.el7.17/ipaserver/install/cainstance.py freeipa-4.2.0/ipaserver/install/cainstance.py
--- freeipa-4.2.0-15.el7.17/ipaserver/install/cainstance.py	2016-05-24 19:37:31.000000000 +0200
+++ freeipa-4.2.0/ipaserver/install/cainstance.py	2016-07-05 17:06:49.433028447 +0200
@@ -391,7 +391,8 @@
                            cert_file=None, cert_chain_file=None,
                            master_replication_port=None,
                            subject_base=None, ca_signing_algorithm=None,
-                           ca_type=None, ra_p12=None):
+                           ca_type=None, ra_p12=None,
+                           subject_rdn=None):
         """Create a CA instance.
 
            For Dogtag 9, this may involve creating the pki-ca instance.
@@ -416,7 +417,11 @@
         if subject_base is None:
             self.subject_base = DN(('O', self.realm))
         else:
-            self.subject_base = subject_base
+            self.subject_base = DN(subject_base)
+        if subject_rdn is None:
+            self.subject_rdn = DN(('CN', 'Certificate Authority'))
+        else:
+            self.subject_rdn = subject_rdn
         if ca_signing_algorithm is None:
             self.ca_signing_algorithm = 'SHA256withRSA'
         else:
@@ -545,7 +550,7 @@
         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)))
+            str(DN(self.subject_rdn, self.subject_base)))
 
         # Certificate nicknames
         config.set("CA", "pki_subsystem_nickname", "subsystemCert cert-pki-ca")
@@ -701,7 +706,7 @@
                     "-ca_ocsp_cert_subject_name", str(DN(('CN', 'OCSP Subsystem'), self.subject_base)),
                     "-ca_server_cert_subject_name", str(DN(('CN', self.fqdn), self.subject_base)),
                     "-ca_audit_signing_cert_subject_name", str(DN(('CN', 'CA Audit'), self.subject_base)),
-                    "-ca_sign_cert_subject_name", str(DN(('CN', 'Certificate Authority'), self.subject_base)) ]
+                    "-ca_sign_cert_subject_name", str(DN(self.subject_rdn, self.subject_base)) ]
             if self.external == 1:
                 args.append("-external")
                 args.append("true")
@@ -946,7 +951,7 @@
             userCertificate=[cert_data],
             description=['2;%s;%s;%s' % (
                 cert.serial_number,
-                DN(('CN', 'Certificate Authority'), self.subject_base),
+                DN(self.subject_rdn, self.subject_base),
                 DN(('CN', 'IPA RA'), self.subject_base))])
         conn.add_entry(entry)
 
@@ -1039,7 +1044,7 @@
         st = 1
         en = 0
         subid = 0
-        ca_dn = DN(('CN','Certificate Authority'), self.subject_base)
+        ca_dn = DN(self.subject_rdn, self.subject_base)
         while st > 0:
             st = certlist.find('-----BEGIN', en)
             en = certlist.find('-----END', en+1)
diff -Nur freeipa-4.2.0-15.el7.17/ipaserver/install/ca.py freeipa-4.2.0/ipaserver/install/ca.py
--- freeipa-4.2.0-15.el7.17/ipaserver/install/ca.py	2016-05-24 19:37:31.000000000 +0200
+++ freeipa-4.2.0/ipaserver/install/ca.py	2016-07-05 17:06:49.433028447 +0200
@@ -23,6 +23,7 @@
     realm_name = options.realm_name
     host_name = options.host_name
     subject_base = options.subject
+    subject_rdn = options.subject_rdn
 
     if replica_config is not None:
         if standalone and api.env.ra_plugin == 'selfsign':
@@ -66,7 +67,7 @@
             sys.exit(1)
 
         external_cert_file, external_ca_file = installutils.load_external_cert(
-            options.external_cert_files, options.subject)
+            options.external_cert_files, options.subject, options.subject_rdn)
     elif options.external_ca:
         if cainstance.is_step_one_done():
             print("CA is already installed.\nRun the installer with "
@@ -87,7 +88,8 @@
         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)
+        dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base,
+                            subject_rdn=subject_rdn)
 
         for db in (cadb, dsdb):
             for nickname, trust_flags in db.list_certs():
@@ -102,7 +104,7 @@
                 if not cert:
                     continue
                 subject = DN(str(x509.get_subject(cert)))
-                if subject in (DN('CN=Certificate Authority', subject_base),
+                if subject in (DN(subject_rdn, subject_base),
                                DN('CN=IPA RA', subject_base),
                                DN('CN=Object Signing Cert', subject_base)):
                     print ("Certificate with subject %s is present in %s, "
@@ -121,6 +123,7 @@
     dm_password = options.dm_password
     host_name = options.host_name
     subject_base = options.subject
+    subject_rdn = options.subject_rdn
 
     dogtag_constants = dogtag.install_constants
 
@@ -161,7 +164,7 @@
     elif external == 1:
         ca.configure_instance(host_name, domain_name, dm_password,
                               dm_password, csr_file=paths.ROOT_IPA_CSR,
-                              subject_base=subject_base,
+                              subject_base=subject_base, subject_rdn=subject_rdn,
                               ca_signing_algorithm=options.ca_signing_algorithm,
                               ca_type=options.external_ca_type)
     else:
@@ -169,7 +172,7 @@
                               dm_password,
                               cert_file=external_cert_file.name,
                               cert_chain_file=external_ca_file.name,
-                              subject_base=subject_base,
+                              subject_base=subject_base, subject_rdn=subject_rdn,
                               ca_signing_algorithm=options.ca_signing_algorithm)
 
 
@@ -179,6 +182,7 @@
     dm_password = options.dm_password
     host_name = options.host_name
     subject_base = options.subject
+    subject_rdn = options.subject_rdn
 
     basedn = ipautil.realm_to_suffix(realm_name)
 
@@ -206,7 +210,8 @@
 
         # Store the new IPA CA cert chain in DS NSS database and LDAP
         cadb = certs.CertDB(realm_name, subject_base=subject_base)
-        dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base)
+        dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base,
+                            subject_rdn=subject_rdn)
         trust_flags = dict(reversed(cadb.list_certs()))
         trust_chain = cadb.find_root_cert('ipaCert')[:-1]
         for nickname in trust_chain[:-1]:
diff -Nur freeipa-4.2.0-15.el7.17/ipaserver/install/certs.py freeipa-4.2.0/ipaserver/install/certs.py
--- freeipa-4.2.0-15.el7.17/ipaserver/install/certs.py	2016-05-24 19:37:31.000000000 +0200
+++ freeipa-4.2.0/ipaserver/install/certs.py	2016-07-05 17:06:49.433028447 +0200
@@ -73,7 +73,8 @@
     CA cert name.
     """
     # 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,
+                       subject_rdn=None):
         self.nssdb = NSSDatabase(nssdir)
 
         self.secdir = nssdir
@@ -93,6 +94,7 @@
         self.certder_fname = None
         self.host_name = host_name
         self.subject_base = subject_base
+        self.subject_rdn = subject_rdn
         try:
             self.cwd = os.getcwd()
         except OSError, e:
@@ -101,6 +103,9 @@
         if not subject_base:
             self.subject_base = DN(('O', 'IPA'))
 
+        if not subject_rdn:
+            self.subject_rdn = DN(('CN', 'Certificate Authority'))
+
         self.cacert_name = get_ca_nickname(self.realm)
         self.valid_months = "120"
         self.keysize = "1024"
@@ -251,12 +256,13 @@
         certs = fd.read()
         fd.close()
 
-        ca_dn = DN(('CN','Certificate Authority'), self.subject_base)
+        ca_dn = DN(self.subject_rdn, self.subject_base)
         st = 0
         while True:
             try:
                 (cert, st) = find_cert_from_txt(certs, st)
                 (rdn, subject_dn) = get_cert_nickname(cert)
+                root_logger.debug('load_cacert S:%s C:%s', subject_dn, ca_dn )
                 if subject_dn == ca_dn:
                     nick = get_ca_nickname(self.realm)
                 else:
diff -Nur freeipa-4.2.0-15.el7.17/ipaserver/install/dsinstance.py freeipa-4.2.0/ipaserver/install/dsinstance.py
--- freeipa-4.2.0-15.el7.17/ipaserver/install/dsinstance.py	2016-05-24 19:37:31.000000000 +0200
+++ freeipa-4.2.0/ipaserver/install/dsinstance.py	2016-07-07 06:20:31.202550084 +0200
@@ -272,7 +272,7 @@
         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, idstart, idmax, pkcs12_info, ca_file=None, subject_rdn=None):
         self.realm = realm_name.upper()
         self.serverid = installutils.realm_to_serverid(self.realm)
         self.suffix = ipautil.realm_to_suffix(self.realm)
@@ -281,6 +281,7 @@
         self.domain = domain_name
         self.principal = "ldap/%s@%s" % (self.fqdn, self.realm)
         self.subject_base = subject_base
+        self.subject_rdn = subject_rdn
         self.idstart = idstart
         self.idmax = idmax
         self.pkcs12_info = pkcs12_info
@@ -293,10 +294,10 @@
     def create_instance(self, realm_name, fqdn, domain_name,
                         dm_password, pkcs12_info=None,
                         idstart=1100, idmax=999999, subject_base=None,
-                        hbac_allow=True, ca_file=None):
+                        hbac_allow=True, ca_file=None, subject_rdn=None):
         self.init_info(
             realm_name, fqdn, domain_name, dm_password,
-            subject_base, idstart, idmax, pkcs12_info, ca_file=ca_file)
+            subject_base, idstart, idmax, pkcs12_info, ca_file=ca_file, subject_rdn=subject_rdn)
 
         self.__common_setup()
 
@@ -326,7 +327,7 @@
         self.start_creation(runtime=10)
 
     def create_replica(self, realm_name, master_fqdn, fqdn,
-                       domain_name, dm_password, subject_base,
+                       domain_name, dm_password, subject_base, subject_rdn,
                        pkcs12_info=None, ca_file=None, ca_is_configured=None):
         # 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
@@ -341,6 +342,7 @@
             domain_name=domain_name,
             dm_password=dm_password,
             subject_base=subject_base,
+            subject_rdn=subject_rdn,
             idstart=idstart,
             idmax=idmax,
             pkcs12_info=pkcs12_info,
@@ -617,7 +619,7 @@
 
     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, subject_rdn=self.subject_rdn)
         if self.pkcs12_info:
             if self.ca_is_configured:
                 trust_flags = 'CT,C,C'
@@ -634,7 +636,7 @@
             self.nickname = server_certs[0][0]
             self.dercert = dsdb.get_cert_from_db(self.nickname, pem=False)
         else:
-            cadb = certs.CertDB(self.realm, host_name=self.fqdn, subject_base=self.subject_base)
+            cadb = certs.CertDB(self.realm, host_name=self.fqdn, subject_base=self.subject_base, subject_rdn=self.subject_rdn)
 
             # FIXME, need to set this nickname in the RA plugin
             cadb.export_ca_cert('ipaCert', False)
@@ -683,7 +685,7 @@
 
         dirname = config_dirname(self.serverid)
         dsdb = certs.CertDB(self.realm, nssdir=dirname,
-                            subject_base=self.subject_base)
+                            subject_base=self.subject_base, subject_rdn=self.subject_rdn)
         trust_flags = dict(reversed(dsdb.list_certs()))
 
         conn = ipaldap.IPAdmin(self.fqdn)
@@ -707,7 +709,7 @@
     def __import_ca_certs(self):
         dirname = config_dirname(self.serverid)
         dsdb = certs.CertDB(self.realm, nssdir=dirname,
-                            subject_base=self.subject_base)
+                            subject_base=self.subject_base, subject_rdn=self.subject_rdn)
 
         conn = ipaldap.IPAdmin(self.fqdn)
         conn.do_simple_bind(DN(('cn', 'directory manager')), self.dm_password)
@@ -736,11 +738,18 @@
                         config_dirname(self.serverid) + "certmap.conf")
         installutils.update_file(config_dirname(self.serverid) + "certmap.conf",
                                  '$SUBJECT_BASE', str(self.subject_base))
+        installutils.update_file(config_dirname(self.serverid) + "certmap.conf",
+                                 '$SUBJECT_RDN', str(self.subject_rdn))
         sysupgrade.set_upgrade_state(
             'certmap.conf',
             'subject_base',
             str(self.subject_base)
         )
+        sysupgrade.set_upgrade_state(
+            'certmap.conf',
+            'subject_rdn',
+            str(self.subject_rdn)
+        )
 
     def __enable_ldapi(self):
         self._ldap_mod("ldapi.ldif", self.sub_dict)
@@ -872,7 +881,7 @@
         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, subject_rdn=self.subject_rdn)
         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
@@ -1072,6 +1081,88 @@
                           'certmap.conf')
         return None
 
+    def find_subject_rdn(self):
+        """
+        Try to find the current value of certificate subject rdn.
+        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
+
+        Note that this method can only be executed AFTER the ipa server
+        is configured, the api is initialized elsewhere and
+        that a ticket already have been acquired.
+        """
+        root_logger.debug(
+            'Trying to find certificate subject rdn in sysupgrade')
+        subject_rdn = sysupgrade.get_upgrade_state(
+            'certmap.conf', 'subject_rdn')
+
+        if subject_rdn:
+            root_logger.debug(
+                'Found certificate subject rdn in sysupgrade: %s',
+                subject_rdn)
+            return subject_rdn
+
+        root_logger.debug(
+            'Unable to find certificate subject rdn in sysupgrade')
+        root_logger.debug(
+            'Trying to find certificate subject rdn in DS')
+
+        ds_is_running = is_ds_running()
+        if not ds_is_running:
+            try:
+                self.start()
+                ds_is_running = True
+            except ipautil.CalledProcessError as e:
+                root_logger.error('Cannot start DS to find certificate '
+                                  'subject rdn: %s', e)
+
+        if ds_is_running:
+            try:
+                api.Backend.ldap2.connect(autobind=True)
+                ret = api.Command['config_show']()
+                subject_rdn = str(
+                    ret['result']['ipacertificatesubjectrdn'][0])
+                root_logger.debug(
+                    'Found certificate subject rdn in DS: %s', subject_rdn)
+            except errors.PublicError, e:
+                root_logger.error('Cannot connect to DS to find certificate '
+                                  'subject rdn: %s', e)
+            finally:
+                try:
+                    api.Backend.ldap2.disconnect()
+                except Exception:
+                    pass
+
+        if not subject_rdn:
+            root_logger.debug('Unable to find certificate subject rdn in DS')
+            root_logger.debug('Trying to find certificate subject rdn 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_rdn = line.strip().split(',')[-2]
+                            root_logger.debug(
+                                'Found certificate subject rdn in certmap.conf: '
+                                '%s', subject_rdn)
+
+            except IOError as e:
+                root_logger.error('Cannot open certmap.conf to find certificate '
+                                  'subject rdn: %s', e.strerror)
+
+        if subject_rdn:
+            return subject_rdn
+
+        root_logger.debug('Unable to find certificate subject rdn in '
+                          'certmap.conf')
+        return None
+
     def __set_domain_level(self):
         # Create global domain level entry and set the domain level
         if self.domainlevel is not None:
diff -Nur freeipa-4.2.0-15.el7.17/ipaserver/install/installutils.py freeipa-4.2.0/ipaserver/install/installutils.py
--- freeipa-4.2.0-15.el7.17/ipaserver/install/installutils.py	2016-05-24 19:37:31.000000000 +0200
+++ freeipa-4.2.0/ipaserver/install/installutils.py	2016-07-07 06:20:31.204550122 +0200
@@ -102,11 +102,13 @@
         self.host_name = ""
         self.dir = ""
         self.subject_base = None
+        self.subject_rdn = None
         self.setup_ca = False
         self.version = 0
         self.top_dir = top_dir
 
     subject_base = ipautil.dn_attribute_property('_subject_base')
+    subject_rdn = ipautil.dn_attribute_property('_subject_rdn')
 
 def get_fqdn():
     fqdn = ""
@@ -579,6 +581,7 @@
     rconfig.domain_name = config.get("realm", "domain_name")
     rconfig.host_name = config.get("realm", "destination_host")
     rconfig.subject_base = config.get("realm", "subject_base")
+    rconfig.subject_rdn = config.get("realm", "subject_rdn")
     try:
         rconfig.version = int(config.get("realm", "version"))
     except NoOptionError:
@@ -973,7 +976,7 @@
     except ValueError as e:
         root_logger.debug("Invalid value in %s %s", paths.ENTROPY_AVAIL, e)
 
-def load_external_cert(files, subject_base):
+def load_external_cert(files, subject_base, subject_rdn=None):
     """
     Load and verify external CA certificate chain from multiple files.
 
@@ -982,9 +985,12 @@
 
     :param files: Names of files to import
     :param subject_base: Subject name base for IPA certificates
+    :param subject_rdn: Subject RDN for IPA certificates
     :returns: Temporary file with the IPA CA certificate and temporary file
         with the external CA certificate chain
     """
+    if subject_rdn is None:
+        subject_rdn = DN(('CN', 'Certificate Authority'))
     with certs.NSSDatabase() as nssdb:
         db_password = ipautil.ipa_generate_password()
         db_pwdfile = ipautil.write_tmp_file(db_password)
@@ -995,7 +1001,7 @@
         except RuntimeError as e:
             raise ScriptError(str(e))
 
-        ca_subject = DN(('CN', 'Certificate Authority'), subject_base)
+        ca_subject = DN(subject_rdn, subject_base)
         ca_nickname = None
         cache = {}
         for nickname, trust_flags in nssdb.list_certs():
diff -Nur freeipa-4.2.0-15.el7.17/ipaserver/install/ipa_replica_prepare.py freeipa-4.2.0/ipaserver/install/ipa_replica_prepare.py
--- freeipa-4.2.0-15.el7.17/ipaserver/install/ipa_replica_prepare.py	2016-05-24 19:37:31.000000000 +0200
+++ freeipa-4.2.0/ipaserver/install/ipa_replica_prepare.py	2016-07-07 06:20:31.205550141 +0200
@@ -187,6 +187,8 @@
             entry_attrs = conn.get_ipa_config()
             self.subject_base = entry_attrs.get(
                 'ipacertificatesubjectbase', [None])[0]
+            self.subject_rdn = entry_attrs.get(
+                'ipacertificatesubjectrdn', [None])[0]
 
             ca_enabled = api.Command.ca_is_enabled()['result']
 
@@ -208,6 +210,10 @@
 
         if self.subject_base is not None:
             self.subject_base = DN(self.subject_base)
+        if self.subject_rdn is None:
+            self.subject_rdn = DN(('CN','Certificate Authority'))
+        else:
+            self.subject_rdn = DN(self.subject_rdn)
 
         # Validate more options using the password
         try:
@@ -447,6 +453,7 @@
         config.set("realm", "domain_name", api.env.domain)
         config.set("realm", "destination_host", self.replica_fqdn)
         config.set("realm", "subject_base", str(self.subject_base))
+        config.set("realm", "subject_rdn", str(self.subject_rdn))
         config.set("realm", "version", str(version.NUM_VERSION))
 
         with open(os.path.join(self.dir, "realm_info"), "w") as fd:
@@ -572,6 +579,7 @@
         options = self.options
         hostname = self.replica_fqdn
         subject_base = self.subject_base
+        subject_rdn = self.subject_rdn
 
         if is_kdc:
             nickname = "KDC-Cert"
@@ -580,11 +588,11 @@
 
         try:
             db = certs.CertDB(
-                api.env.realm, nssdir=self.dir, subject_base=subject_base)
+                api.env.realm, nssdir=self.dir, subject_base=subject_base, subject_rdn=subject_rdn)
             db.create_passwd_file()
             ca_db = certs.CertDB(
                 api.env.realm, host_name=api.env.host,
-                subject_base=subject_base)
+                subject_base=subject_base, subject_rdn=subject_rdn)
             db.create_from_cacert(ca_db.cacert_fname)
             db.create_server_cert(nickname, hostname, ca_db)
 
diff -Nur freeipa-4.2.0-15.el7.17/ipaserver/install/krainstance.py freeipa-4.2.0/ipaserver/install/krainstance.py
--- freeipa-4.2.0-15.el7.17/ipaserver/install/krainstance.py	2016-05-24 19:37:31.000000000 +0200
+++ freeipa-4.2.0/ipaserver/install/krainstance.py	2016-07-05 17:06:49.433028447 +0200
@@ -80,7 +80,7 @@
                            admin_password, ds_port=DEFAULT_DSPORT,
                            pkcs12_info=None, master_host=None,
                            master_replication_port=None,
-                           subject_base=None):
+                           subject_base=None, subject_rdn=None):
         """Create a KRA instance.
 
            To create a clone, pass in pkcs12_info.
@@ -99,6 +99,10 @@
             self.subject_base = DN(('O', self.realm))
         else:
             self.subject_base = subject_base
+        if subject_rdn is None:
+            self.subject_rdn = DN(('CN', 'Certificate Authority'))
+        else:
+            self.subject_rdn = subject_rdn
         self.realm = realm_name
         self.suffix = ipautil.realm_to_suffix(realm_name)
 
@@ -298,7 +302,7 @@
             userCertificate=[cert_data],
             description=['2;%s;%s;%s' % (
                 cert.serial_number,
-                DN(('CN', 'Certificate Authority'), self.subject_base),
+                DN(self.subject_rdn, self.subject_base),
                 DN(('CN', 'IPA RA'), self.subject_base))])
         conn.add_entry(entry)
 
diff -Nur freeipa-4.2.0-15.el7.17/ipaserver/install/kra.py freeipa-4.2.0/ipaserver/install/kra.py
--- freeipa-4.2.0-15.el7.17/ipaserver/install/kra.py	2015-07-09 10:57:36.000000000 +0200
+++ freeipa-4.2.0/ipaserver/install/kra.py	2016-07-05 17:06:49.433028447 +0200
@@ -58,9 +58,18 @@
             api.env.realm,
             dogtag_constants=dogtag.install_constants)
 
+        if not options.subject_cn:
+            root_logger.debug("krainstall no subject_cn, using default")
+            options.subject_cn = 'Certificate Authority'
+
+        if not options.subject_mail:
+            options.subject_rdn = DN(('CN', options.subject_cn))
+        else:
+            options.subject_rdn = DN(('E', options.subject_mail ), ('CN', options.subject_cn))
+
         kra.configure_instance(
             api.env.realm, api.env.host, api.env.domain, options.dm_password,
-            options.dm_password, subject_base=subject)
+            options.dm_password, subject_base=subject, subject_rdn=options.subject_rdn)
     else:
         kra = krainstance.install_replica_kra(replica_config)
 
diff -Nur freeipa-4.2.0-15.el7.17/ipaserver/install/krbinstance.py freeipa-4.2.0/ipaserver/install/krbinstance.py
--- freeipa-4.2.0-15.el7.17/ipaserver/install/krbinstance.py	2015-06-18 14:54:49.000000000 +0200
+++ freeipa-4.2.0/ipaserver/install/krbinstance.py	2016-07-05 17:06:49.433028447 +0200
@@ -163,7 +163,7 @@
         self.step("starting the KDC", self.__start_instance)
         self.step("configuring KDC to start on boot", self.__enable)
 
-    def create_instance(self, realm_name, host_name, domain_name, admin_password, master_password, setup_pkinit=False, pkcs12_info=None, subject_base=None):
+    def create_instance(self, realm_name, host_name, domain_name, admin_password, master_password, setup_pkinit=False, pkcs12_info=None, subject_base=None, subject_rdn=None):
         self.master_password = master_password
         self.pkcs12_info = pkcs12_info
         self.subject_base = subject_base
diff -Nur freeipa-4.2.0-15.el7.17/ipaserver/install/server/install.py freeipa-4.2.0/ipaserver/install/server/install.py
--- freeipa-4.2.0-15.el7.17/ipaserver/install/server/install.py	2016-05-24 19:37:31.000000000 +0200
+++ freeipa-4.2.0/ipaserver/install/server/install.py	2016-05-24 19:37:31.000000000 +0200
@@ -236,7 +236,7 @@
         sys.exit(1)
 
 
-def set_subject_in_config(realm_name, dm_password, suffix, subject_base):
+def set_subject_in_config(realm_name, dm_password, suffix, subject_base, subject_rdn=None):
         ldapuri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % (
             installutils.realm_to_serverid(realm_name)
         )
@@ -252,6 +252,9 @@
         if 'ipacertificatesubjectbase' not in entry_attrs:
             entry_attrs['ipacertificatesubjectbase'] = [str(subject_base)]
             conn.update_entry(entry_attrs)
+        if 'ipacertificatesubjectrdn' not in entry_attrs:
+            entry_attrs['ipacertificatesubjectrdn'] = [str(subject_rdn)]
+            conn.update_entry(entry_attrs)
         conn.disconnect()
 
 
@@ -482,6 +485,14 @@
     if not options.subject:
         options.subject = DN(('O', realm_name))
 
+    if not options.subject_cn:
+        options.subject_cn = 'Certificate Authority'
+
+    if not options.subject_mail:
+        options.subject_rdn = DN(('CN', options.subject_cn))
+    else:
+        options.subject_rdn = DN(('E', options.subject_mail ), ('CN', options.subject_cn))
+
     if options.http_cert_files:
         if options.http_pin is None:
             options.http_pin = installutils.read_password(
@@ -740,7 +751,7 @@
             ds.create_instance(realm_name, host_name, domain_name,
                                dm_password, dirsrv_pkcs12_info,
                                idstart=options.idstart, idmax=options.idmax,
-                               subject_base=options.subject,
+                               subject_base=options.subject, subject_rdn=options.subject_rdn,
                                hbac_allow=not options.no_hbac_allow)
         else:
             ds = dsinstance.DsInstance(fstore=fstore,
@@ -749,15 +760,23 @@
             ds.create_instance(realm_name, host_name, domain_name,
                                dm_password,
                                idstart=options.idstart, idmax=options.idmax,
-                               subject_base=options.subject,
+                               subject_base=options.subject, subject_rdn=options.subject_rdn,
                                hbac_allow=not options.no_hbac_allow)
     else:
         ds = dsinstance.DsInstance(fstore=fstore,
                                    domainlevel=options.domainlevel)
         installer._ds = ds
+        if not options.subject_cn:
+            options.subject_cn = 'Certificate Authority'
+
+        if not options.subject_mail:
+            options.subject_rdn = DN(('CN', options.subject_cn))
+        else:
+            options.subject_rdn = DN(('E', options.subject_mail ), ('CN', options.subject_cn))
+
         ds.init_info(
             realm_name, host_name, domain_name, dm_password,
-            options.subject, 1101, 1100, None)
+            options.subject, 1101, 1100, None, None, subject_rdn=options.subject_rdn)
 
     if setup_ca:
         if not options.external_cert_files and options.external_ca:
@@ -797,12 +816,12 @@
                             dm_password, master_password,
                             setup_pkinit=not options.no_pkinit,
                             pkcs12_info=pkinit_pkcs12_info,
-                            subject_base=options.subject)
+                            subject_base=options.subject, subject_rdn=options.subject_rdn)
     else:
         krb.create_instance(realm_name, host_name, domain_name,
                             dm_password, master_password,
                             setup_pkinit=not options.no_pkinit,
-                            subject_base=options.subject)
+                            subject_base=options.subject, subject_rdn=options.subject_rdn)
 
     # The DS instance is created before the keytab, add the SSL cert we
     # generated
@@ -838,7 +857,8 @@
     ca_db.publish_ca_cert(CACERT)
 
     set_subject_in_config(realm_name, dm_password,
-                          ipautil.realm_to_suffix(realm_name), options.subject)
+                          ipautil.realm_to_suffix(realm_name),
+                          options.subject, options.subject_rdn)
 
     # Apply any LDAP updates. Needs to be done after the configuration file
     # is created
@@ -1282,6 +1302,26 @@
         except ValueError, e:
             raise ValueError("invalid subject base format: %s" % e)
 
+    subject_cn = Knob(
+        str, None,
+        description="The certificate subject CN (value without OC, "
+                    "defaults to Certificate Authority)",
+        cli_name='subject_cn',
+        cli_metavar='NAME',
+    )
+
+    subject_mail = Knob(
+        str, None,
+        description="The certificate subject mail address (value without OC)",
+        cli_name='subject_mail',
+        cli_metavar='NAME',
+    )
+
+    subject_rdn = Knob(
+        str, None,
+        description="The certificate subject RDN",
+    )
+
     ca_signing_algorithm = Knob(
         {'SHA1withRSA', 'SHA256withRSA', 'SHA512withRSA'}, None,
         description="Signing algorithm of the IPA CA certificate",
diff -Nur freeipa-4.2.0-15.el7.17/ipaserver/install/server/replicainstall.py freeipa-4.2.0/ipaserver/install/server/replicainstall.py
--- freeipa-4.2.0-15.el7.17/ipaserver/install/server/replicainstall.py	2016-05-24 19:37:31.000000000 +0200
+++ freeipa-4.2.0/ipaserver/install/server/replicainstall.py	2016-07-07 06:20:31.206550160 +0200
@@ -72,6 +72,7 @@
         domain_name=config.domain_name,
         dm_password=config.dirman_password,
         subject_base=config.subject_base,
+        subject_rdn=config.subject_rdn,
         pkcs12_info=pkcs12_info,
         ca_is_configured=ipautil.file_exists(config.dir + "/cacert.p12"),
         ca_file=config.dir + "/ca.crt",
@@ -412,7 +413,8 @@
         try:
             tmp_db = certs.CertDB(config.realm_name,
                                   nssdir=tmp_db_dir,
-                                  subject_base=config.subject_base)
+                                  subject_base=config.subject_base,
+                                  subject_rdn=config.subject_rdn)
             if ca_enabled:
                 trust_flags = 'CT,C,C'
             else:
@@ -517,6 +519,7 @@
             options.realm_name = config.realm_name
             options.host_name = config.host_name
             options.subject = config.subject_base
+            options.subject_rdn = config.subject_rdn
             ca.install_check(False, config, options)
 
         if config.setup_kra:
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to