Example #1
0
    def add_instance_specific_data(self):
        '''
        Add instance-specific files and directories.

        NOTE: this adds some things that may not get backed up.
        '''
        serverid = ipaldap.realm_to_serverid(api.env.realm)

        for dir in [
                paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid,
                paths.VAR_LIB_DIRSRV_INSTANCE_SCRIPTS_TEMPLATE % serverid,
                paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE % serverid
        ]:
            if os.path.exists(dir):
                self.dirs.append(dir)

        for file in (
                paths.SYSCONFIG_DIRSRV_INSTANCE % serverid,
                paths.ETC_TMPFILESD_DIRSRV % serverid,
                paths.SLAPD_INSTANCE_SYSTEMD_IPA_ENV_TEMPLATE % serverid,
        ):
            if os.path.exists(file):
                self.files.append(file)

        self.files.append(
            paths.HTTPD_PASSWD_FILE_FMT.format(host=api.env.host))

        self.logs.append(paths.VAR_LOG_DIRSRV_INSTANCE_TEMPLATE % serverid)
Example #2
0
    def __setup_default_attributes(self):
        """
        This method setups default attributes that are either constants, or
        based on api.env attributes, such as realm, hostname or domain name.
        """

        # Constants
        self.smb_conf = paths.SMB_CONF
        self.cifs_hosts = []

        # Values obtained from API.env
        self.fqdn = self.fqdn or api.env.host
        self.host_netbios_name = make_netbios_name(self.fqdn)
        self.realm = self.realm or api.env.realm

        self.suffix = ipautil.realm_to_suffix(self.realm)
        self.ldapi_socket = "%%2fvar%%2frun%%2fslapd-%s.socket" % \
                            ipaldap.realm_to_serverid(self.realm)

        # DN definitions
        self.trust_dn = DN(api.env.container_trusts, self.suffix)

        self.smb_dn = DN(('cn', 'adtrust agents'), ('cn', 'sysaccounts'),
                         ('cn', 'etc'), self.suffix)

        self.smb_dom_dn = DN(('cn', api.env.domain),
                             api.env.container_cifsdomains, self.suffix)

        self.cifs_agent = DN(('krbprincipalname', self.principal.lower()),
                             api.env.container_service, self.suffix)
        self.host_princ = DN(('fqdn', self.fqdn), api.env.container_host,
                             self.suffix)
Example #3
0
    def _setup_sub_dict(self):
        if paths.NAMED_CRYPTO_POLICY_FILE is not None:
            crypto_policy = 'include "{}";'.format(
                paths.NAMED_CRYPTO_POLICY_FILE
            )
        else:
            crypto_policy = "// not available"

        self.sub_dict = dict(
            FQDN=self.fqdn,
            SERVER_ID=ipaldap.realm_to_serverid(self.realm),
            SUFFIX=self.suffix,
            MANAGED_KEYS_DIR=paths.NAMED_MANAGED_KEYS_DIR,
            ROOT_KEY=paths.NAMED_ROOT_KEY,
            NAMED_KEYTAB=self.keytab,
            RFC1912_ZONES=paths.NAMED_RFC1912_ZONES,
            NAMED_PID=paths.NAMED_PID,
            NAMED_VAR_DIR=paths.NAMED_VAR_DIR,
            BIND_LDAP_SO=paths.BIND_LDAP_SO,
            INCLUDE_CRYPTO_POLICY=crypto_policy,
            NAMED_CONF=paths.NAMED_CONF,
            NAMED_CUSTOM_CONF=paths.NAMED_CUSTOM_CONF,
            NAMED_CUSTOM_OPTIONS_CONF=paths.NAMED_CUSTOM_OPTIONS_CONF,
            NAMED_LOGGING_OPTIONS_CONF=paths.NAMED_LOGGING_OPTIONS_CONF,
            NAMED_DATA_DIR=constants.NAMED_DATA_DIR,
            NAMED_ZONE_COMMENT=constants.NAMED_ZONE_COMMENT,
            NAMED_DNSSEC_VALIDATION=self._get_dnssec_validation(),
        )
Example #4
0
def realm_to_serverid(realm_name):
    warnings.warn(
        "Use 'ipapython.ipaldap.realm_to_serverid'",
        DeprecationWarning,
        stacklevel=2
    )
    return ipaldap.realm_to_serverid(realm_name)
Example #5
0
    def add_instance_specific_data(self):
        '''
        Add instance-specific files and directories.

        NOTE: this adds some things that may not get backed up.
        '''
        serverid = ipaldap.realm_to_serverid(api.env.realm)

        for dir in [paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid,
                    paths.VAR_LIB_DIRSRV_INSTANCE_SCRIPTS_TEMPLATE % serverid,
                    paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE % serverid]:
            if os.path.exists(dir):
                self.dirs.append(dir)

        for file in (
            paths.SYSCONFIG_DIRSRV_INSTANCE % serverid,
            paths.ETC_TMPFILESD_DIRSRV % serverid,
            paths.SLAPD_INSTANCE_SYSTEMD_IPA_ENV_TEMPLATE % serverid,
        ):
            if os.path.exists(file):
                self.files.append(file)

        self.files.append(
            paths.HTTPD_PASSWD_FILE_FMT.format(host=api.env.host)
        )

        self.logs.append(paths.VAR_LOG_DIRSRV_INSTANCE_TEMPLATE % serverid)
Example #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 = []

    # 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
Example #7
0
 def test_source_ipahealthcheck_ipa_host_check_ipahostkeytab(self):
     """
     Testcase checks behaviour of check IPAHostKeytab in source
     ipahealthcheck.ipa.host when dirsrv service is stopped and
     running on IPA master
     """
     msg = ("Failed to obtain host TGT: Major (851968): "
            "Unspecified GSS failure.  "
            "Minor code may provide more information, "
            "Minor (2529638972): Generic error (see e-text)")
     dirsrv_ipactl_status = 'Directory Service: STOPPED'
     api.env.realm = self.master.domain.name
     serverid = (realm_to_serverid(api.env.realm)).upper()
     dirsrv_service = "dirsrv@%s.service" % serverid
     self.master.run_command(["systemctl", "stop", dirsrv_service])
     result = self.master.run_command(["ipactl", "status"])
     returncode, data = run_healthcheck(
         self.master,
         "ipahealthcheck.ipa.host",
         "IPAHostKeytab",
     )
     assert returncode == 1
     if dirsrv_ipactl_status in result.stdout_text:
         assert data[0]["result"] == "ERROR"
         assert data[0]["kw"]["msg"] == msg
     else:
         assert data[0]["result"] == "SUCCESS"
     self.master.run_command(["systemctl", "start", dirsrv_service])
Example #8
0
 def __init__(self, reg):
     super().__init__(reg)
     self.ca = cainstance.CAInstance(api.env.realm, host_name=api.env.host)
     self.http = httpinstance.HTTPInstance()
     self.ds = dsinstance.DsInstance()
     self.serverid = realm_to_serverid(api.env.realm)
     self.conn = api.Backend.ldap2
    def test_full_backup_and_restore(self):
        """backup, uninstall, restore"""
        with restore_checker(self.master):
            backup_path = tasks.get_backup_dir(self.master)

            self.master.run_command(['ipa-server-install',
                                     '--uninstall',
                                     '-U'])
            assert not self.master.transport.file_exists(
                paths.IPA_CUSTODIA_KEYS)
            assert not self.master.transport.file_exists(
                paths.IPA_CUSTODIA_CONF)

            dirman_password = self.master.config.dirman_password
            self.master.run_command(['ipa-restore', backup_path],
                                    stdin_text=dirman_password + '\nyes')

            # check the file permssion and ownership is set to 770 and
            # dirsrv:dirsrv after restore on /var/log/dirsrv/slapd-<instance>
            # related ticket : https://pagure.io/freeipa/issue/7725
            instance = realm_to_serverid(self.master.domain.realm)
            log_path = paths.VAR_LOG_DIRSRV_INSTANCE_TEMPLATE % instance
            cmd = self.master.run_command(['stat', '-c',
                                           '"%a %G:%U"', log_path])
            assert "770 dirsrv:dirsrv" in cmd.stdout_text
Example #10
0
    def test_failed_uninstall(self):
        self.master.run_command(['ipactl', 'stop'])

        serverid = realm_to_serverid(self.master.domain.realm)
        instance_name = ''.join([DS_INSTANCE_PREFIX, serverid])

        try:
            # Moving the DS instance out of the way will cause the
            # uninstaller to raise an exception and return with a
            # non-zero return code.
            self.master.run_command([
                '/bin/mv',
                '%s/%s' % (paths.ETC_DIRSRV, instance_name),
                '%s/%s.test' % (paths.ETC_DIRSRV, instance_name)
            ])

            cmd = self.master.run_command([
                'ipa-server-install',
                '--uninstall', '-U'],
                raiseonerr=False
            )
            assert cmd.returncode == 1
        finally:
            # Be paranoid. If something really went wrong then DS may
            # be marked as uninstalled so server cert will still be
            # tracked and the instances may remain. This can cause
            # subsequent installations to fail so be thorough.
            dashed_domain = self.master.domain.realm.replace(".", '-')
            dirsrv_service = "dirsrv@%s.service" % dashed_domain
            self.master.run_command(['systemctl', 'stop', dirsrv_service])

            # Moving it back should allow the uninstall to finish
            # successfully.
            self.master.run_command([
                '/bin/mv',
                '%s/%s.test' % (paths.ETC_DIRSRV, instance_name),
                '%s/%s' % (paths.ETC_DIRSRV, instance_name)
            ])

            cmd = self.master.run_command([
                'ipa-server-install',
                '--uninstall', '-U'],
                raiseonerr=False
            )
            assert cmd.returncode == 0

            self.master.run_command([
                paths.IPA_GETCERT,
                'stop-tracking',
                '-d', '%s/%s' % (paths.ETC_DIRSRV, instance_name),
                '-n', 'Server-Cert',
            ])

            self.master.run_command([
                paths.DSCTL, serverid, 'remove', '--do-it'
            ])
Example #11
0
    def test_failed_uninstall(self):
        self.master.run_command(['ipactl', 'stop'])

        serverid = realm_to_serverid(self.master.domain.realm)
        instance_name = ''.join([dsinstance.DS_INSTANCE_PREFIX, serverid])

        try:
            # Moving the DS instance out of the way will cause the
            # uninstaller to raise an exception and return with a
            # non-zero return code.
            self.master.run_command([
                '/bin/mv',
                '%s/%s' % (paths.ETC_DIRSRV, instance_name),
                '%s/%s.test' % (paths.ETC_DIRSRV, instance_name)
            ])

            cmd = self.master.run_command([
                'ipa-server-install',
                '--uninstall', '-U'],
                raiseonerr=False
            )
            assert cmd.returncode == 1
        finally:
            # Be paranoid. If something really went wrong then DS may
            # be marked as uninstalled so server cert will still be
            # tracked and the instances may remain. This can cause
            # subsequent installations to fail so be thorough.
            dashed_domain = self.master.domain.realm.replace(".", '-')
            dirsrv_service = "dirsrv@%s.service" % dashed_domain
            self.master.run_command(['systemctl', 'stop', dirsrv_service])

            # Moving it back should allow the uninstall to finish
            # successfully.
            self.master.run_command([
                '/bin/mv',
                '%s/%s.test' % (paths.ETC_DIRSRV, instance_name),
                '%s/%s' % (paths.ETC_DIRSRV, instance_name)
            ])

            cmd = self.master.run_command([
                'ipa-server-install',
                '--uninstall', '-U'],
                raiseonerr=False
            )
            assert cmd.returncode == 0

            self.master.run_command([
                paths.IPA_GETCERT,
                'stop-tracking',
                '-d', '%s/%s' % (paths.ETC_DIRSRV, instance_name),
                '-n', 'Server-Cert',
            ])

            self.master.run_command([
                paths.DSCTL, serverid, 'remove', '--do-it'
            ])
Example #12
0
    def check(self):
        if not self.registry.trust_controller:
            logger.debug('Not a trust controller, skipping')
            return

        ldapi_socket = "ipasam:ldapi://%%2fvar%%2frun%%2fslapd-%s.socket" % \
                       realm_to_serverid(api.env.realm)

        try:
            result = ipautil.run(['net', 'conf', 'list'], capture_output=True)
        except Exception as e:
            yield Result(self,
                         constants.ERROR,
                         key='net conf list',
                         error=str(e),
                         msg='Execution of {key} failed: {error}')
            return

        conf = result.output.replace('\t', '')
        config = configparser.ConfigParser(delimiters=('='),
                                           interpolation=None)
        try:
            config.read_string(conf)
        except Exception as e:
            yield Result(self,
                         constants.ERROR,
                         key='net conf list',
                         error=str(e),
                         msg='Unable to parse {key} output: {error}')
            return

        try:
            net_ldapi = config.get('global', 'passdb backend')
        except Exception as e:
            yield Result(self,
                         constants.ERROR,
                         key='net conf list',
                         error=str(e),
                         section='global',
                         option='passdb backend',
                         msg='Unable to read \'{option}\' in section '
                         '{section} in {key} output: {error}')
            return

        if net_ldapi != ldapi_socket:
            yield Result(self,
                         constants.ERROR,
                         key='net conf list',
                         got=net_ldapi,
                         expected=ldapi_socket,
                         option='passdb backend',
                         msg='{key} option {option} value {got} '
                         'doesn\'t match expected value {expected}')
        else:
            yield Result(self, constants.SUCCESS, key='net conf list')
Example #13
0
    def __setup_sub_dict(self):
        if os.path.exists(paths.COMMON_KRB5_CONF_DIR):
            includes = 'includedir {}'.format(paths.COMMON_KRB5_CONF_DIR)
        else:
            includes = ''

        self.sub_dict = dict(FQDN=self.fqdn,
                             IP=self.ip,
                             PASSWORD=self.kdc_password,
                             SUFFIX=self.suffix,
                             DOMAIN=self.domain,
                             HOST=self.host,
                             SERVER_ID=ipaldap.realm_to_serverid(self.realm),
                             REALM=self.realm,
                             KRB5KDC_KADM5_ACL=paths.KRB5KDC_KADM5_ACL,
                             DICT_WORDS=paths.DICT_WORDS,
                             KRB5KDC_KADM5_KEYTAB=paths.KRB5KDC_KADM5_KEYTAB,
                             KDC_CERT=paths.KDC_CERT,
                             KDC_KEY=paths.KDC_KEY,
                             CACERT_PEM=paths.CACERT_PEM,
                             KDC_CA_BUNDLE_PEM=paths.KDC_CA_BUNDLE_PEM,
                             CA_BUNDLE_PEM=paths.CA_BUNDLE_PEM,
                             INCLUDES=includes,
                             FIPS='#' if tasks.is_fips_enabled() else '')

        # IPA server/KDC is not a subdomain of default domain
        # Proper domain-realm mapping needs to be specified
        domain = dns.name.from_text(self.domain)
        fqdn = dns.name.from_text(self.fqdn)
        if not fqdn.is_subdomain(domain):
            logger.debug("IPA FQDN '%s' is not located in default domain '%s'",
                         fqdn, domain)
            server_domain = fqdn.parent().to_unicode(omit_final_dot=True)
            logger.debug("Domain '%s' needs additional mapping in krb5.conf",
                         server_domain)
            dr_map = " .%(domain)s = %(realm)s\n %(domain)s = %(realm)s\n" \
                        % dict(domain=server_domain, realm=self.realm)
        else:
            dr_map = ""
        self.sub_dict['OTHER_DOMAIN_REALM_MAPS'] = dr_map

        # Configure KEYRING CCACHE if supported
        if kernel_keyring.is_persistent_keyring_supported():
            logger.debug("Enabling persistent keyring CCACHE")
            self.sub_dict['OTHER_LIBDEFAULTS'] = \
                " default_ccache_name = KEYRING:persistent:%{uid}\n"
        else:
            logger.debug("Persistent keyring CCACHE is not enabled")
            self.sub_dict['OTHER_LIBDEFAULTS'] = ''

        # Create kadm5.acl if it doesn't exist
        if not os.path.exists(paths.KRB5KDC_KADM5_ACL):
            open(paths.KRB5KDC_KADM5_ACL, 'a').close()
            os.chmod(paths.KRB5KDC_KADM5_ACL, 0o600)
Example #14
0
    def __setup_sub_dict(self):
        if os.path.exists(paths.COMMON_KRB5_CONF_DIR):
            includes = 'includedir {}'.format(paths.COMMON_KRB5_CONF_DIR)
        else:
            includes = ''

        self.sub_dict = dict(FQDN=self.fqdn,
                             IP=self.ip,
                             PASSWORD=self.kdc_password,
                             SUFFIX=self.suffix,
                             DOMAIN=self.domain,
                             HOST=self.host,
                             SERVER_ID=ipaldap.realm_to_serverid(self.realm),
                             REALM=self.realm,
                             KRB5KDC_KADM5_ACL=paths.KRB5KDC_KADM5_ACL,
                             DICT_WORDS=paths.DICT_WORDS,
                             KRB5KDC_KADM5_KEYTAB=paths.KRB5KDC_KADM5_KEYTAB,
                             KDC_CERT=paths.KDC_CERT,
                             KDC_KEY=paths.KDC_KEY,
                             CACERT_PEM=paths.CACERT_PEM,
                             KDC_CA_BUNDLE_PEM=paths.KDC_CA_BUNDLE_PEM,
                             CA_BUNDLE_PEM=paths.CA_BUNDLE_PEM,
                             INCLUDES=includes)

        # IPA server/KDC is not a subdomain of default domain
        # Proper domain-realm mapping needs to be specified
        domain = dns.name.from_text(self.domain)
        fqdn = dns.name.from_text(self.fqdn)
        if not fqdn.is_subdomain(domain):
            logger.debug("IPA FQDN '%s' is not located in default domain '%s'",
                         fqdn, domain)
            server_domain = fqdn.parent().to_unicode(omit_final_dot=True)
            logger.debug("Domain '%s' needs additional mapping in krb5.conf",
                         server_domain)
            dr_map = " .%(domain)s = %(realm)s\n %(domain)s = %(realm)s\n" \
                        % dict(domain=server_domain, realm=self.realm)
        else:
            dr_map = ""
        self.sub_dict['OTHER_DOMAIN_REALM_MAPS'] = dr_map

        # Configure KEYRING CCACHE if supported
        if kernel_keyring.is_persistent_keyring_supported():
            logger.debug("Enabling persistent keyring CCACHE")
            self.sub_dict['OTHER_LIBDEFAULTS'] = \
                " default_ccache_name = KEYRING:persistent:%{uid}\n"
        else:
            logger.debug("Persistent keyring CCACHE is not enabled")
            self.sub_dict['OTHER_LIBDEFAULTS'] = ''

        # Create kadm5.acl if it doesn't exist
        if not os.path.exists(paths.KRB5KDC_KADM5_ACL):
            open(paths.KRB5KDC_KADM5_ACL, 'a').close()
            os.chmod(paths.KRB5KDC_KADM5_ACL, 0o600)
Example #15
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
Example #16
0
    def __init__(self, realm_name, files=[], schema_files=[]):
        """
        realm_name: kerberos realm name, used to determine DS instance dir
        files: list of update files to process. If none use UPDATEDIR
        """

        ext = ''
        rand = random.Random()
        for _i in range(8):
            h = "%02x" % rand.randint(0,255)
            ext += h
        super(IPAUpgrade, self).__init__("dirsrv", realm_name=realm_name)
        serverid = ipaldap.realm_to_serverid(realm_name)
        self.filename = '%s/%s' % (paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, DSE)
        self.savefilename = '%s/%s.ipa.%s' % (paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, DSE, ext)
        self.files = files
        self.modified = False
        self.serverid = serverid
        self.schema_files = schema_files
Example #17
0
    def install_dirsrv_cert(self):
        serverid = ipaldap.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
    def install_dirsrv_cert(self):
        serverid = ipaldap.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
Example #19
0
    def __init__(self, realm_name, files=[], schema_files=[]):
        """
        realm_name: kerberos realm name, used to determine DS instance dir
        files: list of update files to process. If none use UPDATEDIR
        """

        ext = ''
        rand = random.Random()
        for _i in range(8):
            h = "%02x" % rand.randint(0,255)
            ext += h
        super(IPAUpgrade, self).__init__("dirsrv", realm_name=realm_name)
        serverid = ipaldap.realm_to_serverid(realm_name)
        self.filename = '%s/%s' % (paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, DSE)
        self.savefilename = '%s/%s.ipa.%s' % (paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % serverid, DSE, ext)
        self.files = files
        self.modified = False
        self.serverid = serverid
        self.schema_files = schema_files
Example #20
0
    def cert_restore_prepare(self):
        cainstance.CAInstance().stop_tracking_certificates()
        httpinstance.HTTPInstance().stop_tracking_certificates()
        try:
            dsinstance.DsInstance().stop_tracking_certificates(
                ipaldap.realm_to_serverid(api.env.realm))
        except (OSError, IOError):
            # When IPA is not installed, DS NSS DB does not exist
            pass

        krbinstance.KrbInstance().stop_tracking_certs()

        for basename in certdb.NSS_FILES:
            filename = os.path.join(paths.IPA_NSSDB_DIR, basename)
            try:
                ipautil.backup_file(filename)
            except OSError as e:
                logger.error("Failed to backup %s: %s", filename, e)

        tasks.remove_ca_certs_from_systemwide_ca_store()
Example #21
0
    def cert_restore_prepare(self):
        cainstance.CAInstance().stop_tracking_certificates()
        httpinstance.HTTPInstance().stop_tracking_certificates()
        try:
            dsinstance.DsInstance().stop_tracking_certificates(
                ipaldap.realm_to_serverid(api.env.realm))
        except (OSError, IOError):
            # When IPA is not installed, DS NSS DB does not exist
            pass

        krbinstance.KrbInstance().stop_tracking_certs()

        for basename in certdb.NSS_FILES:
            filename = os.path.join(paths.IPA_NSSDB_DIR, basename)
            try:
                ipautil.backup_file(filename)
            except OSError as e:
                logger.error("Failed to backup %s: %s", filename, e)

        tasks.remove_ca_certs_from_systemwide_ca_store()
Example #22
0
    def get_connection(self):
        '''
        Create an ldapi connection and bind to it using autobind as root.
        '''
        instance_name = ipaldap.realm_to_serverid(api.env.realm)

        if not services.knownservices.dirsrv.is_running(instance_name):
            raise admintool.ScriptError(
                "directory server instance is not running/configured")

        if self._conn is not None:
            return self._conn

        self._conn = ipaldap.LDAPClient.from_realm(api.env.realm)

        try:
            self._conn.external_bind()
        except Exception as e:
            raise admintool.ScriptError('Unable to bind to LDAP server: %s' %
                                        e)
        return self._conn
Example #23
0
    def init_api(self, **overrides):
        overrides.setdefault('confdir', paths.ETC_IPA)
        api.bootstrap(in_server=True, context='restore', **overrides)
        api.finalize()

        self.instances = [ipaldap.realm_to_serverid(api.env.realm)]
        self.backends = ['userRoot', 'ipaca']

        # no IPA config means we are reinstalling from nothing so
        # there is nothing to test the DM password against.
        if os.path.exists(paths.IPA_DEFAULT_CONF):
            instance_name = ipapython.ipaldap.realm_to_serverid(api.env.realm)
            if not services.knownservices.dirsrv.is_running(instance_name):
                raise admintool.ScriptError(
                    "directory server instance is not running")
            try:
                ReplicationManager(api.env.realm, api.env.host,
                                   self.dirman_password)
            except errors.ACIError:
                logger.error("Incorrect Directory Manager password provided")
                raise
Example #24
0
    def init_api(self, **overrides):
        overrides.setdefault('confdir', paths.ETC_IPA)
        api.bootstrap(in_server=True, context='restore', **overrides)
        api.finalize()

        self.instances = [ipaldap.realm_to_serverid(api.env.realm)]
        self.backends = ['userRoot', 'ipaca']

        # no IPA config means we are reinstalling from nothing so
        # there is nothing to test the DM password against.
        if os.path.exists(paths.IPA_DEFAULT_CONF):
            instance_name = ipapython.ipaldap.realm_to_serverid(api.env.realm)
            if not services.knownservices.dirsrv.is_running(instance_name):
                raise admintool.ScriptError(
                    "directory server instance is not running"
                )
            try:
                ReplicationManager(api.env.realm, api.env.host,
                                   self.dirman_password)
            except errors.ACIError:
                logger.error("Incorrect Directory Manager password provided")
                raise
Example #25
0
    def test_ldapi_ok(self, mock_run):
        ldapi_socket = "ipasam:ldapi://%%2fvar%%2frun%%2fslapd-%s.socket" % \
                       realm_to_serverid(m_api.env.realm)
        run_result = namedtuple('run', ['returncode', 'output'])
        run_result.returncode = 0
        run_result.output = '[global]\n\tpassdb backend=%s' % ldapi_socket
        mock_run.return_value = run_result

        framework = object()
        registry.initialize(framework, config.Config)
        registry.trust_controller = True
        f = IPATrustControllerConfCheck(registry)

        self.results = capture_results(f)

        assert len(self.results) == 1

        result = self.results.results[0]
        assert result.result == constants.SUCCESS
        assert result.source == 'ipahealthcheck.ipa.trust'
        assert result.check == 'IPATrustControllerConfCheck'
        assert result.kw.get('key') == 'net conf list'
Example #26
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)
Example #27
0
    def get_connection(self):
        '''
        Create an ldapi connection and bind to it using autobind as root.
        '''
        instance_name = ipaldap.realm_to_serverid(api.env.realm)

        if not services.knownservices.dirsrv.is_running(instance_name):
            raise admintool.ScriptError(
                "directory server instance is not running/configured"
            )

        if self._conn is not None:
            return self._conn

        self._conn = ipaldap.LDAPClient.from_realm(api.env.realm)

        try:
            self._conn.external_bind()
        except Exception as e:
            raise admintool.ScriptError('Unable to bind to LDAP server: %s'
                % e)
        return self._conn
Example #28
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)
Example #29
0
    def __setup_sub_dict(self):
        if paths.NAMED_CRYPTO_POLICY_FILE is not None:
            crypto_policy = 'include "{}";'.format(
                paths.NAMED_CRYPTO_POLICY_FILE)
        else:
            crypto_policy = "// not available"

        self.sub_dict = dict(
            FQDN=self.fqdn,
            SERVER_ID=ipaldap.realm_to_serverid(self.realm),
            SUFFIX=self.suffix,
            BINDKEYS_FILE=paths.NAMED_BINDKEYS_FILE,
            MANAGED_KEYS_DIR=paths.NAMED_MANAGED_KEYS_DIR,
            ROOT_KEY=paths.NAMED_ROOT_KEY,
            NAMED_KEYTAB=self.keytab,
            RFC1912_ZONES=paths.NAMED_RFC1912_ZONES,
            NAMED_PID=paths.NAMED_PID,
            NAMED_VAR_DIR=paths.NAMED_VAR_DIR,
            BIND_LDAP_SO=paths.BIND_LDAP_SO,
            INCLUDE_CRYPTO_POLICY=crypto_policy,
            NAMED_DATA_DIR=constants.NAMED_DATA_DIR,
            NAMED_ZONE_COMMENT=constants.NAMED_ZONE_COMMENT,
        )
Example #30
0
    def __setup_default_attributes(self):
        """
        This method setups default attributes that are either constants, or
        based on api.env attributes, such as realm, hostname or domain name.
        """

        # Constants
        self.smb_conf = paths.SMB_CONF
        self.cifs_hosts = []

        # Values obtained from API.env
        self.fqdn = self.fqdn or api.env.host
        self.host_netbios_name = make_netbios_name(self.fqdn)
        self.realm = self.realm or api.env.realm

        self.suffix = ipautil.realm_to_suffix(self.realm)
        self.ldapi_socket = "%%2fvar%%2frun%%2fslapd-%s.socket" % \
                            ipaldap.realm_to_serverid(self.realm)

        # DN definitions
        self.trust_dn = DN(api.env.container_trusts, self.suffix)

        self.smb_dn = DN(('cn', 'adtrust agents'),
                         ('cn', 'sysaccounts'),
                         ('cn', 'etc'),
                         self.suffix)

        self.smb_dom_dn = DN(('cn', api.env.domain),
                             api.env.container_cifsdomains,
                             self.suffix)

        self.cifs_agent = DN(('krbprincipalname', self.principal.lower()),
                             api.env.container_service,
                             self.suffix)
        self.host_princ = DN(('fqdn', self.fqdn),
                             api.env.container_host,
                             self.suffix)
Example #31
0
 def test_source_ipahealthcheck_ipa_host_check_ipahostkeytab(self):
     """
     Testcase checks behaviour of check IPAHostKeytab in source
     ipahealthcheck.ipa.host when dirsrv service is stopped and
     running on IPA master
     """
     msg = ("Failed to obtain host TGT: Major (851968): "
            "Unspecified GSS failure.  "
            "Minor code may provide more information, "
            "Minor (2529638972): Generic error (see e-text)")
     dirsrv_ipactl_status = 'Directory Service: STOPPED'
     api.env.realm = self.master.domain.name
     serverid = (realm_to_serverid(api.env.realm)).upper()
     dirsrv_service = "dirsrv@%s.service" % serverid
     self.master.run_command(["systemctl", "stop", dirsrv_service])
     result = self.master.run_command(["ipactl", "status"])
     self.master.run_command(
         [
             "ipa-healthcheck",
             "--source",
             "ipahealthcheck.ipa.host",
             "--check",
             "IPAHostKeytab",
             "--output-file",
             HEALTHCHECK_OUTPUT_FILE,
         ],
         raiseonerr=False,
     )
     contents = self.master.get_file_contents(HEALTHCHECK_OUTPUT_FILE,
                                              encoding="utf-8")
     data = json.loads(contents)
     if dirsrv_ipactl_status in result.stdout_text:
         assert data[0]["result"] == "ERROR"
         assert data[0]["kw"]["msg"] == msg
     else:
         assert data[0]["result"] == "SUCCESS"
     self.master.run_command(["systemctl", "start", dirsrv_service])
Example #32
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
Example #33
0
    def __setup_sub_dict(self):
        if paths.NAMED_CRYPTO_POLICY_FILE is not None:
            crypto_policy = 'include "{}";'.format(
                paths.NAMED_CRYPTO_POLICY_FILE
            )
        else:
            crypto_policy = "// not available"

        self.sub_dict = dict(
            FQDN=self.fqdn,
            SERVER_ID=ipaldap.realm_to_serverid(self.realm),
            SUFFIX=self.suffix,
            BINDKEYS_FILE=paths.NAMED_BINDKEYS_FILE,
            MANAGED_KEYS_DIR=paths.NAMED_MANAGED_KEYS_DIR,
            ROOT_KEY=paths.NAMED_ROOT_KEY,
            NAMED_KEYTAB=self.keytab,
            RFC1912_ZONES=paths.NAMED_RFC1912_ZONES,
            NAMED_PID=paths.NAMED_PID,
            NAMED_VAR_DIR=paths.NAMED_VAR_DIR,
            BIND_LDAP_SO=paths.BIND_LDAP_SO,
            INCLUDE_CRYPTO_POLICY=crypto_policy,
            NAMED_DATA_DIR=constants.NAMED_DATA_DIR,
            NAMED_ZONE_COMMENT=constants.NAMED_ZONE_COMMENT,
        )
Example #34
0
    def run(self):
        options = self.options
        super(Backup, self).run()

        api.bootstrap(in_server=True, context='backup', confdir=paths.ETC_IPA)
        api.finalize()

        logger.info("Preparing backup on %s", api.env.host)

        pent = pwd.getpwnam(constants.DS_USER)

        self.top_dir = tempfile.mkdtemp("ipa")
        os.chown(self.top_dir, pent.pw_uid, pent.pw_gid)
        os.chmod(self.top_dir, 0o750)
        self.dir = os.path.join(self.top_dir, "ipa")
        os.mkdir(self.dir)
        os.chmod(self.dir, 0o750)
        os.chown(self.dir, pent.pw_uid, pent.pw_gid)
        self.tarfile = None

        self.header = os.path.join(self.top_dir, 'header')

        cwd = os.getcwd()
        try:
            dirsrv = services.knownservices.dirsrv

            self.add_instance_specific_data()

            # We need the dirsrv running to get the list of services
            dirsrv.start(capture_output=False)

            self.get_connection()

            self.create_header(options.data_only)
            if options.data_only:
                if not options.online:
                    logger.info('Stopping Directory Server')
                    dirsrv.stop(capture_output=False)
            else:
                logger.info('Stopping IPA services')
                run([paths.IPACTL, 'stop'])

            instance = ipaldap.realm_to_serverid(api.env.realm)
            if os.path.exists(paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE %
                              instance):
                if os.path.exists(paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
                                  (instance, 'ipaca')):
                    self.db2ldif(instance, 'ipaca', online=options.online)
                self.db2ldif(instance, 'userRoot', online=options.online)
                self.db2bak(instance, online=options.online)
            if not options.data_only:
                # create backup of auth configuration
                auth_backup_path = os.path.join(paths.VAR_LIB_IPA,
                                                'auth_backup')
                tasks.backup_auth_configuration(auth_backup_path)
                self.file_backup(options)

            if options.data_only:
                if not options.online:
                    logger.info('Starting Directory Server')
                    dirsrv.start(capture_output=False)
            else:
                logger.info('Starting IPA service')
                run([paths.IPACTL, 'start'])

            # Compress after services are restarted to minimize
            # the unavailability window
            if not options.data_only:
                self.compress_file_backup()

            self.finalize_backup(options.data_only, options.gpg,
                                 options.gpg_keyring)

        finally:
            try:
                os.chdir(cwd)
            except Exception as e:
                logger.error('Cannot change directory to %s: %s', cwd, e)
            shutil.rmtree(self.top_dir)
Example #35
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)
Example #36
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()
Example #37
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))
Example #38
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, []
Example #39
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

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

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

    tasks.restore_pkcs11_modules(fstore)

    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')
        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)
Example #40
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))
Example #41
0
    def test_renew_expired_cert_replica(self, expire_certs):
        """Test renewal of certificates on replica with ipa-cert-fix

        This is to check that ipa-cert-fix renews the certificates
        on replica

        related: https://pagure.io/freeipa/issue/7885
        """
        # wait for cert expiry
        check_status(self.master, 8, "CA_UNREACHABLE")

        self.master.run_command(['ipa-cert-fix', '-v'], stdin_text='yes\n')

        check_status(self.master, 9, "MONITORING")

        # replica operations
        # 'Server-Cert cert-pki-ca' cert will be in CA_UNREACHABLE state
        cmd = self.replicas[0].run_command([
            'getcert', 'list', '-d', paths.PKI_TOMCAT_ALIAS_DIR, '-n',
            'Server-Cert cert-pki-ca'
        ])
        req_id = get_certmonger_fs_id(cmd.stdout_text)
        tasks.wait_for_certmonger_status(self.replicas[0], ('CA_UNREACHABLE'),
                                         req_id,
                                         timeout=600)
        # get initial expiry date to compare later with renewed cert
        initial_expiry = get_cert_expiry(self.replicas[0],
                                         paths.PKI_TOMCAT_ALIAS_DIR,
                                         'Server-Cert cert-pki-ca')

        # check that HTTP,LDAP,PKINIT are renewed and in MONITORING state
        instance = realm_to_serverid(self.master.domain.realm)
        dirsrv_cert = paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % instance
        for cert in (paths.KDC_CERT, paths.HTTPD_CERT_FILE):
            cmd = self.replicas[0].run_command(['getcert', 'list', '-f', cert])
            req_id = get_certmonger_fs_id(cmd.stdout_text)
            tasks.wait_for_certmonger_status(self.replicas[0], ('MONITORING'),
                                             req_id,
                                             timeout=600)

        cmd = self.replicas[0].run_command(
            ['getcert', 'list', '-d', dirsrv_cert])
        req_id = get_certmonger_fs_id(cmd.stdout_text)
        tasks.wait_for_certmonger_status(self.replicas[0], ('MONITORING'),
                                         req_id,
                                         timeout=600)

        # check if replication working fine
        testuser = '******'
        password = '******'
        stdin = (f"{self.master.config.admin_password}\n"
                 f"{self.master.config.admin_password}\n"
                 f"{self.master.config.admin_password}\n")
        self.master.run_command(['kinit', 'admin'], stdin_text=stdin)
        tasks.user_add(self.master, testuser, password=password)
        self.replicas[0].run_command(['kinit', 'admin'], stdin_text=stdin)
        self.replicas[0].run_command(['ipa', 'user-show', testuser])

        # renew shared certificates by resubmitting to certmonger
        cmd = self.replicas[0].run_command(
            ['getcert', 'list', '-f', paths.RA_AGENT_PEM])
        req_id = get_certmonger_fs_id(cmd.stdout_text)
        if needs_resubmit(self.replicas[0], req_id):
            self.replicas[0].run_command(['getcert', 'resubmit', '-i', req_id])
            tasks.wait_for_certmonger_status(self.replicas[0], ('MONITORING'),
                                             req_id,
                                             timeout=600)
        for cert_nick in ('auditSigningCert cert-pki-ca',
                          'ocspSigningCert cert-pki-ca',
                          'subsystemCert cert-pki-ca'):
            cmd = self.replicas[0].run_command([
                'getcert', 'list', '-d', paths.PKI_TOMCAT_ALIAS_DIR, '-n',
                cert_nick
            ])
            req_id = get_certmonger_fs_id(cmd.stdout_text)
            if needs_resubmit(self.replicas[0], req_id):
                self.replicas[0].run_command(
                    ['getcert', 'resubmit', '-i', req_id])
                tasks.wait_for_certmonger_status(self.replicas[0],
                                                 ('MONITORING'),
                                                 req_id,
                                                 timeout=600)

        self.replicas[0].run_command(['ipa-cert-fix', '-v'],
                                     stdin_text='yes\n')

        check_status(self.replicas[0], 9, "MONITORING")

        # Sometimes certmonger takes time to update the cert status
        # So check in nssdb instead of relying on getcert command
        renewed_expiry = get_cert_expiry(self.replicas[0],
                                         paths.PKI_TOMCAT_ALIAS_DIR,
                                         'Server-Cert cert-pki-ca')
        assert renewed_expiry > initial_expiry
Example #42
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()
Example #43
0
    def check(self, instance=''):
        self.service_name = 'dirsrv'

        return super().check(realm_to_serverid(api.env.realm))
Example #44
0
    def run(self):
        if not is_ipa_configured():
            print("IPA is not configured.")
            return 2

        if not cainstance.is_ca_installed_locally():
            print("CA is not installed on this server.")
            return 1

        try:
            ipautil.run(['pki-server', 'cert-fix', '--help'], raiseonerr=True)
        except ipautil.CalledProcessError:
            print("The 'pki-server cert-fix' command is not available; "
                  "cannot proceed.")
            return 1

        api.bootstrap(in_server=True, confdir=paths.ETC_IPA)
        api.finalize()

        if not dsinstance.is_ds_running(realm_to_serverid(api.env.realm)):
            print("The LDAP server is not running; cannot proceed.")
            return 1

        api.Backend.ldap2.connect()  # ensure DS is up

        subject_base = dsinstance.DsInstance().find_subject_base()
        if not subject_base:
            raise RuntimeError("Cannot determine certificate subject base.")

        ca_subject_dn = ca.lookup_ca_subject(api, subject_base)

        now = datetime.datetime.now() + datetime.timedelta(weeks=2)
        certs, extra_certs, non_renewed = expired_certs(now)

        if not certs and not extra_certs:
            print("Nothing to do.")
            return 0

        print(msg)

        print_intentions(certs, extra_certs, non_renewed)

        response = ipautil.user_input('Enter "yes" to proceed')
        if response.lower() != 'yes':
            print("Not proceeding.")
            return 0
        print("Proceeding.")

        try:
            fix_certreq_directives(certs)
            run_cert_fix(certs, extra_certs)
        except ipautil.CalledProcessError:
            if any(x[0] is IPACertType.LDAPS
                   for x in extra_certs + non_renewed):
                # The DS cert was expired.  This will cause 'pki-server
                # cert-fix' to fail at the final restart, and return nonzero.
                # So this exception *might* be OK to ignore.
                #
                # If 'pki-server cert-fix' has written new certificates
                # corresponding to all the extra_certs, then ignore the
                # CalledProcessError and proceed to installing the IPA-specific
                # certs.  Otherwise re-raise.
                if check_renewed_ipa_certs(extra_certs):
                    pass
                else:
                    raise
            else:
                raise  # otherwise re-raise

        replicate_dogtag_certs(subject_base, ca_subject_dn, certs)
        install_ipa_certs(subject_base, ca_subject_dn, extra_certs)

        if any(x[0] != 'sslserver' for x in certs) \
                or any(x[0] is IPACertType.IPARA for x in extra_certs):
            # we renewed a "shared" certificate, therefore we must
            # become the renewal master
            print("Becoming renewal master.")
            cainstance.CAInstance().set_renewal_master()

        print("Restarting IPA")
        ipautil.run(['ipactl', 'restart'], raiseonerr=True)

        print(renewal_note)
        return 0
Example #45
0
    def run(self):
        options = self.options
        super(Backup, self).run()

        api.bootstrap(in_server=True, context='backup', confdir=paths.ETC_IPA)
        api.finalize()

        logger.info("Preparing backup on %s", api.env.host)

        pent = pwd.getpwnam(constants.DS_USER)

        self.top_dir = tempfile.mkdtemp("ipa")
        os.chown(self.top_dir, pent.pw_uid, pent.pw_gid)
        os.chmod(self.top_dir, 0o750)
        self.dir = os.path.join(self.top_dir, "ipa")
        os.mkdir(self.dir)
        os.chmod(self.dir, 0o750)
        os.chown(self.dir, pent.pw_uid, pent.pw_gid)
        self.tarfile = None

        self.header = os.path.join(self.top_dir, 'header')

        cwd = os.getcwd()
        try:
            dirsrv = services.knownservices.dirsrv

            self.add_instance_specific_data()

            # We need the dirsrv running to get the list of services
            dirsrv.start(capture_output=False)

            self.get_connection()

            self.create_header(options.data_only)
            if options.data_only:
                if not options.online:
                    logger.info('Stopping Directory Server')
                    dirsrv.stop(capture_output=False)
            else:
                logger.info('Stopping IPA services')
                run([paths.IPACTL, 'stop'])

            instance = ipaldap.realm_to_serverid(api.env.realm)
            if os.path.exists(paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE %
                              instance):
                if os.path.exists(paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
                                  (instance, 'ipaca')):
                    self.db2ldif(instance, 'ipaca', online=options.online)
                self.db2ldif(instance, 'userRoot', online=options.online)
                self.db2bak(instance, online=options.online)
            if not options.data_only:
                # create backup of auth configuration
                auth_backup_path = os.path.join(paths.VAR_LIB_IPA, 'auth_backup')
                tasks.backup_auth_configuration(auth_backup_path)
                self.file_backup(options)

            if options.data_only:
                if not options.online:
                    logger.info('Starting Directory Server')
                    dirsrv.start(capture_output=False)
            else:
                logger.info('Starting IPA service')
                run([paths.IPACTL, 'start'])

            # Compress after services are restarted to minimize
            # the unavailability window
            if not options.data_only:
                self.compress_file_backup()

            self.finalize_backup(options.data_only, options.gpg,
                                 options.gpg_keyring)

        finally:
            try:
                os.chdir(cwd)
            except Exception as e:
                logger.error('Cannot change directory to %s: %s', cwd, e)
            shutil.rmtree(self.top_dir)