Esempio n. 1
0
def expired_ipa_certs(now):
    """
    Determine which IPA certs are expired, or close to expiry.

    Return a list of (IPACertType, cert) pairs.

    """
    certs = []

    # IPA RA
    cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
    if cert.not_valid_after <= now:
        certs.append((IPACertType.IPARA, cert))

    # Apache HTTPD
    cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
    if cert.not_valid_after <= now:
        certs.append((IPACertType.HTTPS, cert))

    # LDAPS
    ds_dbdir = dsinstance.config_dirname(realm_to_serverid(api.env.realm))
    db = NSSDatabase(nssdir=ds_dbdir)
    cert = db.get_cert('Server-Cert')
    if cert.not_valid_after <= now:
        certs.append((IPACertType.LDAPS, cert))

    # KDC
    cert = x509.load_certificate_from_file(paths.KDC_CERT)
    if cert.not_valid_after <= now:
        certs.append((IPACertType.KDC, cert))

    return certs
Esempio n. 2
0
    def check(self):
        self.files = []

        self.collect_files(dsinstance.config_dirname(self.serverid),
                           NSS_SQL_FILES, 'dirsrv', 'root', '0640')

        # There always has to be a special one. pkcs11.txt has a different
        # group so pop off the auto-generated one and add a replacement.
        old = (os.path.join(dsinstance.config_dirname(self.serverid),
                            'pkcs11.txt'), 'dirsrv', 'root', '0640')
        self.files.remove(old)
        new = (os.path.join(dsinstance.config_dirname(self.serverid),
                            'pkcs11.txt'), 'dirsrv', 'dirsrv', '0640')
        self.files.append(new)

        if self.ca.is_configured():
            self.collect_files(paths.PKI_TOMCAT_ALIAS_DIR, NSS_SQL_FILES,
                               'pkiuser', 'pkiuser', '0600')

        return FileCheck.check(self)
Esempio n. 3
0
    def validate_options(self):
        options = self.options
        super(ReplicaPrepare, self).validate_options(needs_root=True)
        installutils.check_server_configuration()

        if not options.ip_addresses:
            if options.reverse_zones:
                self.option_parser.error(
                    "You cannot specify a --reverse-zone "
                    "option without the --ip-address option")
            if options.no_reverse:
                self.option_parser.error(
                    "You cannot specify a --no-reverse "
                    "option without the --ip-address option")
        elif options.reverse_zones and options.no_reverse:
            self.option_parser.error("You cannot specify a --reverse-zone "
                                     "option together with --no-reverse")

        #Automatically disable pkinit w/ dogtag until that is supported
        options.setup_pkinit = False

        # If any of the PKCS#12 options are selected, all are required.
        cert_file_req = (options.dirsrv_cert_files, options.http_cert_files)
        cert_file_opt = (options.pkinit_cert_files, )
        if any(cert_file_req + cert_file_opt) and not all(cert_file_req):
            self.option_parser.error(
                "--dirsrv-cert-file and --http-cert-file are required if any "
                "PKCS#12 options are used.")

        if len(self.args) < 1:
            self.option_parser.error(
                "must provide the fully-qualified name of the replica")
        elif len(self.args) > 1:
            self.option_parser.error(
                "must provide exactly one name for the replica")
        else:
            [self.replica_fqdn] = self.args

        api.bootstrap(in_server=True)
        api.finalize()
        # Connect to LDAP, connection is closed at the end of run()
        api.Backend.ldap2.connect()

        self.check_for_supported_domain_level()

        if api.env.host == self.replica_fqdn:
            raise admintool.ScriptError("You can't create a replica on itself")

        config_dir = dsinstance.config_dirname(
            installutils.realm_to_serverid(api.env.realm))
        if not ipautil.dir_exists(config_dir):
            raise admintool.ScriptError(
                "could not find directory instance: %s" % config_dir)
Esempio n. 4
0
    def validate_options(self):
        options = self.options
        super(ReplicaPrepare, self).validate_options(needs_root=True)
        installutils.check_server_configuration()

        if not options.ip_address:
            if options.reverse_zone:
                self.option_parser.error("You cannot specify a --reverse-zone "
                    "option without the --ip-address option")
            if options.no_reverse:
                self.option_parser.error("You cannot specify a --no-reverse "
                    "option without the --ip-address option")
        elif options.reverse_zone and options.no_reverse:
            self.option_parser.error("You cannot specify a --reverse-zone "
                "option together with --no-reverse")

        #Automatically disable pkinit w/ dogtag until that is supported
        options.setup_pkinit = False

        # If any of the PKCS#12 options are selected, all are required.
        pkcs12_req = (options.dirsrv_pkcs12, options.http_pkcs12)
        pkcs12_opt = (options.pkinit_pkcs12,)
        if any(pkcs12_req + pkcs12_opt) and not all(pkcs12_req):
            self.option_parser.error(
                "--dirsrv_pkcs12 and --http_pkcs12 are required if any "
                "PKCS#12 options are used.")

        if len(self.args) < 1:
            self.option_parser.error(
                "must provide the fully-qualified name of the replica")
        elif len(self.args) > 1:
            self.option_parser.error(
                "must provide exactly one name for the replica")
        else:
            [self.replica_fqdn] = self.args

        api.bootstrap(in_server=True)
        api.finalize()

        if api.env.host == self.replica_fqdn:
            raise admintool.ScriptError("You can't create a replica on itself")

        if not api.env.enable_ra and not options.http_pkcs12:
            raise admintool.ScriptError(
                "Cannot issue certificates: a CA is not installed. Use the "
                "--http_pkcs12, --dirsrv_pkcs12 options to provide custom "
                "certificates.")

        config_dir = dsinstance.config_dirname(
            dsinstance.realm_to_serverid(api.env.realm))
        if not ipautil.dir_exists(config_dir):
            raise admintool.ScriptError(
                "could not find directory instance: %s" % config_dir)
Esempio n. 5
0
    def validate_options(self):
        options = self.options
        super(ReplicaPrepare, self).validate_options(needs_root=True)
        installutils.check_server_configuration()

        if not options.ip_addresses:
            if options.reverse_zones:
                self.option_parser.error("You cannot specify a --reverse-zone "
                    "option without the --ip-address option")
            if options.no_reverse:
                self.option_parser.error("You cannot specify a --no-reverse "
                    "option without the --ip-address option")
        elif options.reverse_zones and options.no_reverse:
            self.option_parser.error("You cannot specify a --reverse-zone "
                "option together with --no-reverse")

        #Automatically disable pkinit w/ dogtag until that is supported
        options.setup_pkinit = False

        # If any of the PKCS#12 options are selected, all are required.
        cert_file_req = (options.dirsrv_cert_files, options.http_cert_files)
        cert_file_opt = (options.pkinit_cert_files,)
        if any(cert_file_req + cert_file_opt) and not all(cert_file_req):
            self.option_parser.error(
                "--dirsrv-cert-file and --http-cert-file are required if any "
                "PKCS#12 options are used.")

        if len(self.args) < 1:
            self.option_parser.error(
                "must provide the fully-qualified name of the replica")
        elif len(self.args) > 1:
            self.option_parser.error(
                "must provide exactly one name for the replica")
        else:
            [self.replica_fqdn] = self.args

        api.bootstrap(in_server=True)
        api.finalize()
        # Connect to LDAP, connection is closed at the end of run()
        api.Backend.ldap2.connect()

        self.check_for_supported_domain_level()

        if api.env.host == self.replica_fqdn:
            raise admintool.ScriptError("You can't create a replica on itself")

        config_dir = dsinstance.config_dirname(
            installutils.realm_to_serverid(api.env.realm))
        if not ipautil.dir_exists(config_dir):
            raise admintool.ScriptError(
                "could not find directory instance: %s" % config_dir)
Esempio n. 6
0
def expired_ipa_certs(now):
    """
    Determine which IPA certs are expired, or close to expiry.

    Return a list of (IPACertType, cert) pairs.

    """
    certs = []
    non_renewed = []

    # IPA RA
    cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
    if cert.not_valid_after <= now:
        certs.append((IPACertType.IPARA, cert))

    # Apache HTTPD
    cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
    if cert.not_valid_after <= now:
        if not is_ipa_issued_cert(api, cert):
            non_renewed.append((IPACertType.HTTPS, cert))
        else:
            certs.append((IPACertType.HTTPS, cert))

    # LDAPS
    serverid = realm_to_serverid(api.env.realm)
    ds = dsinstance.DsInstance(realm_name=api.env.realm)
    ds_dbdir = dsinstance.config_dirname(serverid)
    ds_nickname = ds.get_server_cert_nickname(serverid)
    db = NSSDatabase(nssdir=ds_dbdir)
    cert = db.get_cert(ds_nickname)
    if cert.not_valid_after <= now:
        if not is_ipa_issued_cert(api, cert):
            non_renewed.append((IPACertType.LDAPS, cert))
        else:
            certs.append((IPACertType.LDAPS, cert))

    # KDC
    cert = x509.load_certificate_from_file(paths.KDC_CERT)
    if cert.not_valid_after <= now:
        if not is_ipa_issued_cert(api, cert):
            non_renewed.append((IPACertType.HTTPS, cert))
        else:
            certs.append((IPACertType.KDC, cert))

    return certs, non_renewed
Esempio n. 7
0
    def install_dirsrv_cert(self):
        serverid = installutils.realm_to_serverid(api.env.realm)
        dirname = dsinstance.config_dirname(serverid)

        conn = api.Backend.ldap2
        entry = conn.get_entry(DN(('cn', 'RSA'), ('cn', 'encryption'),
                                  ('cn', 'config')),
                               ['nssslpersonalityssl'])
        old_cert = entry.single_value['nssslpersonalityssl']

        server_cert = self.import_cert(dirname, self.options.pin,
                                       old_cert, 'ldap/%s' % api.env.host,
                                       'restart_dirsrv %s' % serverid)

        entry['nssslpersonalityssl'] = [server_cert]
        try:
            conn.update_entry(entry)
        except errors.EmptyModlist:
            pass
Esempio n. 8
0
    def install_dirsrv_cert(self):
        serverid = installutils.realm_to_serverid(api.env.realm)
        dirname = dsinstance.config_dirname(serverid)

        conn = api.Backend.ldap2
        entry = conn.get_entry(
            DN(('cn', 'RSA'), ('cn', 'encryption'), ('cn', 'config')),
            ['nssslpersonalityssl'])
        old_cert = entry.single_value['nssslpersonalityssl']

        server_cert = self.import_cert(dirname, self.options.pin, old_cert,
                                       'ldap/%s' % api.env.host,
                                       'restart_dirsrv %s' % serverid)

        entry['nssslpersonalityssl'] = [server_cert]
        try:
            conn.update_entry(entry)
        except errors.EmptyModlist:
            pass
Esempio n. 9
0
    def execute(self, **options):
        ldap = self.obj.backend
        (cdn, ipa_config) = ldap.get_ipa_config()
        subject_base = ipa_config.get('ipacertificatesubjectbase', [None])[0]
        dirname = config_dirname(realm_to_serverid(api.env.realm))
        certdb = certs.CertDB(api.env.realm, nssdir=dirname, subject_base=subject_base)

        dercert = certdb.get_cert_from_db(certdb.cacert_name, pem=False)

        updates = {}
        dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn','etc'), api.env.basedn)

        cacrt_entry = ['objectclass:nsContainer',
                       'objectclass:pkiCA',
                       'cn:CAcert',
                       'cACertificate;binary:%s' % dercert,
                      ]
        updates[dn] = {'dn': dn, 'default': cacrt_entry}

        return (False, True, [updates])
Esempio n. 10
0
def install_ipa_certs(subject_base, ca_subject_dn, certs):
    """Print details and install renewed IPA certificates."""
    for certtype, oldcert in certs:
        cert_path = "/etc/pki/pki-tomcat/certs/{}-renewed.crt" \
            .format(oldcert.serial_number)
        cert = x509.load_certificate_from_file(cert_path)
        print_cert_info("Renewed IPA", certtype.value, cert)

        if certtype is IPACertType.IPARA:
            shutil.copyfile(cert_path, paths.RA_AGENT_PEM)
            cainstance.update_people_entry(cert)
            replicate_cert(subject_base, ca_subject_dn, cert)
        elif certtype is IPACertType.HTTPS:
            shutil.copyfile(cert_path, paths.HTTPD_CERT_FILE)
        elif certtype is IPACertType.LDAPS:
            ds_dbdir = dsinstance.config_dirname(
                realm_to_serverid(api.env.realm))
            db = NSSDatabase(nssdir=ds_dbdir)
            db.delete_cert('Server-Cert')
            db.import_pem_cert('Server-Cert', EMPTY_TRUST_FLAGS, cert_path)
        elif certtype is IPACertType.KDC:
            shutil.copyfile(cert_path, paths.KDC_CERT)
Esempio n. 11
0
def install_ipa_certs(subject_base, ca_subject_dn, certs):
    """Print details and install renewed IPA certificates."""
    for certtype, oldcert in certs:
        cert_path = RENEWED_CERT_PATH_TEMPLATE.format(oldcert.serial_number)
        cert = x509.load_certificate_from_file(cert_path)
        print_cert_info("Renewed IPA", certtype.value, cert)

        if certtype is IPACertType.IPARA:
            shutil.copyfile(cert_path, paths.RA_AGENT_PEM)
            cainstance.update_people_entry(cert)
            replicate_cert(subject_base, ca_subject_dn, cert)
        elif certtype is IPACertType.HTTPS:
            shutil.copyfile(cert_path, paths.HTTPD_CERT_FILE)
        elif certtype is IPACertType.LDAPS:
            serverid = realm_to_serverid(api.env.realm)
            ds = dsinstance.DsInstance(realm_name=api.env.realm)
            ds_dbdir = dsinstance.config_dirname(serverid)
            db = NSSDatabase(nssdir=ds_dbdir)
            ds_nickname = ds.get_server_cert_nickname(serverid)
            db.delete_cert(ds_nickname)
            db.import_pem_cert(ds_nickname, EMPTY_TRUST_FLAGS, cert_path)
        elif certtype is IPACertType.KDC:
            shutil.copyfile(cert_path, paths.KDC_CERT)
Esempio n. 12
0
def is_dirsrv_debugging_enabled():
    """
    Check the 389-ds instance to see if debugging is enabled.
    If so we suppress that in our output.

    returns True or False
    """
    debugging = False
    serverid = realm_to_serverid(api.env.realm)
    dselist = [config_dirname(serverid)]
    for dse in dselist:
        try:
            fd = open(dse + "dse.ldif", "r")
        except IOError:
            continue
        lines = fd.readlines()
        fd.close()
        for line in lines:
            if line.lower().startswith("nsslapd-errorlog-level"):
                _option, value = line.split(":")
                if int(value) > 0:
                    debugging = True

    return debugging
Esempio n. 13
0
    def install_dirsrv_cert(self):
        serverid = dsinstance.realm_to_serverid(api.env.realm)
        dirname = dsinstance.config_dirname(serverid)

        conn = ldap2(shared_instance=False, base_dn='')
        conn.connect(bind_dn=DN(('cn', 'directory manager')),
                     bind_pw=self.options.dirman_password)

        entry = conn.get_entry(DN(('cn', 'RSA'), ('cn', 'encryption'),
                                  ('cn', 'config')),
                               ['nssslpersonalityssl'])
        old_cert = entry.single_value['nssslpersonalityssl']

        server_cert = self.import_cert(dirname, self.options.pin,
                                       old_cert, 'ldap/%s' % api.env.host,
                                       'restart_dirsrv %s' % serverid)

        entry['nssslpersonalityssl'] = [server_cert]
        try:
            conn.update_entry(entry)
        except errors.EmptyModlist:
            pass

        conn.disconnect()
Esempio n. 14
0
def install_step_1(standalone, replica_config, options):
    realm_name = options.realm_name
    domain_name = options.domain_name
    dm_password = options.dm_password
    host_name = options.host_name
    subject_base = options.subject

    basedn = ipautil.realm_to_suffix(realm_name)

    ca = cainstance.CAInstance(realm_name, certs.NSS_DIR, host_name=host_name)

    if standalone:
        ca.stop('pki-tomcat')

    # We need to ldap_enable the CA now that DS is up and running
    if replica_config is None:
        config = ['caRenewalMaster']
    else:
        config = []
    ca.ldap_enable('CA', host_name, dm_password, basedn, config)

    # This is done within stopped_service context, which restarts CA
    ca.enable_client_auth_to_db(paths.CA_CS_CFG_PATH)

    # Lightweight CA key retrieval is configured in step 1 instead
    # of CAInstance.configure_instance (which is invoked from step
    # 0) because kadmin_addprinc fails until krb5.conf is installed
    # by krb.create_instance.
    #
    ca.setup_lightweight_ca_key_retrieval()

    if standalone and replica_config is None:
        serverid = installutils.realm_to_serverid(realm_name)
        dirname = dsinstance.config_dirname(serverid)

        # 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)
        trust_flags = dict(reversed(cadb.list_certs()))
        trust_chain = cadb.find_root_cert('ipaCert')[:-1]
        for nickname in trust_chain[:-1]:
            cert = cadb.get_cert_from_db(nickname, pem=False)
            dsdb.add_cert(cert, nickname, trust_flags[nickname])
            certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn,
                                      cert, nickname, trust_flags[nickname])

        nickname = trust_chain[-1]
        cert = cadb.get_cert_from_db(nickname, pem=False)
        dsdb.add_cert(cert, nickname, trust_flags[nickname])
        certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn,
                                  cert, nickname, trust_flags[nickname],
                                  config_ipa=True, config_compat=True)


        api.Backend.ldap2.disconnect()

        # Restart DS
        services.knownservices.dirsrv.restart(serverid)

        api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')),
                                  bind_pw=dm_password)

        # Store DS CA cert in Dogtag NSS database
        dogtagdb = certs.CertDB(realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR)
        trust_flags = dict(reversed(dsdb.list_certs()))
        server_certs = dsdb.find_server_certs()
        trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1]
        nickname = trust_chain[-1]
        cert = dsdb.get_cert_from_db(nickname)
        dogtagdb.add_cert(cert, nickname, trust_flags[nickname])

    if standalone:
        ca.start('pki-tomcat')

        # We need to restart apache as we drop a new config file in there
        services.knownservices.httpd.restart(capture_output=True)

        # Install CA DNS records
        if bindinstance.dns_container_exists(host_name, basedn, dm_password):
            bind = bindinstance.BindInstance(dm_password=dm_password)
            bind.update_system_records()
Esempio n. 15
0
    def check(self):
        validate = []
        ca_pw_fname = None

        if self.ca.is_configured():
            try:
                ca_passwd = get_dogtag_cert_password()
            except IOError as e:
                yield Result(
                    self,
                    constants.ERROR,
                    error=str(e),
                    msg='Unable to read CA NSSDB token password: {error}')
                return
            else:
                with tempfile.NamedTemporaryFile(mode='w',
                                                 delete=False) as ca_pw_file:
                    ca_pw_file.write(ca_passwd)
                    ca_pw_fname = ca_pw_file.name

                validate.append((
                    paths.PKI_TOMCAT_ALIAS_DIR,
                    'Server-Cert cert-pki-ca',
                    ca_pw_fname,
                ), )

        validate.append((
            dsinstance.config_dirname(self.serverid),
            self.ds.get_server_cert_nickname(self.serverid),
            os.path.join(dsinstance.config_dirname(self.serverid),
                         'pwdfile.txt'),
        ))

        # Wrap in try/except to ensure the temporary password file is
        # removed
        try:
            for (dbdir, nickname, pinfile) in validate:
                # detect the database type so we have the right prefix
                db = certdb.NSSDatabase(dbdir)

                key = os.path.normpath(dbdir) + ':' + nickname
                try:
                    response = self.validate_nss(dbdir, db.dbtype, pinfile,
                                                 nickname)
                except ipautil.CalledProcessError as e:
                    logger.debug('Validation of NSS certificate failed %s', e)
                    yield Result(
                        self,
                        constants.ERROR,
                        key=key,
                        dbdir=dbdir,
                        nickname=nickname,
                        reason=response.output_error,
                        msg='Validation of {nickname} in {dbdir} failed: '
                        '{reason}')
                else:
                    if 'certificate is valid' not in \
                            response.raw_output.decode('utf-8'):
                        yield Result(
                            self,
                            constants.ERROR,
                            key=key,
                            dbdir=dbdir,
                            nickname=nickname,
                            reason="%s: %s" %
                            (response.raw_output.decode('utf-8'),
                             response.error_log),
                            msg='Validation of {nickname} in {dbdir} failed: '
                            '{reason}')
                    else:
                        yield Result(self,
                                     constants.SUCCESS,
                                     dbdir=dbdir,
                                     nickname=nickname,
                                     key=key)
        finally:
            if ca_pw_fname:
                ipautil.remove_file(ca_pw_fname)
Esempio n. 16
0
def install_step_1(standalone, replica_config, options):
    realm_name = options.realm_name
    dm_password = options.dm_password
    host_name = options.host_name
    subject_base = options.subject

    basedn = ipautil.realm_to_suffix(realm_name)

    ca = cainstance.CAInstance(realm_name, certs.NSS_DIR, host_name=host_name)

    if standalone:
        ca.stop('pki-tomcat')

    # We need to ldap_enable the CA now that DS is up and running
    if replica_config is None:
        config = ['caRenewalMaster']
    else:
        config = []
    ca.ldap_enable('CA', host_name, dm_password, basedn, config)

    # This is done within stopped_service context, which restarts CA
    ca.enable_client_auth_to_db(paths.CA_CS_CFG_PATH)

    # Lightweight CA key retrieval is configured in step 1 instead
    # of CAInstance.configure_instance (which is invoked from step
    # 0) because kadmin_addprinc fails until krb5.conf is installed
    # by krb.create_instance.
    #
    ca.setup_lightweight_ca_key_retrieval()

    if standalone and replica_config is None:
        serverid = installutils.realm_to_serverid(realm_name)
        dirname = dsinstance.config_dirname(serverid)

        # 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)
        trust_flags = dict(reversed(cadb.list_certs()))
        trust_chain = cadb.find_root_cert('ipaCert')[:-1]
        for nickname in trust_chain[:-1]:
            cert = cadb.get_cert_from_db(nickname, pem=False)
            dsdb.add_cert(cert, nickname, trust_flags[nickname])
            certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn, cert,
                                      nickname, trust_flags[nickname])

        nickname = trust_chain[-1]
        cert = cadb.get_cert_from_db(nickname, pem=False)
        dsdb.add_cert(cert, nickname, trust_flags[nickname])
        certstore.put_ca_cert_nss(api.Backend.ldap2,
                                  api.env.basedn,
                                  cert,
                                  nickname,
                                  trust_flags[nickname],
                                  config_ipa=True,
                                  config_compat=True)

        api.Backend.ldap2.disconnect()

        # Restart DS
        services.knownservices.dirsrv.restart(serverid)

        api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')),
                                  bind_pw=dm_password)

        # Store DS CA cert in Dogtag NSS database
        dogtagdb = certs.CertDB(realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR)
        trust_flags = dict(reversed(dsdb.list_certs()))
        server_certs = dsdb.find_server_certs()
        trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1]
        nickname = trust_chain[-1]
        cert = dsdb.get_cert_from_db(nickname)
        dogtagdb.add_cert(cert, nickname, trust_flags[nickname])

    if standalone:
        ca.start('pki-tomcat')

        # We need to restart apache as we drop a new config file in there
        services.knownservices.httpd.restart(capture_output=True)

        # Install CA DNS records
        if bindinstance.dns_container_exists(host_name, basedn, dm_password):
            bind = bindinstance.BindInstance(dm_password=dm_password)
            bind.update_system_records()
Esempio n. 17
0
    def get_requests(self):
        """Get certmonger tracking requests"""

        # TODO: put this in some central place for here and for
        #       ipaserver/install/server/upgrade.py

        template = paths.CERTMONGER_COMMAND_TEMPLATE

        requests = [
            {
                'cert-file': paths.RA_AGENT_PEM,
                'key-file': paths.RA_AGENT_KEY,
                'ca-name': 'dogtag-ipa-ca-renew-agent',
                'cert-presave-command': template % 'renew_ra_cert_pre',
                'cert-postsave-command': template % 'renew_ra_cert',
            },
        ]

        ca_requests = [
            {
                'cert-database':
                paths.PKI_TOMCAT_ALIAS_DIR,
                'cert-nickname':
                'auditSigningCert cert-pki-ca',
                'ca-name':
                'dogtag-ipa-ca-renew-agent',
                'cert-presave-command':
                template % 'stop_pkicad',
                'cert-postsave-command':
                (template % 'renew_ca_cert "auditSigningCert cert-pki-ca"'),
            },
            {
                'cert-database':
                paths.PKI_TOMCAT_ALIAS_DIR,
                'cert-nickname':
                'ocspSigningCert cert-pki-ca',
                'ca-name':
                'dogtag-ipa-ca-renew-agent',
                'cert-presave-command':
                template % 'stop_pkicad',
                'cert-postsave-command':
                (template % 'renew_ca_cert "ocspSigningCert cert-pki-ca"'),
            },
            {
                'cert-database':
                paths.PKI_TOMCAT_ALIAS_DIR,
                'cert-nickname':
                'subsystemCert cert-pki-ca',
                'ca-name':
                'dogtag-ipa-ca-renew-agent',
                'cert-presave-command':
                template % 'stop_pkicad',
                'cert-postsave-command':
                (template % 'renew_ca_cert "subsystemCert cert-pki-ca"'),
            },
            {
                'cert-database':
                paths.PKI_TOMCAT_ALIAS_DIR,
                'cert-nickname':
                'caSigningCert cert-pki-ca',
                'ca-name':
                'dogtag-ipa-ca-renew-agent',
                'cert-presave-command':
                template % 'stop_pkicad',
                'cert-postsave-command':
                (template % 'renew_ca_cert "caSigningCert cert-pki-ca"'),
                'template-profile':
                None,
            },
            {
                'cert-database':
                paths.PKI_TOMCAT_ALIAS_DIR,
                'cert-nickname':
                'Server-Cert cert-pki-ca',
                'ca-name':
                'dogtag-ipa-ca-renew-agent',
                'cert-presave-command':
                template % 'stop_pkicad',
                'cert-postsave-command':
                (template % 'renew_ca_cert "Server-Cert cert-pki-ca"'),
            },
        ]

        if self.ca.is_configured():
            db = certs.CertDB(api.env.realm, paths.PKI_TOMCAT_ALIAS_DIR)
            for nickname, _trust_flags in db.list_certs():
                if nickname.startswith('caSigningCert cert-pki-ca '):
                    requests.append({
                        'cert-database':
                        paths.PKI_TOMCAT_ALIAS_DIR,
                        'cert-nickname':
                        nickname,
                        'ca-name':
                        'dogtag-ipa-ca-renew-agent',
                        'cert-presave-command':
                        template % 'stop_pkicad',
                        'cert-postsave-command':
                        (template % ('renew_ca_cert "%s"' % nickname)),
                        'template-profile':
                        'caCACert',
                    })

        if self.ca.is_configured():
            requests += ca_requests

        # Check the http server cert if issued by IPA
        if version.NUM_VERSION >= 40700:
            cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
            if is_ipa_issued_cert(api, cert):
                requests.append({
                    'cert-file':
                    paths.HTTPD_CERT_FILE,
                    'key-file':
                    paths.HTTPD_KEY_FILE,
                    'ca-name':
                    'IPA',
                    'cert-postsave-command':
                    template % 'restart_httpd',
                })
        else:
            http_nickname = self.http.get_mod_nss_nickname()
            http_db = certs.CertDB(api.env.realm, nssdir=paths.HTTPD_ALIAS_DIR)
            if http_db.is_ipa_issued_cert(api, http_nickname):
                requests.append({
                    'cert-database':
                    paths.HTTPD_ALIAS_DIR,
                    'cert-nickname':
                    http_nickname,
                    'ca-name':
                    'IPA',
                    'cert-postsave-command':
                    template % 'restart_httpd',
                })

        # Check the ldap server cert if issued by IPA
        ds_nickname = self.ds.get_server_cert_nickname(self.serverid)
        ds_db_dirname = dsinstance.config_dirname(self.serverid)
        ds_db = certs.CertDB(api.env.realm, nssdir=ds_db_dirname)
        if ds_db.is_ipa_issued_cert(api, ds_nickname):
            requests.append({
                'cert-database':
                ds_db_dirname[:-1],
                'cert-nickname':
                ds_nickname,
                'ca-name':
                'IPA',
                'cert-postsave-command':
                '%s %s' % (template % 'restart_dirsrv', self.serverid),
            })

        # Check the KDC cert if issued by IPA
        cert = x509.load_certificate_from_file(paths.KDC_CERT)
        if is_ipa_issued_cert(api, cert):
            requests.append({
                'cert-file':
                paths.KDC_CERT,
                'key-file':
                paths.KDC_KEY,
                'ca-name':
                'IPA',
                'cert-postsave-command':
                template % 'renew_kdc_cert',
            })

        return requests
Esempio n. 18
0
def get_expected_requests(ca, ds, serverid):
    """Provide the expected certmonger tracking request data

       This list is based in part on certificate_renewal_update() in
       ipaserver/install/server/upgrade.py and various
       start_tracking_certificates() methods in *instance.py.

       The list is filtered depending on whether a CA is running
       and the certificates have been issued by IPA.

      :param ca: the CAInstance
      :param ds: the DSInstance
      :param serverid: the DS serverid name
    """
    template = paths.CERTMONGER_COMMAND_TEMPLATE

    if api.Command.ca_is_enabled()['result']:
        requests = [
            {
                'cert-file': paths.RA_AGENT_PEM,
                'key-file': paths.RA_AGENT_KEY,
                'ca-name': RENEWAL_CA_NAME,
                'cert-presave-command': template % 'renew_ra_cert_pre',
                'cert-postsave-command': template % 'renew_ra_cert',
            },
        ]
    else:
        requests = []

    if ca.is_configured():
        dogtag_reqs = ca.tracking_reqs.items()
        kra = krainstance.KRAInstance(api.env.realm)
        if kra.is_installed():
            dogtag_reqs = itertools.chain(dogtag_reqs,
                                          kra.tracking_reqs.items())
        for nick, profile in dogtag_reqs:
            req = {
                'cert-database':
                paths.PKI_TOMCAT_ALIAS_DIR,
                'cert-nickname':
                nick,
                'ca-name':
                RENEWAL_CA_NAME,
                'cert-presave-command':
                template % 'stop_pkicad',
                'cert-postsave-command':
                (template % 'renew_ca_cert "{}"'.format(nick)),
                'template-profile':
                profile,
            }
            requests.append(req)
    else:
        logger.debug('CA is not configured, skipping CA tracking')

    cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
    issued = is_ipa_issued_cert(api, cert)
    if issued is None:
        logger.debug('Unable to determine if \'%s\' was issued by IPA '
                     'because no LDAP connection, assuming yes.')
    if issued or issued is None:
        requests.append({
            'cert-file': paths.HTTPD_CERT_FILE,
            'key-file': paths.HTTPD_KEY_FILE,
            'ca-name': 'IPA',
            'cert-postsave-command': template % 'restart_httpd',
        })
    else:
        logger.debug(
            'HTTP cert not issued by IPA, \'%s\', skip tracking '
            'check', DN(cert.issuer))

    # Check the ldap server cert if issued by IPA
    ds_nickname = ds.get_server_cert_nickname(serverid)
    ds_db_dirname = dsinstance.config_dirname(serverid)
    ds_db = certs.CertDB(api.env.realm, nssdir=ds_db_dirname)
    connected = api.Backend.ldap2.isconnected()
    if not connected:
        logger.debug('Unable to determine if \'%s\' was issued by IPA '
                     'because no LDAP connection, assuming yes.')
    if not connected or ds_db.is_ipa_issued_cert(api, ds_nickname):
        requests.append({
            'cert-database':
            ds_db_dirname[:-1],
            'cert-nickname':
            ds_nickname,
            'ca-name':
            'IPA',
            'cert-postsave-command':
            '%s %s' % (template % 'restart_dirsrv', serverid),
        })
    else:
        logger.debug('DS cert is not issued by IPA, skip tracking check')

    # Check if pkinit is enabled
    if os.path.exists(paths.KDC_CERT):
        pkinit_request_ca = krbinstance.get_pkinit_request_ca()
        requests.append({
            'cert-file': paths.KDC_CERT,
            'key-file': paths.KDC_KEY,
            'ca-name': pkinit_request_ca,
            'cert-postsave-command': template % 'renew_kdc_cert',
        })
    else:
        logger.debug('No KDC pkinit certificate')

    return requests
Esempio n. 19
0
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

    if replica_config is not None:
        if standalone and api.env.ra_plugin == 'selfsign':
            raise ScriptError('A selfsign CA can not be added')

        cafile = os.path.join(replica_config.dir, 'cacert.p12')
        if not options.promote and not ipautil.file_exists(cafile):
            raise ScriptError('CA cannot be installed in CA-less setup.')

        if standalone and not options.skip_conncheck:
            principal = options.principal
            replica_conn_check(replica_config.ca_host_name,
                               host_name,
                               realm_name,
                               True,
                               replica_config.ca_ds_port,
                               options.admin_password,
                               principal=principal,
                               ca_cert_file=options.ca_cert_file)

        if options.skip_schema_check:
            root_logger.info("Skipping CA DS schema check")
        else:
            cainstance.replica_ca_install_check(replica_config,
                                                options.promote)

        return

    if standalone:
        if api.Command.ca_is_enabled()['result']:
            raise ScriptError(
                "One or more CA masters are already present in IPA realm "
                "'%s'.\nIf you wish to replicate CA to this host, please "
                "re-run 'ipa-ca-install'\nwith a replica file generated on "
                "an existing CA master as argument." % realm_name)

    if options.external_cert_files:
        if not cainstance.is_step_one_done():
            # This can happen if someone passes external_ca_file without
            # already having done the first stage of the CA install.
            raise ScriptError(
                "CA is not installed yet. To install with an external CA "
                "is a two-stage process.\nFirst run the installer with "
                "--external-ca.")

        external_cert_file, external_ca_file = installutils.load_external_cert(
            options.external_cert_files, options.subject)
    elif options.external_ca:
        if cainstance.is_step_one_done():
            raise ScriptError(
                "CA is already installed.\nRun the installer with "
                "--external-cert-file.")
        if ipautil.file_exists(paths.ROOT_IPA_CSR):
            raise ScriptError(
                "CA CSR file %s already exists.\nIn order to continue "
                "remove the file and run the installer again." %
                paths.ROOT_IPA_CSR)

    if not options.external_cert_files:
        if not cainstance.check_port():
            print("IPA requires port 8443 for PKI but it is currently in use.")
            raise ScriptError("Aborting installation")

    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)

        for db in (cadb, dsdb):
            for nickname, _trust_flags in db.list_certs():
                if nickname in (certdb.get_ca_nickname(realm_name), 'ipaCert'):
                    raise ScriptError(
                        "Certificate with nickname %s is present in %s, "
                        "cannot continue." % (nickname, db.secdir))

                cert = db.get_cert_from_db(nickname)
                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)):
                    raise ScriptError(
                        "Certificate with subject %s is present in %s, "
                        "cannot continue." % (subject, db.secdir))
Esempio n. 20
0
def uninstall(installer):
    fstore = installer._fstore
    sstore = installer._sstore

    rv = 0

    print("Shutting down all IPA services")
    try:
        run([paths.IPACTL, "stop"], raiseonerr=False)
    except Exception as e:
        pass

    ntpinstance.NTPInstance(fstore).uninstall()

    kra.uninstall(False)

    ca.uninstall()

    dns.uninstall()

    httpinstance.HTTPInstance(fstore).uninstall()
    krbinstance.KrbInstance(fstore).uninstall()
    dsinstance.DsInstance(fstore=fstore).uninstall()
    if _server_trust_ad_installed:
        adtrustinstance.ADTRUSTInstance(fstore).uninstall()
    custodiainstance.CustodiaInstance().uninstall()
    memcacheinstance.MemcacheInstance().uninstall()
    otpdinstance.OtpdInstance().uninstall()
    tasks.restore_hostname(fstore, sstore)
    fstore.restore_all_files()
    try:
        os.remove(paths.ROOT_IPA_CACHE)
    except Exception:
        pass
    try:
        os.remove(paths.ROOT_IPA_CSR)
    except Exception:
        pass

    # ipa-client-install removes /etc/ipa/default.conf

    sstore._load()

    ipaclient.ntpconf.restore_forced_ntpd(sstore)

    # Clean up group_exists (unused since IPA 2.2, not being set since 4.1)
    sstore.restore_state("install", "group_exists")

    services.knownservices.ipa.disable()

    # remove upgrade state file
    sysupgrade.remove_upgrade_file()

    if fstore.has_files():
        root_logger.error('Some files have not been restored, see '
                          '%s/sysrestore.index' % SYSRESTORE_DIR_PATH)
    has_state = False
    for module in IPA_MODULES:  # from installutils
        if sstore.has_state(module):
            root_logger.error('Some installation state for %s has not been '
                              'restored, see %s/sysrestore.state' %
                              (module, SYSRESTORE_DIR_PATH))
            has_state = True
            rv = 1

    if has_state:
        root_logger.error('Some installation state has not been restored.\n'
                          'This may cause re-installation to fail.\n'
                          'It should be safe to remove %s/sysrestore.state '
                          'but it may\n'
                          'mean your system hasn\'t be restored to its '
                          'pre-installation state.' % SYSRESTORE_DIR_PATH)

    # Note that this name will be wrong after the first uninstall.
    dirname = dsinstance.config_dirname(
        installutils.realm_to_serverid(api.env.realm))
    dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, certs.NSS_DIR]
    ids = certmonger.check_state(dirs)
    if ids:
        root_logger.error('Some certificates may still be tracked by '
                          'certmonger.\n'
                          'This will cause re-installation to fail.\n'
                          'Start the certmonger service and list the '
                          'certificates being tracked\n'
                          ' # getcert list\n'
                          'These may be untracked by executing\n'
                          ' # getcert stop-tracking -i <request_id>\n'
                          'for each id in: %s' % ', '.join(ids))

    print("Removing IPA client configuration")
    try:
        result = run([paths.IPA_CLIENT_INSTALL, "--on-master",
                      "--unattended", "--uninstall"],
                     raiseonerr=False, redirect_output=True)
        if result.returncode not in [0, 2]:
            raise RuntimeError("Failed to configure the client")
    except Exception:
        rv = 1
        print("Uninstall of client side components failed!")

    sys.exit(rv)
Esempio n. 21
0
def install_check(standalone, replica_config, options):
    global external_cert_file
    global external_ca_file

    realm_name = options.realm_name
    host_name = options.host_name

    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 = str(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':
            raise ScriptError('A selfsign CA can not be added')

        if standalone and not options.skip_conncheck:
            principal = options.principal
            replica_conn_check(replica_config.ca_host_name,
                               host_name,
                               realm_name,
                               True,
                               replica_config.ca_ds_port,
                               options.admin_password,
                               principal=principal,
                               ca_cert_file=options.ca_cert_file)

        if options.skip_schema_check:
            logger.info("Skipping CA DS schema check")

        return

    if standalone:
        if api.Command.ca_is_enabled()['result']:
            raise ScriptError(
                "One or more CA masters are already present in IPA realm "
                "'%s'.\nIf you wish to replicate CA to this host, please "
                "re-run 'ipa-ca-install'\nwith a replica file generated on "
                "an existing CA master as argument." % realm_name)

    if options.external_cert_files:
        if not cainstance.is_step_one_done():
            # This can happen if someone passes external_ca_file without
            # already having done the first stage of the CA install.
            raise ScriptError(
                "CA is not installed yet. To install with an external CA "
                "is a two-stage process.\nFirst run the installer with "
                "--external-ca.")

        external_cert_file, external_ca_file = installutils.load_external_cert(
            options.external_cert_files, options._ca_subject)
    elif options.external_ca:
        if cainstance.is_step_one_done():
            raise ScriptError(
                "CA is already installed.\nRun the installer with "
                "--external-cert-file.")
        if os.path.isfile(paths.ROOT_IPA_CSR):
            raise ScriptError(
                "CA CSR file %s already exists.\nIn order to continue "
                "remove the file and run the installer again." %
                paths.ROOT_IPA_CSR)

        if not options.external_ca_type:
            options.external_ca_type = x509.ExternalCAType.GENERIC.value

        if options.external_ca_profile is not None:
            # check that profile is valid for the external ca type
            if options.external_ca_type \
                    not in options.external_ca_profile.valid_for:
                raise ScriptError(
                    "External CA profile specification '{}' "
                    "cannot be used with external CA type '{}'.".format(
                        options.external_ca_profile.unparsed_input,
                        options.external_ca_type))

    if not options.external_cert_files:
        if not cainstance.check_ports():
            print("IPA requires ports 8080 and 8443 for PKI, but one or more "
                  "are currently in use.")
            raise ScriptError("Aborting installation")

    if standalone:
        dirname = dsinstance.config_dirname(
            ipaldap.realm_to_serverid(realm_name))
        cadb = certs.CertDB(realm_name,
                            nssdir=paths.PKI_TOMCAT_ALIAS_DIR,
                            subject_base=options._subject_base)
        dsdb = certs.CertDB(realm_name,
                            nssdir=dirname,
                            subject_base=options._subject_base)

        # Check that we can add our CA cert to DS and PKI NSS databases
        for db in (cadb, dsdb):
            if not db.exists():
                continue
            for nickname, _trust_flags in db.list_certs():
                if nickname == certdb.get_ca_nickname(realm_name):
                    raise ScriptError(
                        "Certificate with nickname %s is present in %s, "
                        "cannot continue." % (nickname, db.secdir))

                cert = db.get_cert_from_db(nickname)
                if not cert:
                    continue
                subject = DN(cert.subject)
                if subject == DN(options._ca_subject):
                    raise ScriptError(
                        "Certificate with subject %s is present in %s, "
                        "cannot continue." % (subject, db.secdir))
Esempio n. 22
0
def uninstall(installer):
    fstore = installer._fstore
    sstore = installer._sstore

    rv = 0

    # further steps assumes that temporary directories exists so rather
    # ensure they are created
    tasks.create_tmpfiles_dirs()

    print("Shutting down all IPA services")
    try:
        services.knownservices.ipa.stop()
    except Exception:
        # Fallback to direct ipactl stop only if system command fails
        try:
            run([paths.IPACTL, "stop"], raiseonerr=False)
        except Exception:
            pass

    ntpinstance.NTPInstance(fstore).uninstall()

    kra.uninstall()

    ca.uninstall()

    dns.uninstall()

    httpinstance.HTTPInstance(fstore).uninstall()
    krbinstance.KrbInstance(fstore).uninstall()
    dsinstance.DsInstance(fstore=fstore).uninstall()
    if _server_trust_ad_installed:
        adtrustinstance.ADTRUSTInstance(fstore).uninstall()
    custodiainstance.CustodiaInstance().uninstall()
    otpdinstance.OtpdInstance().uninstall()
    tasks.restore_hostname(fstore, sstore)
    fstore.restore_all_files()
    try:
        os.remove(paths.ROOT_IPA_CACHE)
    except Exception:
        pass
    try:
        os.remove(paths.ROOT_IPA_CSR)
    except Exception:
        pass

    # ipa-client-install removes /etc/ipa/default.conf

    sstore._load()

    ipaclient.install.ntpconf.restore_forced_ntpd(sstore)

    # Clean up group_exists (unused since IPA 2.2, not being set since 4.1)
    sstore.restore_state("install", "group_exists")

    services.knownservices.ipa.disable()

    # remove upgrade state file
    sysupgrade.remove_upgrade_file()

    if fstore.has_files():
        root_logger.error('Some files have not been restored, see '
                          '%s/sysrestore.index' % SYSRESTORE_DIR_PATH)
    has_state = False
    for module in IPA_MODULES:  # from installutils
        if sstore.has_state(module):
            root_logger.error('Some installation state for %s has not been '
                              'restored, see %s/sysrestore.state' %
                              (module, SYSRESTORE_DIR_PATH))
            has_state = True
            rv = 1

    if has_state:
        root_logger.error('Some installation state has not been restored.\n'
                          'This may cause re-installation to fail.\n'
                          'It should be safe to remove %s/sysrestore.state '
                          'but it may\n'
                          'mean your system hasn\'t be restored to its '
                          'pre-installation state.' % SYSRESTORE_DIR_PATH)

    # Note that this name will be wrong after the first uninstall.
    dirname = dsinstance.config_dirname(
        installutils.realm_to_serverid(api.env.realm))
    dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, paths.HTTPD_ALIAS_DIR]
    ids = certmonger.check_state(dirs)
    if ids:
        root_logger.error('Some certificates may still be tracked by '
                          'certmonger.\n'
                          'This will cause re-installation to fail.\n'
                          'Start the certmonger service and list the '
                          'certificates being tracked\n'
                          ' # getcert list\n'
                          'These may be untracked by executing\n'
                          ' # getcert stop-tracking -i <request_id>\n'
                          'for each id in: %s' % ', '.join(ids))

    # Remove the cert renewal lock file
    try:
        os.remove(paths.IPA_RENEWAL_LOCK)
    except OSError as e:
        if e.errno != errno.ENOENT:
            root_logger.warning("Failed to remove file %s: %s",
                                paths.IPA_RENEWAL_LOCK, e)

    print("Removing IPA client configuration")
    try:
        result = run([
            paths.IPA_CLIENT_INSTALL, "--on-master", "--unattended",
            "--uninstall"
        ],
                     raiseonerr=False,
                     redirect_output=True)
        if result.returncode not in [0, 2]:
            raise RuntimeError("Failed to configure the client")
    except Exception:
        rv = 1
        print("Uninstall of client side components failed!")

    sys.exit(rv)
Esempio n. 23
0
def install_step_1(standalone, replica_config, options):
    realm_name = options.realm_name
    domain_name = options.domain_name
    dm_password = options.dm_password
    host_name = options.host_name
    subject_base = options.subject

    basedn = ipautil.realm_to_suffix(realm_name)

    dogtag_constants = dogtag.install_constants

    ca = cainstance.CAInstance(realm_name, certs.NSS_DIR,
        dogtag_constants=dogtag_constants)

    if standalone:
        ca.stop(ca.dogtag_constants.PKI_INSTANCE_NAME)

    # We need to ldap_enable the CA now that DS is up and running
    ca.ldap_enable('CA', host_name, dm_password, basedn, ['caRenewalMaster'])

    # This is done within stopped_service context, which restarts CA
    ca.enable_client_auth_to_db(dogtag_constants.CS_CFG_PATH)

    if standalone and replica_config is None:
        serverid = installutils.realm_to_serverid(realm_name)
        dirname = dsinstance.config_dirname(serverid)

        # 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)
        trust_flags = dict(reversed(cadb.list_certs()))
        trust_chain = cadb.find_root_cert('ipaCert')[:-1]
        for nickname in trust_chain[:-1]:
            cert = cadb.get_cert_from_db(nickname, pem=False)
            dsdb.add_cert(cert, nickname, trust_flags[nickname])
            certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn,
                                      cert, nickname, trust_flags[nickname])

        nickname = trust_chain[-1]
        cert = cadb.get_cert_from_db(nickname, pem=False)
        dsdb.add_cert(cert, nickname, trust_flags[nickname])
        certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn,
                                  cert, nickname, trust_flags[nickname],
                                  config_ipa=True, config_compat=True)


        api.Backend.ldap2.disconnect()

        # Restart DS
        services.knownservices.dirsrv.restart(serverid)

        api.Backend.ldap2.connect(bind_dn=DN(('cn', 'Directory Manager')),
                                  bind_pw=dm_password)

        # Store DS CA cert in Dogtag NSS database
        dogtagdb = certs.CertDB(realm_name, nssdir=dogtag_constants.ALIAS_DIR)
        trust_flags = dict(reversed(dsdb.list_certs()))
        server_certs = dsdb.find_server_certs()
        trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1]
        nickname = trust_chain[-1]
        cert = dsdb.get_cert_from_db(nickname)
        dogtagdb.add_cert(cert, nickname, trust_flags[nickname])

    if standalone:
        ca.start(ca.dogtag_constants.PKI_INSTANCE_NAME)

        # Update config file
        try:
            parser = RawConfigParser()
            parser.read(paths.IPA_DEFAULT_CONF)
            parser.set('global', 'enable_ra', 'True')
            parser.set('global', 'ra_plugin', 'dogtag')
            parser.set('global', 'dogtag_version',
                       str(dogtag_constants.DOGTAG_VERSION))
            with open(paths.IPA_DEFAULT_CONF, 'w') as f:
                parser.write(f)
        except IOError as e:
            print "Failed to update /etc/ipa/default.conf"
            root_logger.error(str(e))
            sys.exit(1)

        # We need to restart apache as we drop a new config file in there
        services.knownservices.httpd.restart(capture_output=True)

        # Install CA DNS records
        if bindinstance.dns_container_exists(host_name, basedn, dm_password):
            bind = bindinstance.BindInstance(dm_password=dm_password)
            bind.add_ipa_ca_dns_records(host_name, domain_name)
Esempio n. 24
0
    def check_permissions(self):

        # TODO: see if this is something unique about my install
        if version.NUM_VERSION < 40700:
            dirsrv_group = 'root'
        else:
            dirsrv_group = 'dirsrv'

        databases = [
            {
                'dirname':
                dsinstance.config_dirname(self.serverid),
                'files': [
                    (KEYDB, 'dirsrv', 'root', '0640'),
                    (CERTDB, 'dirsrv', 'root', '0640'),
                    (SECDB, 'dirsrv', dirsrv_group, '0640'),
                ]
            },
            {
                'dirname':
                paths.VAR_LIB_IPA,
                'files': [
                    ('ra-agent.key', 'root', 'ipaapi', '0440'),
                    ('ra-agent.pem', 'root', 'ipaapi', '0440'),
                ]
            },
        ]

        if self.ca.is_configured():
            databases.append(
                {
                    'dirname':
                    paths.PKI_TOMCAT_ALIAS_DIR,
                    'files': [
                        (KEYDB, 'pkiuser', 'pkiuser', '0600'),
                        (CERTDB, 'pkiuser', 'pkiuser', '0600'),
                        (SECDB, 'pkiuser', 'pkiuser', '0600'),
                    ]
                }, )

        if version.NUM_VERSION < 40700:
            databases.append(
                {
                    'dirname':
                    paths.HTTPD_ALIAS_DIR,
                    'files': [
                        # file, owner, group, perms
                        (KEYDB, 'root', 'apache', '0640'),
                        (CERTDB, 'root', 'apache', '0640'),
                        (SECDB, 'root', 'apache', '0640'),
                    ]
                }, )

        for db in databases:
            for (file, owner, group, mode) in db['files']:
                path = os.path.join(db['dirname'], file)
                stat = os.stat(path)
                fmode = str(oct(stat.st_mode)[-4:])
                logger.debug(path)
                if mode != fmode:
                    self.failure('Permissions of %s are %s and should '
                                 'be %s' % (path, fmode, mode))
                fowner = pwd.getpwnam(owner)
                if fowner.pw_uid != stat.st_uid:
                    actual = pwd.getpwuid(stat.st_uid)
                    self.failure('Ownership of %s is %s and should '
                                 'be %s' % (path, actual.pw_name, owner))
                fgroup = grp.getgrnam(group)
                if fgroup.gr_gid != stat.st_gid:
                    actual = grp.getgrgid(stat.st_gid)
                    self.failure('Group of %s is %s and should '
                                 'be %s' % (path, actual.gr_name, group))
Esempio n. 25
0
def get_expected_requests(ca, ds, serverid):
    """Provide the expected certmonger tracking request data

       This list is based in part on certificate_renewal_update() in
       ipaserver/install/server/upgrade.py and various
       start_tracking_certificates() methods in *instance.py.

       The list is filtered depending on whether a CA is running
       and the certificates have been issued by IPA.

      :param ca: the CAInstance
      :param ds: the DSInstance
      :param serverid: the DS serverid name
    """
    template = paths.CERTMONGER_COMMAND_TEMPLATE

    if api.Command.ca_is_enabled()['result']:
        requests = [
            {
                'cert-file': paths.RA_AGENT_PEM,
                'key-file': paths.RA_AGENT_KEY,
                'ca-name': 'dogtag-ipa-ca-renew-agent',
                'cert-presave-command': template % 'renew_ra_cert_pre',
                'cert-postsave-command': template % 'renew_ra_cert',
            },
        ]
    else:
        requests = []

    ca_requests = [
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'auditSigningCert cert-pki-ca',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "auditSigningCert cert-pki-ca"'),
        },
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'ocspSigningCert cert-pki-ca',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "ocspSigningCert cert-pki-ca"'),
        },
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'subsystemCert cert-pki-ca',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "subsystemCert cert-pki-ca"'),
        },
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'caSigningCert cert-pki-ca',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "caSigningCert cert-pki-ca"'),
            'template-profile':
            None,
        },
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'Server-Cert cert-pki-ca',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "Server-Cert cert-pki-ca"'),
        },
    ]

    kra_requests = [
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'auditSigningCert cert-pki-kra',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "auditSigningCert cert-pki-kra"'),
        },
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'transportCert cert-pki-kra',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "transportCert cert-pki-kra"'),
        },
        {
            'cert-database':
            paths.PKI_TOMCAT_ALIAS_DIR,
            'cert-nickname':
            'storageCert cert-pki-kra',
            'ca-name':
            'dogtag-ipa-ca-renew-agent',
            'cert-presave-command':
            template % 'stop_pkicad',
            'cert-postsave-command':
            (template % 'renew_ca_cert "storageCert cert-pki-kra"'),
        },
    ]

    if ca.is_configured():
        db = certs.CertDB(api.env.realm, paths.PKI_TOMCAT_ALIAS_DIR)
        for nickname, _trust_flags in db.list_certs():
            if nickname.startswith('caSigningCert cert-pki-ca '):
                requests.append({
                    'cert-database':
                    paths.PKI_TOMCAT_ALIAS_DIR,
                    'cert-nickname':
                    nickname,
                    'ca-name':
                    'dogtag-ipa-ca-renew-agent',
                    'cert-presave-command':
                    template % 'stop_pkicad',
                    'cert-postsave-command':
                    (template % ('renew_ca_cert "%s"' % nickname)),
                    'template-profile':
                    'caCACert',
                })
        requests += ca_requests
        kra = krainstance.KRAInstance(api.env.realm)
        if kra.is_installed():
            requests += kra_requests
    else:
        logger.debug('CA is not configured, skipping CA tracking')

    cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
    issued = is_ipa_issued_cert(api, cert)
    if issued is None:
        logger.debug('Unable to determine if \'%s\' was issued by IPA '
                     'because no LDAP connection, assuming yes.')
    if issued or issued is None:
        requests.append({
            'cert-file': paths.HTTPD_CERT_FILE,
            'key-file': paths.HTTPD_KEY_FILE,
            'ca-name': 'IPA',
            'cert-postsave-command': template % 'restart_httpd',
        })
    else:
        logger.debug(
            'HTTP cert not issued by IPA, \'%s\', skip tracking '
            'check', DN(cert.issuer))

    # Check the ldap server cert if issued by IPA
    ds_nickname = ds.get_server_cert_nickname(serverid)
    ds_db_dirname = dsinstance.config_dirname(serverid)
    ds_db = certs.CertDB(api.env.realm, nssdir=ds_db_dirname)
    connected = api.Backend.ldap2.isconnected()
    if not connected:
        logger.debug('Unable to determine if \'%s\' was issued by IPA '
                     'because no LDAP connection, assuming yes.')
    if not connected or ds_db.is_ipa_issued_cert(api, ds_nickname):
        requests.append({
            'cert-database':
            ds_db_dirname[:-1],
            'cert-nickname':
            ds_nickname,
            'ca-name':
            'IPA',
            'cert-postsave-command':
            '%s %s' % (template % 'restart_dirsrv', serverid),
        })
    else:
        logger.debug(
            'DS cert is not issued by IPA, \'%s\', skip tracking '
            'check', DN(cert.issuer))

    # Check if pkinit is enabled
    if os.path.exists(paths.KDC_CERT):
        pkinit_request_ca = krbinstance.get_pkinit_request_ca()
        cert = x509.load_certificate_from_file(paths.KDC_CERT)
        requests.append({
            'cert-file': paths.KDC_CERT,
            'key-file': paths.KDC_KEY,
            'ca-name': pkinit_request_ca,
            'cert-postsave-command': template % 'renew_kdc_cert',
        })
    else:
        logger.debug('No KDC pkinit certificate')

    return requests
Esempio n. 26
0
    def execute(self, **options):
        serverid = realm_to_serverid(self.api.env.realm)
        db = certs.CertDB(self.api.env.realm,
                          nssdir=dsinstance.config_dirname(serverid))
        ca_cert = None

        ca_enabled = self.api.Command.ca_is_enabled()['result']
        if ca_enabled:
            ca_nickname = certdb.get_ca_nickname(self.api.env.realm)
            ca_subject = certstore.get_ca_subject(self.api.Backend.ldap2,
                                                  self.api.env.container_ca,
                                                  self.api.env.basedn)
        else:
            ca_nickname = None
            server_certs = db.find_server_certs()
            if server_certs:
                ca_chain = db.find_root_cert(server_certs[0][0])[:-1]
                if ca_chain:
                    ca_nickname = ca_chain[-1]

        ldap = self.api.Backend.ldap2

        for nickname, trust_flags in db.list_certs():
            if trust_flags.has_key:
                continue
            cert = db.get_cert_from_db(nickname)
            subject = cert.subject
            if ca_enabled and subject == ca_subject:
                # When ca is enabled, we can have the IPA CA cert stored
                # in the nss db with a different nickname (for instance
                # when the server was installed with --subject to
                # customize the CA cert subject), but it must always be
                # stored in LDAP with the DN cn=$DOMAIN IPA CA
                # This is why we check the subject instead of the nickname here
                nickname = ca_nickname
                trust_flags = certdb.IPA_CA_TRUST_FLAGS
            trust, _ca, eku = certstore.trust_flags_to_key_policy(trust_flags)

            dn = DN(('cn', nickname), ('cn', 'certificates'), ('cn', 'ipa'),
                    ('cn', 'etc'), self.api.env.basedn)
            entry = ldap.make_entry(dn)

            try:
                certstore.init_ca_entry(entry, cert, nickname, trust, eku)
            except Exception as e:
                logger.warning("Failed to create entry for %s: %s", nickname,
                               e)
                continue
            if nickname == ca_nickname:
                ca_cert = cert
                config = entry.setdefault('ipaConfigString', [])
                if ca_enabled:
                    config.append('ipaCa')
                config.append('ipaCa')

            try:
                ldap.add_entry(entry)
            except errors.DuplicateEntry:
                if nickname == ca_nickname and ca_enabled:
                    try:
                        ldap.update_entry(entry)
                    except errors.EmptyModlist:
                        pass

        if ca_cert:
            dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn', 'etc'),
                    self.api.env.basedn)
            try:
                entry = ldap.get_entry(dn)
            except errors.NotFound:
                entry = ldap.make_entry(dn)
                entry['objectclass'] = ['nsContainer', 'pkiCA']
                entry.single_value['cn'] = 'CAcert'
                entry.single_value['cACertificate;binary'] = ca_cert
                ldap.add_entry(entry)
            else:
                force_write = False
                try:
                    _cert_bin = entry['cACertificate;binary']
                except ValueError:
                    # BZ 1644874
                    # sometimes the cert is badly stored, twice encoded
                    # force write to fix the value
                    logger.debug(
                        'Fixing the value of cACertificate;binary '
                        'in entry %s', entry.dn)
                    force_write = True

                if force_write or b'' in entry['cACertificate;binary']:
                    entry.single_value['cACertificate;binary'] = ca_cert
                    ldap.update_entry(entry)

        return False, []
Esempio n. 27
0
def uninstall(installer):
    fstore = installer._fstore
    sstore = installer._sstore

    rv = 0

    # Uninstall the KRA prior to shutting the services down so it
    # can un-register with the CA.
    kra.uninstall()

    print("Shutting down all IPA services")
    try:
        services.knownservices.ipa.stop()
    except Exception:
        # Fallback to direct ipactl stop only if system command fails
        try:
            run([paths.IPACTL, "stop"], raiseonerr=False)
        except Exception:
            pass

    restore_time_sync(sstore, fstore)

    ca.uninstall()

    dns.uninstall()

    httpinstance.HTTPInstance(fstore).uninstall()
    krbinstance.KrbInstance(fstore).uninstall()
    dsinstance.DsInstance(fstore=fstore).uninstall()
    adtrustinstance.ADTRUSTInstance(fstore).uninstall()
    # realm isn't used, but IPAKEMKeys parses /etc/ipa/default.conf
    # otherwise, see https://pagure.io/freeipa/issue/7474 .
    custodiainstance.CustodiaInstance(realm='REALM.INVALID').uninstall()
    otpdinstance.OtpdInstance().uninstall()
    tasks.restore_hostname(fstore, sstore)
    tasks.restore_pkcs11_modules(fstore)
    fstore.restore_all_files()
    try:
        os.remove(paths.ROOT_IPA_CACHE)
    except Exception:
        pass
    try:
        os.remove(paths.ROOT_IPA_CSR)
    except Exception:
        pass

    # ipa-client-install removes /etc/ipa/default.conf

    sstore._load()

    timeconf.restore_forced_timeservices(sstore)

    # Clean up group_exists (unused since IPA 2.2, not being set since 4.1)
    sstore.restore_state("install", "group_exists")

    services.knownservices.ipa.disable()

    # remove upgrade state file
    sysupgrade.remove_upgrade_file()

    if fstore.has_files():
        logger.error('Some files have not been restored, see '
                     '%s/sysrestore.index', SYSRESTORE_DIR_PATH)
    sstore.delete_state('installation', 'complete')
    has_state = False
    for module in IPA_MODULES:  # from installutils
        if sstore.has_state(module):
            logger.error('Some installation state for %s has not been '
                         'restored, see %s/sysrestore.state',
                         module, SYSRESTORE_DIR_PATH)
            has_state = True
            rv = 1

    if has_state:
        logger.error('Some installation state has not been restored.\n'
                     'This may cause re-installation to fail.\n'
                     'It should be safe to remove %s/sysrestore.state '
                     'but it may\n'
                     'mean your system hasn\'t be restored to its '
                     'pre-installation state.', SYSRESTORE_DIR_PATH)
    else:
        # sysrestore.state has no state left, remove it
        sysrestore = os.path.join(SYSRESTORE_DIR_PATH, 'sysrestore.state')
        ipautil.remove_file(sysrestore)

    # Note that this name will be wrong after the first uninstall.
    dirname = dsinstance.config_dirname(
        ipaldap.realm_to_serverid(api.env.realm))
    dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, paths.HTTPD_ALIAS_DIR]
    ids = certmonger.check_state(dirs)
    if ids:
        logger.error('Some certificates may still be tracked by '
                     'certmonger.\n'
                     'This will cause re-installation to fail.\n'
                     'Start the certmonger service and list the '
                     'certificates being tracked\n'
                     ' # getcert list\n'
                     'These may be untracked by executing\n'
                     ' # getcert stop-tracking -i <request_id>\n'
                     'for each id in: %s', ', '.join(ids))

    # Remove the cert renewal lock file
    try:
        os.remove(paths.IPA_RENEWAL_LOCK)
    except OSError as e:
        if e.errno != errno.ENOENT:
            logger.warning("Failed to remove file %s: %s",
                           paths.IPA_RENEWAL_LOCK, e)

    print("Removing IPA client configuration")
    try:
        result = run([paths.IPA_CLIENT_INSTALL, "--on-master",
                      "--unattended", "--uninstall"],
                     raiseonerr=False, redirect_output=True)
        if result.returncode not in [0, 2]:
            raise RuntimeError("Failed to configure the client")
    except Exception:
        rv = 1
        print("Uninstall of client side components failed!")

    sys.exit(rv)
Esempio n. 28
0
def install_step_1(standalone, replica_config, options, custodia):
    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
    basedn = ipautil.realm_to_suffix(realm_name)

    ca = cainstance.CAInstance(
        realm=realm_name, host_name=host_name, custodia=custodia
    )

    ca.stop('pki-tomcat')

    # This is done within stopped_service context, which restarts CA
    ca.enable_client_auth_to_db()

    # Lightweight CA key retrieval is configured in step 1 instead
    # of CAInstance.configure_instance (which is invoked from step
    # 0) because kadmin_addprinc fails until krb5.conf is installed
    # by krb.create_instance.
    #
    ca.setup_lightweight_ca_key_retrieval()

    serverid = ipaldap.realm_to_serverid(realm_name)

    if standalone and replica_config is None:
        dirname = dsinstance.config_dirname(serverid)

        # Store the new IPA CA cert chain in DS NSS database and LDAP
        cadb = certs.CertDB(
            realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR,
            subject_base=subject_base)
        dsdb = certs.CertDB(
            realm_name, nssdir=dirname, subject_base=subject_base)
        cacert = cadb.get_cert_from_db('caSigningCert cert-pki-ca')
        nickname = certdb.get_ca_nickname(realm_name)
        trust_flags = certdb.IPA_CA_TRUST_FLAGS
        dsdb.add_cert(cacert, nickname, trust_flags)
        certstore.put_ca_cert_nss(api.Backend.ldap2, api.env.basedn,
                                  cacert, nickname, trust_flags,
                                  config_ipa=True, config_compat=True)

        # Store DS CA cert in Dogtag NSS database
        trust_flags = dict(reversed(dsdb.list_certs()))
        server_certs = dsdb.find_server_certs()
        trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1]
        nickname = trust_chain[-1]
        cert = dsdb.get_cert_from_db(nickname)
        cadb.add_cert(cert, nickname, trust_flags[nickname])

    installutils.restart_dirsrv()

    ca.start('pki-tomcat')

    if standalone or replica_config is not None:
        # We need to restart apache as we drop a new config file in there
        services.knownservices.httpd.restart(capture_output=True)

    if standalone:
        # Install CA DNS records
        if bindinstance.dns_container_exists(basedn):
            bind = bindinstance.BindInstance()
            bind.update_system_records()
Esempio n. 29
0
def install_check(standalone, replica_config, options):
    global external_cert_file
    global external_ca_file

    realm_name = options.realm_name
    host_name = options.host_name

    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 = str(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':
            raise ScriptError('A selfsign CA can not be added')

        if standalone and not options.skip_conncheck:
            principal = options.principal
            replica_conn_check(
                replica_config.ca_host_name, host_name, realm_name, True,
                replica_config.ca_ds_port, options.admin_password,
                principal=principal, ca_cert_file=options.ca_cert_file)

        if options.skip_schema_check:
            logger.info("Skipping CA DS schema check")

        return

    if standalone:
        if api.Command.ca_is_enabled()['result']:
            raise ScriptError(
                "One or more CA masters are already present in IPA realm "
                "'%s'.\nIf you wish to replicate CA to this host, please "
                "re-run 'ipa-ca-install'\nwith a replica file generated on "
                "an existing CA master as argument." % realm_name
            )

    if options.external_cert_files:
        if not cainstance.is_step_one_done():
            # This can happen if someone passes external_ca_file without
            # already having done the first stage of the CA install.
            raise ScriptError(
                  "CA is not installed yet. To install with an external CA "
                  "is a two-stage process.\nFirst run the installer with "
                  "--external-ca.")

        external_cert_file, external_ca_file = installutils.load_external_cert(
            options.external_cert_files, options._ca_subject)
    elif options.external_ca:
        if cainstance.is_step_one_done():
            raise ScriptError(
                "CA is already installed.\nRun the installer with "
                "--external-cert-file.")
        if os.path.isfile(paths.ROOT_IPA_CSR):
            raise ScriptError(
                "CA CSR file %s already exists.\nIn order to continue "
                "remove the file and run the installer again." %
                paths.ROOT_IPA_CSR)

        if not options.external_ca_type:
            options.external_ca_type = \
                cainstance.ExternalCAType.GENERIC.value

        if options.external_ca_profile is not None:
            # check that profile is valid for the external ca type
            if options.external_ca_type \
                    not in options.external_ca_profile.valid_for:
                raise ScriptError(
                    "External CA profile specification '{}' "
                    "cannot be used with external CA type '{}'."
                    .format(
                        options.external_ca_profile.unparsed_input,
                        options.external_ca_type)
                    )

    if not options.external_cert_files:
        if not cainstance.check_ports():
            print(
                "IPA requires ports 8080 and 8443 for PKI, but one or more "
                "are currently in use."
            )
            raise ScriptError("Aborting installation")

    if standalone:
        dirname = dsinstance.config_dirname(
            ipaldap.realm_to_serverid(realm_name))
        cadb = certs.CertDB(realm_name, nssdir=paths.PKI_TOMCAT_ALIAS_DIR,
                            subject_base=options._subject_base)
        dsdb = certs.CertDB(
            realm_name, nssdir=dirname, subject_base=options._subject_base)

        # Check that we can add our CA cert to DS and PKI NSS databases
        for db in (cadb, dsdb):
            if not db.exists():
                continue
            for nickname, _trust_flags in db.list_certs():
                if nickname == certdb.get_ca_nickname(realm_name):
                    raise ScriptError(
                        "Certificate with nickname %s is present in %s, "
                        "cannot continue." % (nickname, db.secdir))

                cert = db.get_cert_from_db(nickname)
                if not cert:
                    continue
                subject = DN(cert.subject)
                if subject == DN(options._ca_subject):
                    raise ScriptError(
                        "Certificate with subject %s is present in %s, "
                        "cannot continue." % (subject, db.secdir))
Esempio n. 30
0
            root_logger.error('Some installation state for %s has not been '
                              'restored, see %s/sysrestore.state' %
                              (module, SYSRESTORE_DIR_PATH))
            has_state = True
            rv = 1

    if has_state:
        root_logger.error('Some installation state has not been restored.\n'
                          'This may cause re-installation to fail.\n'
                          'It should be safe to remove %s/sysrestore.state '
                          'but it may\n'
                          'mean your system hasn\'t be restored to its '
                          'pre-installation state.' % SYSRESTORE_DIR_PATH)

    # Note that this name will be wrong after the first uninstall.
    dirname = dsinstance.config_dirname(
        installutils.realm_to_serverid(api.env.realm))
    dirs = [dirname, dogtag_constants.ALIAS_DIR, certs.NSS_DIR]
    ids = certmonger.check_state(dirs)
    if ids:
        root_logger.error('Some certificates may still be tracked by '
                          'certmonger.\n'
                          'This will cause re-installation to fail.\n'
                          'Start the certmonger service and list the '
                          'certificates being tracked\n'
                          ' # getcert list\n'
                          'These may be untracked by executing\n'
                          ' # getcert stop-tracking -i <request_id>\n'
                          'for each id in: %s' % ', '.join(ids))

    # Use private ccache
    destroy_private_ccache()
Esempio n. 31
0
def install_check(standalone, replica_config, options):
    global external_cert_file
    global external_ca_file

    realm_name = options.realm_name
    host_name = options.host_name
    subject_base = options.subject

    if replica_config is not None:
        if standalone and api.env.ra_plugin == 'selfsign':
            sys.exit('A selfsign CA can not be added')

        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
            replica_conn_check(
                replica_config.master_host_name, host_name, realm_name, True,
                replica_config.ca_ds_port, options.admin_password,
                principal=principal, ca_cert_file=options.ca_cert_file)

        if options.skip_schema_check or options.promote:
            root_logger.info("Skipping CA DS schema check")
        else:
            cainstance.replica_ca_install_check(replica_config)

        return

    if standalone:
        if api.Command.ca_is_enabled()['result']:
            sys.exit(
                "One or more CA masters are already present in IPA realm "
                "'%s'.\nIf you wish to replicate CA to this host, please "
                "re-run 'ipa-ca-install'\nwith a replica file generated on "
                "an existing CA master as argument." % realm_name
            )

    if options.external_cert_files:
        if not cainstance.is_step_one_done():
            # This can happen if someone passes external_ca_file without
            # already having done the first stage of the CA install.
            print("CA is not installed yet. To install with an external CA "
                  "is a two-stage process.\nFirst run the installer with "
                  "--external-ca.")
            sys.exit(1)

        external_cert_file, external_ca_file = installutils.load_external_cert(
            options.external_cert_files, options.subject)
    elif options.external_ca:
        if cainstance.is_step_one_done():
            print("CA is already installed.\nRun the installer with "
                  "--external-cert-file.")
            sys.exit(1)
        if ipautil.file_exists(paths.ROOT_IPA_CSR):
            print(("CA CSR file %s already exists.\nIn order to continue "
                  "remove the file and run the installer again." %
                  paths.ROOT_IPA_CSR))
            sys.exit(1)

    if not options.external_cert_files:
        if not cainstance.check_port():
            print("IPA requires port 8443 for PKI but it is currently in use.")
            sys.exit("Aborting installation")

    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)

        for db in (cadb, dsdb):
            for nickname, trust_flags in db.list_certs():
                if nickname in (certdb.get_ca_nickname(realm_name),
                                'ipaCert',
                                'Signing-Cert'):
                    print(("Certificate with nickname %s is present in %s, "
                           "cannot continue." % (nickname, db.secdir)))
                    sys.exit(1)

                cert = db.get_cert_from_db(nickname)
                if not cert:
                    continue
                subject = DN(str(x509.get_subject(cert)))
                if subject in (DN('CN=Certificate Authority', subject_base),
                               DN('CN=IPA RA', subject_base),
                               DN('CN=Object Signing Cert', subject_base)):
                    print(("Certificate with subject %s is present in %s, "
                           "cannot continue." % (subject, db.secdir)))
                    sys.exit(1)
Esempio n. 32
0
def install_step_1(standalone, replica_config, options, custodia):
    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
    basedn = ipautil.realm_to_suffix(realm_name)

    ca = cainstance.CAInstance(realm=realm_name,
                               host_name=host_name,
                               custodia=custodia)

    ca.stop('pki-tomcat')

    # This is done within stopped_service context, which restarts CA
    ca.enable_client_auth_to_db()

    # Lightweight CA key retrieval is configured in step 1 instead
    # of CAInstance.configure_instance (which is invoked from step
    # 0) because kadmin_addprinc fails until krb5.conf is installed
    # by krb.create_instance.
    #
    ca.setup_lightweight_ca_key_retrieval()

    serverid = ipaldap.realm_to_serverid(realm_name)

    if standalone and replica_config is None:
        dirname = dsinstance.config_dirname(serverid)

        # Store the new IPA CA cert chain in DS NSS database and LDAP
        cadb = certs.CertDB(realm_name,
                            nssdir=paths.PKI_TOMCAT_ALIAS_DIR,
                            subject_base=subject_base)
        dsdb = certs.CertDB(realm_name,
                            nssdir=dirname,
                            subject_base=subject_base)
        cacert = cadb.get_cert_from_db('caSigningCert cert-pki-ca')
        nickname = certdb.get_ca_nickname(realm_name)
        trust_flags = certdb.IPA_CA_TRUST_FLAGS
        dsdb.add_cert(cacert, nickname, trust_flags)
        certstore.put_ca_cert_nss(api.Backend.ldap2,
                                  api.env.basedn,
                                  cacert,
                                  nickname,
                                  trust_flags,
                                  config_ipa=True,
                                  config_compat=True)

        # Store DS CA cert in Dogtag NSS database
        trust_flags = dict(reversed(dsdb.list_certs()))
        server_certs = dsdb.find_server_certs()
        trust_chain = dsdb.find_root_cert(server_certs[0][0])[:-1]
        nickname = trust_chain[-1]
        cert = dsdb.get_cert_from_db(nickname)
        cadb.add_cert(cert, nickname, trust_flags[nickname])

    installutils.restart_dirsrv()

    ca.start('pki-tomcat')

    if standalone or replica_config is not None:
        # We need to restart apache as we drop a new config file in there
        services.knownservices.httpd.restart(capture_output=True)

    if standalone:
        # Install CA DNS records
        if bindinstance.dns_container_exists(basedn):
            bind = bindinstance.BindInstance()
            bind.update_system_records()
Esempio n. 33
0
    def validate_certs(self):
        """Use certutil -V to validate the certs we can"""
        ca_pw_name = None

        if self.ca.is_configured():
            ca_passwd = None
            token = 'internal'
            with open(paths.PKI_TOMCAT_PASSWORD_CONF, 'r') as f:
                for line in f:
                    (tok, pin) = line.split('=', 1)
                    if token == tok:
                        ca_passwd = pin.strip()
                        break
                else:
                    self.failure("The password to the 'internal' "
                                 "token of the Dogtag certificate "
                                 "store was not found.")
            with tempfile.NamedTemporaryFile(mode='w',
                                             delete=False) as ca_pw_file:
                ca_pw_file.write(ca_passwd)
                ca_pw_name = ca_pw_file.name

        try:
            validate = [
                (
                    dsinstance.config_dirname(self.serverid),
                    self.ds.get_server_cert_nickname(self.serverid),
                    os.path.join(dsinstance.config_dirname(self.serverid),
                                 'pwdfile.txt'),
                ),
            ]

            if self.ca.is_configured():
                validate.append((
                    paths.PKI_TOMCAT_ALIAS_DIR,
                    'Server-Cert cert-pki-ca',
                    ca_pw_name,
                ), )

            if version.NUM_VERSION < 40700:
                validate.append((
                    paths.HTTPD_ALIAS_DIR,
                    self.http.get_mod_nss_nickname(),
                    os.path.join(paths.HTTPD_ALIAS_DIR, 'pwdfile.txt'),
                ), )

            for (dbdir, nickname, pinfile) in validate:
                args = [paths.CERTUTIL, "-V", "-u", "V", "-e"]
                args.extend(["-d", dbdir])
                args.extend(["-n", nickname])
                args.extend(["-f", pinfile])

                try:
                    result = ipautil.run(args)
                except ipautil.CalledProcessError as e:
                    self.failure('Validation of %s in %s failed: %s' %
                                 (nickname, dbdir, e))
                else:
                    if 'certificate is valid' not in \
                            result.raw_output.decode('utf-8'):
                        self.failure('Validation of %s in %s failed: '
                                     '%s %s' %
                                     (nickname, dbdir, result.raw_output,
                                      result.error_log))
        finally:
            if ca_pw_name:
                installutils.remove_file(ca_pw_name)

        if version.NUM_VERSION >= 40700:
            self.validate_openssl(paths.HTTPD_CERT_FILE)

        self.validate_openssl(paths.RA_AGENT_PEM)
Esempio n. 34
0
def uninstall(installer):
    fstore = installer._fstore
    sstore = installer._sstore

    rv = 0

    print("Shutting down all IPA services")
    try:
        services.knownservices.ipa.stop()
    except Exception:
        # Fallback to direct ipactl stop only if system command fails
        try:
            run([paths.IPACTL, "stop"], raiseonerr=False)
        except Exception:
            pass

    ipaclient.install.client.restore_time_sync(sstore, fstore)

    kra.uninstall()

    ca.uninstall()

    dns.uninstall()

    httpinstance.HTTPInstance(fstore).uninstall()
    krbinstance.KrbInstance(fstore).uninstall()
    dsinstance.DsInstance(fstore=fstore).uninstall()
    if _server_trust_ad_installed:
        adtrustinstance.ADTRUSTInstance(fstore).uninstall()
    # realm isn't used, but IPAKEMKeys parses /etc/ipa/default.conf
    # otherwise, see https://pagure.io/freeipa/issue/7474 .
    custodiainstance.CustodiaInstance(realm='REALM.INVALID').uninstall()
    otpdinstance.OtpdInstance().uninstall()
    tasks.restore_hostname(fstore, sstore)
    fstore.restore_all_files()
    try:
        os.remove(paths.ROOT_IPA_CACHE)
    except Exception:
        pass
    try:
        os.remove(paths.ROOT_IPA_CSR)
    except Exception:
        pass

    # ipa-client-install removes /etc/ipa/default.conf

    sstore._load()

    ipaclient.install.timeconf.restore_forced_timeservices(sstore)

    # Clean up group_exists (unused since IPA 2.2, not being set since 4.1)
    sstore.restore_state("install", "group_exists")

    services.knownservices.ipa.disable()

    # remove upgrade state file
    sysupgrade.remove_upgrade_file()

    if fstore.has_files():
        logger.error('Some files have not been restored, see '
                     '%s/sysrestore.index', SYSRESTORE_DIR_PATH)
    has_state = False
    for module in IPA_MODULES:  # from installutils
        if sstore.has_state(module):
            logger.error('Some installation state for %s has not been '
                         'restored, see %s/sysrestore.state',
                         module, SYSRESTORE_DIR_PATH)
            has_state = True
            rv = 1

    if has_state:
        logger.error('Some installation state has not been restored.\n'
                     'This may cause re-installation to fail.\n'
                     'It should be safe to remove %s/sysrestore.state '
                     'but it may\n'
                     'mean your system hasn\'t be restored to its '
                     'pre-installation state.', SYSRESTORE_DIR_PATH)
    else:
        # sysrestore.state has no state left, remove it
        sysrestore = os.path.join(SYSRESTORE_DIR_PATH, 'sysrestore.state')
        installutils.remove_file(sysrestore)

    # Note that this name will be wrong after the first uninstall.
    dirname = dsinstance.config_dirname(
        ipaldap.realm_to_serverid(api.env.realm))
    dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, paths.HTTPD_ALIAS_DIR]
    ids = certmonger.check_state(dirs)
    if ids:
        logger.error('Some certificates may still be tracked by '
                     'certmonger.\n'
                     'This will cause re-installation to fail.\n'
                     'Start the certmonger service and list the '
                     'certificates being tracked\n'
                     ' # getcert list\n'
                     'These may be untracked by executing\n'
                     ' # getcert stop-tracking -i <request_id>\n'
                     'for each id in: %s', ', '.join(ids))

    # Remove the cert renewal lock file
    try:
        os.remove(paths.IPA_RENEWAL_LOCK)
    except OSError as e:
        if e.errno != errno.ENOENT:
            logger.warning("Failed to remove file %s: %s",
                           paths.IPA_RENEWAL_LOCK, e)

    print("Removing IPA client configuration")
    try:
        result = run([paths.IPA_CLIENT_INSTALL, "--on-master",
                      "--unattended", "--uninstall"],
                     raiseonerr=False, redirect_output=True)
        if result.returncode not in [0, 2]:
            raise RuntimeError("Failed to configure the client")
    except Exception:
        rv = 1
        print("Uninstall of client side components failed!")

    sys.exit(rv)
Esempio n. 35
0
    def execute(self, **options):
        serverid = realm_to_serverid(self.api.env.realm)
        db = certs.CertDB(self.api.env.realm,
                          nssdir=dsinstance.config_dirname(serverid))
        ca_cert = None

        ca_enabled = self.api.Command.ca_is_enabled()['result']
        if ca_enabled:
            ca_nickname = certdb.get_ca_nickname(self.api.env.realm)
            ca_subject = certstore.get_ca_subject(
                self.api.Backend.ldap2,
                self.api.env.container_ca,
                self.api.env.basedn)
        else:
            ca_nickname = None
            server_certs = db.find_server_certs()
            if server_certs:
                ca_chain = db.find_root_cert(server_certs[0][0])[:-1]
                if ca_chain:
                    ca_nickname = ca_chain[-1]

        ldap = self.api.Backend.ldap2

        for nickname, trust_flags in db.list_certs():
            if trust_flags.has_key:
                continue
            cert = db.get_cert_from_db(nickname)
            subject = cert.subject
            if ca_enabled and subject == ca_subject:
                # When ca is enabled, we can have the IPA CA cert stored
                # in the nss db with a different nickname (for instance
                # when the server was installed with --subject to
                # customize the CA cert subject), but it must always be
                # stored in LDAP with the DN cn=$DOMAIN IPA CA
                # This is why we check the subject instead of the nickname here
                nickname = ca_nickname
                trust_flags = certdb.IPA_CA_TRUST_FLAGS
            trust, _ca, eku = certstore.trust_flags_to_key_policy(trust_flags)

            dn = DN(('cn', nickname), ('cn', 'certificates'), ('cn', 'ipa'),
                    ('cn','etc'), self.api.env.basedn)
            entry = ldap.make_entry(dn)

            try:
                certstore.init_ca_entry(entry, cert, nickname, trust, eku)
            except Exception as e:
                logger.warning("Failed to create entry for %s: %s",
                               nickname, e)
                continue
            if nickname == ca_nickname:
                ca_cert = cert
                config = entry.setdefault('ipaConfigString', [])
                if ca_enabled:
                    config.append('ipaCa')
                config.append('ipaCa')

            try:
                ldap.add_entry(entry)
            except errors.DuplicateEntry:
                if nickname == ca_nickname and ca_enabled:
                    try:
                        ldap.update_entry(entry)
                    except errors.EmptyModlist:
                        pass

        if ca_cert:
            dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn','etc'),
                    self.api.env.basedn)
            try:
                entry = ldap.get_entry(dn)
            except errors.NotFound:
                entry = ldap.make_entry(dn)
                entry['objectclass'] = ['nsContainer', 'pkiCA']
                entry.single_value['cn'] = 'CAcert'
                entry.single_value['cACertificate;binary'] = ca_cert
                ldap.add_entry(entry)
            else:
                force_write = False
                try:
                    _cert_bin = entry['cACertificate;binary']
                except ValueError:
                    # BZ 1644874
                    # sometimes the cert is badly stored, twice encoded
                    # force write to fix the value
                    logger.debug('Fixing the value of cACertificate;binary '
                                 'in entry %s', entry.dn)
                    force_write = True

                if force_write or b'' in entry['cACertificate;binary']:
                    entry.single_value['cACertificate;binary'] = ca_cert
                    ldap.update_entry(entry)

        return False, []