Ejemplo n.º 1
0
    def init_api(self, **overrides):
        overrides.setdefault('confdir', paths.ETC_IPA)
        api.bootstrap(in_server=True, context='restore', **overrides)
        api.finalize()

        self.instances = [installutils.realm_to_serverid(api.env.realm)]
        self.backends = ['userRoot', 'ipaca']
Ejemplo n.º 2
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 = installutils.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,
        ):
            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)
Ejemplo n.º 3
0
    def get_connection(self):
        '''
        Create an ldapi connection and bind to it using autobind as root.
        '''
        instance_name = installutils.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.IPAdmin(host=api.env.host,
                                   ldapi=True,
                                   protocol='ldapi',
                                   realm=api.env.realm)

        try:
            pw_name = pwd.getpwuid(os.geteuid()).pw_name
            self._conn.do_external_bind(pw_name)
        except Exception as e:
            raise admintool.ScriptError('Unable to bind to LDAP server: %s'
                % e)
        return self._conn
Ejemplo n.º 4
0
    def __setup_sub_dict(self):
        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=installutils.realm_to_serverid(self.realm),
                             REALM=self.realm)

        # 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):
            root_logger.debug("IPA FQDN '%s' is not located in default domain '%s'",
                    fqdn, domain)
            server_domain = fqdn.parent().to_unicode(omit_final_dot=True)
            root_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():
            root_logger.debug("Enabling persistent keyring CCACHE")
            self.sub_dict['OTHER_LIBDEFAULTS'] = \
                " default_ccache_name = KEYRING:persistent:%{uid}\n"
        else:
            root_logger.debug("Persistent keyring CCACHE is not enabled")
            self.sub_dict['OTHER_LIBDEFAULTS'] = ''
Ejemplo n.º 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, like the PKI-IPA
              instance.
        '''
        serverid = installutils.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,
                paths.VAR_LIB_SLAPD_PKI_IPA_DIR_TEMPLATE,
                paths.USR_LIB_SLAPD_PKI_IPA_DIR,
                paths.ETC_SLAPD_PKI_IPA_DIR,
                paths.VAR_LIB_SLAPD_PKI_IPA_DIR_TEMPLATE,
                self.__find_scripts_dir('PKI-IPA'),
            ]:
            if os.path.exists(dir):
                self.dirs.append(dir)

        for file in [
                paths.SYSCONFIG_DIRSRV_INSTANCE % serverid,
                paths.SYSCONFIG_DIRSRV_PKI_IPA_DIR]:
            if os.path.exists(file):
                self.files.append(file)

        for log in [
            paths.VAR_LOG_DIRSRV_INSTANCE_TEMPLATE % serverid,
        ]:
            self.logs.append(log)
Ejemplo n.º 6
0
    def init_api(self, **overrides):
        api.bootstrap(in_server=False, context='restore', **overrides)
        api.finalize()

        self.instances = [
            installutils.realm_to_serverid(api.env.realm), 'PKI-IPA'
        ]
        self.backends = ['userRoot', 'ipaca']
Ejemplo n.º 7
0
    def find_subject_base(self):
        """
        Try to find the current value of certificate subject base.
        1) Look in sysupgrade first
        2) If no value is found there, look in DS (start DS if necessary)
        3) Last resort, look in the certmap.conf itself
        4) If all fails, log loudly and return None

        Note that this method can only be executed AFTER the ipa server
        is configured, the api is initialized elsewhere and
        that a ticket already have been acquired.
        """
        root_logger.debug("Trying to find certificate subject base in sysupgrade")
        subject_base = sysupgrade.get_upgrade_state("certmap.conf", "subject_base")

        if subject_base:
            root_logger.debug("Found certificate subject base in sysupgrade: %s", subject_base)
            return subject_base

        root_logger.debug("Unable to find certificate subject base in sysupgrade")
        root_logger.debug("Trying to find certificate subject base in DS")

        ds_is_running = is_ds_running()
        if not ds_is_running:
            try:
                self.start()
                ds_is_running = True
            except ipautil.CalledProcessError as e:
                root_logger.error("Cannot start DS to find certificate " "subject base: %s", e)

        if ds_is_running:
            try:
                ret = api.Command["config_show"]()
                subject_base = str(ret["result"]["ipacertificatesubjectbase"][0])
                root_logger.debug("Found certificate subject base in DS: %s", subject_base)
            except errors.PublicError as e:
                root_logger.error("Cannot connect to DS to find certificate " "subject base: %s", e)

        if not subject_base:
            root_logger.debug("Unable to find certificate subject base in DS")
            root_logger.debug("Trying to find certificate subject base in " "certmap.conf")

            certmap_dir = config_dirname(installutils.realm_to_serverid(api.env.realm))
            try:
                with open(os.path.join(certmap_dir, "certmap.conf")) as f:
                    for line in f:
                        if line.startswith("certmap ipaca"):
                            subject_base = line.strip().split(",")[-1]
                            root_logger.debug("Found certificate subject base in certmap.conf: " "%s", subject_base)

            except IOError as e:
                root_logger.error("Cannot open certmap.conf to find certificate " "subject base: %s", e.strerror)

        if subject_base:
            return subject_base

        root_logger.debug("Unable to find certificate subject base in " "certmap.conf")
        return None
Ejemplo n.º 8
0
def write_certmap_conf(realm, ca_subject):
    """(Re)write certmap.conf with given CA subject DN."""
    serverid = installutils.realm_to_serverid(realm)
    ds_dirname = config_dirname(serverid)
    certmap_filename = os.path.join(ds_dirname, "certmap.conf")
    shutil.copyfile(
        os.path.join(paths.USR_SHARE_IPA_DIR, "certmap.conf.template"),
        certmap_filename)
    installutils.update_file(certmap_filename, '$ISSUER_DN', str(ca_subject))
Ejemplo n.º 9
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([
                '/usr/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.
            ds = dsinstance.DsInstance()
            ds_running = ds.is_running()
            if ds_running:
                ds.stop(serverid)

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

            # DS has been marked as uninstalled so force the issue
            ds.stop_tracking_certificates(serverid)

            self.master.run_command([
                paths.REMOVE_DS_PL,
                '-i', instance_name
            ])

            cmd = self.master.run_command([
                'ipa-server-install',
                '--uninstall', '-U'],
                raiseonerr=False
            )
            assert cmd.returncode == 0
Ejemplo n.º 10
0
def set_subject_in_config(realm_name, dm_password, suffix, subject_base):
        ldapuri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % (
            installutils.realm_to_serverid(realm_name)
        )
        try:
            conn = ldap2(shared_instance=False, ldap_uri=ldapuri,
                         base_dn=suffix)
            conn.connect(bind_dn=DN(('cn', 'directory manager')),
                         bind_pw=dm_password)
        except errors.ExecutionError, e:
            root_logger.critical("Could not connect to the Directory Server "
                                 "on %s" % realm_name)
            raise e
Ejemplo n.º 11
0
 def __setup_sub_dict(self):
     self.sub_dict = dict(
         FQDN=self.fqdn,
         SERVER_ID=installutils.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=paths.NAMED_KEYTAB,
         RFC1912_ZONES=paths.NAMED_RFC1912_ZONES,
         NAMED_PID=paths.NAMED_PID,
         NAMED_VAR_DIR=paths.NAMED_VAR_DIR,
         )
Ejemplo n.º 12
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)
Ejemplo n.º 13
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")

        # If any of the PKCS#12 options are selected, all are required.
        cert_file_req = (options.dirsrv_cert_files, options.http_cert_files)
        if any(cert_file_req) and not all(cert_file_req):
            self.option_parser.error(
                "--dirsrv-cert-file and --http-cert-file are required if any "
                "key file 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, confdir=paths.ETC_IPA)
        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)
Ejemplo n.º 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=installutils.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'] = ''
Ejemplo n.º 15
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=installutils.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'] = ''
Ejemplo n.º 16
0
def set_subject_in_config(realm_name, dm_password, suffix, subject_base):
    ldapuri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % (
        installutils.realm_to_serverid(realm_name))
    try:
        conn = ldap2(api, ldap_uri=ldapuri)
        conn.connect(bind_dn=DN(('cn', 'directory manager')),
                     bind_pw=dm_password)
    except errors.ExecutionError as e:
        root_logger.critical("Could not connect to the Directory Server "
                             "on %s" % realm_name)
        raise e
    entry_attrs = conn.get_ipa_config()
    if 'ipacertificatesubjectbase' not in entry_attrs:
        entry_attrs['ipacertificatesubjectbase'] = [str(subject_base)]
        conn.update_entry(entry_attrs)
    conn.disconnect()
Ejemplo n.º 17
0
    def add_ca_cert(self, cacert_fname, cacert_name=''):
        """Add a CA certificate to the directory server cert db.  We
        first have to shut down the directory server in case it has
        opened the cert db read-only.  Then we use the CertDB class
        to add the CA cert.  We have to provide a nickname, and we
        do not use 'IPA CA' since that's the default, so
        we use 'Imported CA' if none specified.  Then we restart
        the server."""
        # first make sure we have a valid cacert_fname
        try:
            if not os.access(cacert_fname, os.R_OK):
                root_logger.critical(
                    "The given CA cert file named [%s] could not be read" %
                    cacert_fname)
                return False
        except OSError as e:
            root_logger.critical(
                "The given CA cert file named [%s] could not be read: %s" %
                (cacert_fname, str(e)))
            return False
        # ok - ca cert file can be read
        # shutdown the server
        self.stop()

        dirname = config_dirname(installutils.realm_to_serverid(self.realm))
        certdb = certs.CertDB(
            self.realm,
            nssdir=dirname,
            subject_base=self.subject_base,
            ca_subject=self.ca_subject,
        )
        if not cacert_name or len(cacert_name) == 0:
            cacert_name = "Imported CA"
        # we can't pass in the nickname, so we set the instance variable
        certdb.cacert_name = cacert_name
        status = True
        try:
            certdb.load_cacert(cacert_fname, 'C,,')
        except ipautil.CalledProcessError as e:
            root_logger.critical(
                "Error importing CA cert file named [%s]: %s" %
                (cacert_fname, str(e)))
            status = False
        # restart the directory server
        self.start()

        return status
Ejemplo n.º 18
0
    def init_info(self, realm_name, fqdn, domain_name, dm_password,
                  subject_base, idstart, idmax, pkcs12_info, ca_file=None):
        self.realm = realm_name.upper()
        self.serverid = installutils.realm_to_serverid(self.realm)
        self.suffix = ipautil.realm_to_suffix(self.realm)
        self.fqdn = fqdn
        self.dm_password = dm_password
        self.domain = domain_name
        self.subject_base = subject_base
        self.idstart = idstart
        self.idmax = idmax
        self.pkcs12_info = pkcs12_info
        if pkcs12_info:
            self.ca_is_configured = False
        self.ca_file = ca_file

        self.__setup_sub_dict()
Ejemplo n.º 19
0
def set_subject_in_config(realm_name, dm_password, suffix, subject_base):
        ldapuri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % (
            installutils.realm_to_serverid(realm_name)
        )
        try:
            conn = ldap2(api, ldap_uri=ldapuri)
            conn.connect(bind_dn=DN(('cn', 'directory manager')),
                         bind_pw=dm_password)
        except errors.ExecutionError as e:
            root_logger.critical("Could not connect to the Directory Server "
                                 "on %s" % realm_name)
            raise e
        entry_attrs = conn.get_ipa_config()
        if 'ipacertificatesubjectbase' not in entry_attrs:
            entry_attrs['ipacertificatesubjectbase'] = [str(subject_base)]
            conn.update_entry(entry_attrs)
        conn.disconnect()
Ejemplo n.º 20
0
    def __create_kra_agent(self):
        """
        Create KRA agent, assign a certificate, and add the user to
        the appropriate groups for accessing KRA services.
        """

        # get ipaCert certificate
        with certdb.NSSDatabase(paths.HTTPD_ALIAS_DIR) as ipa_nssdb:
            cert_data = ipa_nssdb.get_cert("ipaCert")
        cert = x509.load_certificate(cert_data, x509.DER)

        # connect to KRA database
        server_id = installutils.realm_to_serverid(api.env.realm)
        dogtag_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % server_id
        conn = ldap2.ldap2(api, ldap_uri=dogtag_uri)
        conn.connect(autobind=True)

        # create ipakra user with ipaCert certificate
        user_dn = DN(('uid', "ipakra"), ('ou', 'people'), self.basedn)
        entry = conn.make_entry(
            user_dn,
            objectClass=[
                'top', 'person', 'organizationalPerson', 'inetOrgPerson',
                'cmsuser'
            ],
            uid=["ipakra"],
            sn=["IPA KRA User"],
            cn=["IPA KRA User"],
            usertype=["undefined"],
            userCertificate=[cert_data],
            description=[
                '2;%s;%s;%s' %
                (cert.serial_number,
                 DN(('CN', 'Certificate Authority'),
                    self.subject_base), DN(
                        ('CN', 'IPA RA'), self.subject_base))
            ])
        conn.add_entry(entry)

        # add ipakra user to Data Recovery Manager Agents group
        group_dn = DN(('cn', 'Data Recovery Manager Agents'), ('ou', 'groups'),
                      self.basedn)
        conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember')

        conn.disconnect()
Ejemplo n.º 21
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([
                '/usr/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.
            ds = dsinstance.DsInstance()
            ds_running = ds.is_running()
            if ds_running:
                ds.stop(serverid)

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

            # DS has been marked as uninstalled so force the issue
            ds.stop_tracking_certificates(serverid)

            self.master.run_command([paths.REMOVE_DS_PL, '-i', instance_name])

            cmd = self.master.run_command(
                ['ipa-server-install', '--uninstall', '-U'], raiseonerr=False)
            assert cmd.returncode == 0
Ejemplo n.º 22
0
    def cert_restore_prepare(self):
        cainstance.CAInstance().stop_tracking_certificates()
        httpinstance.HTTPInstance().stop_tracking_certificates()
        try:
            dsinstance.DsInstance().stop_tracking_certificates(
                installutils.realm_to_serverid(api.env.realm))
        except OSError:
            # When IPA is not installed, DS NSS DB does not exist
            pass

        for basename in ('cert8.db', 'key3.db', 'secmod.db', 'pwdfile.txt'):
            filename = os.path.join(paths.IPA_NSSDB_DIR, basename)
            try:
                ipautil.backup_file(filename)
            except OSError as e:
                self.log.error("Failed to backup %s: %s" % (filename, e))

        tasks.remove_ca_certs_from_systemwide_ca_store()
Ejemplo n.º 23
0
    def init_info(
        self, realm_name, fqdn, domain_name, dm_password, subject_base, idstart, idmax, pkcs12_info, ca_file=None
    ):
        self.realm = realm_name.upper()
        self.serverid = installutils.realm_to_serverid(self.realm)
        self.suffix = ipautil.realm_to_suffix(self.realm)
        self.fqdn = fqdn
        self.dm_password = dm_password
        self.domain = domain_name
        self.subject_base = subject_base
        self.idstart = idstart
        self.idmax = idmax
        self.pkcs12_info = pkcs12_info
        if pkcs12_info:
            self.ca_is_configured = False
        self.ca_file = ca_file

        self.__setup_sub_dict()
Ejemplo n.º 24
0
    def cert_restore_prepare(self):
        cainstance.CAInstance().stop_tracking_certificates()
        httpinstance.HTTPInstance().stop_tracking_certificates()
        try:
            dsinstance.DsInstance().stop_tracking_certificates(
                installutils.realm_to_serverid(api.env.realm))
        except OSError:
            # When IPA is not installed, DS NSS DB does not exist
            pass

        for basename in ('cert8.db', 'key3.db', 'secmod.db', 'pwdfile.txt'):
            filename = os.path.join(paths.IPA_NSSDB_DIR, basename)
            try:
                ipautil.backup_file(filename)
            except OSError as e:
                self.log.error("Failed to backup %s: %s" % (filename, e))

        tasks.remove_ca_certs_from_systemwide_ca_store()
Ejemplo n.º 25
0
    def __setup_sub_dict(self):
        if self.forwarders:
            fwds = "\n"
            for forwarder in self.forwarders:
                fwds += "\t\t%s;\n" % forwarder
            fwds += "\t"
        else:
            fwds = " "

        if self.ntp:
            optional_ntp =  "\n;ntp server\n"
            optional_ntp += "_ntp._udp\t\tIN SRV 0 100 123\t%s" % self.host_in_rr
        else:
            optional_ntp = ""

        ipa_ca = ""
        for addr in self.ip_addresses:
            if addr.version in (4, 6):
                ipa_ca += "%s\t\t\tIN %s\t\t\t%s\n" % (
                    IPA_CA_RECORD,
                    "A" if addr.version == 4 else "AAAA",
                    str(addr))

        self.sub_dict = dict(
            FQDN=self.fqdn,
            IP=[str(ip) for ip in self.ip_addresses],
            DOMAIN=self.domain,
            HOST=self.host,
            REALM=self.realm,
            SERVER_ID=installutils.realm_to_serverid(self.realm),
            FORWARDERS=fwds,
            FORWARD_POLICY=self.forward_policy,
            SUFFIX=self.suffix,
            OPTIONAL_NTP=optional_ntp,
            ZONEMGR=self.zonemgr,
            IPA_CA_RECORD=ipa_ca,
            BINDKEYS_FILE=paths.NAMED_BINDKEYS_FILE,
            MANAGED_KEYS_DIR=paths.NAMED_MANAGED_KEYS_DIR,
            ROOT_KEY=paths.NAMED_ROOT_KEY,
            NAMED_KEYTAB=paths.NAMED_KEYTAB,
            RFC1912_ZONES=paths.NAMED_RFC1912_ZONES,
            NAMED_PID=paths.NAMED_PID,
            NAMED_VAR_DIR=paths.NAMED_VAR_DIR,
            )
Ejemplo n.º 26
0
    def add_ca_cert(self, cacert_fname, cacert_name=''):
        """Add a CA certificate to the directory server cert db.  We
        first have to shut down the directory server in case it has
        opened the cert db read-only.  Then we use the CertDB class
        to add the CA cert.  We have to provide a nickname, and we
        do not use 'IPA CA' since that's the default, so
        we use 'Imported CA' if none specified.  Then we restart
        the server."""
        # first make sure we have a valid cacert_fname
        try:
            if not os.access(cacert_fname, os.R_OK):
                logger.critical("The given CA cert file named [%s] could not "
                                "be read", cacert_fname)
                return False
        except OSError as e:
            logger.critical("The given CA cert file named [%s] could not "
                            "be read: %s", cacert_fname, str(e))
            return False
        # ok - ca cert file can be read
        # shutdown the server
        self.stop()

        dirname = config_dirname(installutils.realm_to_serverid(self.realm))
        certdb = certs.CertDB(
            self.realm,
            nssdir=dirname,
            subject_base=self.subject_base,
            ca_subject=self.ca_subject,
        )
        if not cacert_name or len(cacert_name) == 0:
            cacert_name = "Imported CA"
        # we can't pass in the nickname, so we set the instance variable
        certdb.cacert_name = cacert_name
        status = True
        try:
            certdb.load_cacert(cacert_fname, EXTERNAL_CA_TRUST_FLAGS)
        except ipautil.CalledProcessError as e:
            logger.critical("Error importing CA cert file named [%s]: %s",
                            cacert_fname, str(e))
            status = False
        # restart the directory server
        self.start()

        return status
Ejemplo n.º 27
0
    def __create_kra_agent(self):
        """
        Create KRA agent, assign a certificate, and add the user to
        the appropriate groups for accessing KRA services.
        """

        # get ipaCert certificate
        with certdb.NSSDatabase(paths.HTTPD_ALIAS_DIR) as ipa_nssdb:
            cert_data = ipa_nssdb.get_cert("ipaCert")
        cert = x509.load_certificate(cert_data, x509.DER)

        # connect to KRA database
        server_id = installutils.realm_to_serverid(api.env.realm)
        dogtag_uri = "ldapi://%%2fvar%%2frun%%2fslapd-%s.socket" % server_id
        conn = ldap2.ldap2(api, ldap_uri=dogtag_uri)
        conn.connect(autobind=True)

        # create ipakra user with ipaCert certificate
        user_dn = DN(("uid", "ipakra"), ("ou", "people"), self.basedn)
        entry = conn.make_entry(
            user_dn,
            objectClass=["top", "person", "organizationalPerson", "inetOrgPerson", "cmsuser"],
            uid=["ipakra"],
            sn=["IPA KRA User"],
            cn=["IPA KRA User"],
            usertype=["undefined"],
            userCertificate=[cert_data],
            description=[
                "2;%s;%s;%s"
                % (
                    cert.serial_number,
                    DN(("CN", "Certificate Authority"), self.subject_base),
                    DN(("CN", "IPA RA"), self.subject_base),
                )
            ],
        )
        conn.add_entry(entry)

        # add ipakra user to Data Recovery Manager Agents group
        group_dn = DN(("cn", "Data Recovery Manager Agents"), ("ou", "groups"), self.basedn)
        conn.add_entry_to_group(user_dn, group_dn, "uniqueMember")

        conn.disconnect()
Ejemplo n.º 28
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 = installutils.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
Ejemplo n.º 29
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
Ejemplo n.º 30
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 = installutils.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
Ejemplo n.º 31
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
Ejemplo n.º 32
0
    def cert_restore_prepare(self):
        cainstance.CAInstance().stop_tracking_certificates()
        httpinstance.HTTPInstance().stop_tracking_certificates()
        try:
            dsinstance.DsInstance().stop_tracking_certificates(
                installutils.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()
Ejemplo n.º 33
0
    def cert_restore_prepare(self):
        cainstance.CAInstance().stop_tracking_certificates()
        httpinstance.HTTPInstance().stop_tracking_certificates()
        try:
            dsinstance.DsInstance().stop_tracking_certificates(
                installutils.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()
Ejemplo n.º 34
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=installutils.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,
        )
Ejemplo n.º 35
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.samba_keytab = paths.SAMBA_KEYTAB
        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.domain_name = self.domain_name or api.env.domain

        self.cifs_principal = "cifs/" + self.fqdn + "@" + self.realm
        self.suffix = ipautil.realm_to_suffix(self.realm)
        self.ldapi_socket = "%%2fvar%%2frun%%2fslapd-%s.socket" % \
                            installutils.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', self.domain_name),
                             api.env.container_cifsdomains,
                             self.suffix)

        self.cifs_agent = DN(('krbprincipalname', self.cifs_principal.lower()),
                             api.env.container_service,
                             self.suffix)
        self.host_princ = DN(('fqdn', self.fqdn),
                             api.env.container_host,
                             self.suffix)
Ejemplo n.º 36
0
    def get_connection(self):
        '''
        Create an ldapi connection and bind to it using autobind as root.
        '''
        instance_name = installutils.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

        ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm)
        self._conn = ipaldap.LDAPClient(ldap_uri)

        try:
            self._conn.external_bind()
        except Exception as e:
            raise admintool.ScriptError('Unable to bind to LDAP server: %s' %
                                        e)
        return self._conn
Ejemplo n.º 37
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=installutils.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,
        )
Ejemplo n.º 38
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 = installutils.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,
        ):
            if os.path.exists(file):
                self.files.append(file)

        self.logs.append(paths.VAR_LOG_DIRSRV_INSTANCE_TEMPLATE % serverid)
Ejemplo n.º 39
0
    def get_connection(self):
        '''
        Create an ldapi connection and bind to it using autobind as root.
        '''
        instance_name = installutils.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

        ldap_uri = ipaldap.get_ldap_uri(protocol='ldapi', realm=api.env.realm)
        self._conn = ipaldap.LDAPClient(ldap_uri)

        try:
            self._conn.external_bind()
        except Exception as e:
            raise admintool.ScriptError('Unable to bind to LDAP server: %s'
                % e)
        return self._conn
Ejemplo n.º 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
    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)
Ejemplo n.º 41
0
def create_ipa_conf(fstore, config, ca_enabled, master=None):
    """
    Create /etc/ipa/default.conf master configuration
    :param fstore: sysrestore file store used for backup and restore of
                   the server configuration
    :param config: replica config
    :param ca_enabled: True if the topology includes a CA
    :param master: if set, the xmlrpc_uri parameter will use the provided
                   master instead of this host
    """
    # Save client file on Domain Level 1
    target_fname = paths.IPA_DEFAULT_CONF
    fstore.backup_file(target_fname)

    ipaconf = IPAChangeConf("IPA Replica Install")
    ipaconf.setOptionAssignment(" = ")
    ipaconf.setSectionNameDelimiters(("[", "]"))

    if master:
        xmlrpc_uri = 'https://{0}/ipa/xml'.format(
            ipautil.format_netloc(master))
    else:
        xmlrpc_uri = 'https://{0}/ipa/xml'.format(
            ipautil.format_netloc(config.host_name))
    ldapi_uri = 'ldapi://%2fvar%2frun%2fslapd-{0}.socket\n'.format(
        installutils.realm_to_serverid(config.realm_name))

    # [global] section
    gopts = [
        ipaconf.setOption('basedn', str(config.basedn)),
        ipaconf.setOption('host', config.host_name),
        ipaconf.setOption('realm', config.realm_name),
        ipaconf.setOption('domain', config.domain_name),
        ipaconf.setOption('xmlrpc_uri', xmlrpc_uri),
        ipaconf.setOption('ldap_uri', ldapi_uri),
        ipaconf.setOption('mode', 'production')
    ]

    if ca_enabled:
        gopts.extend([
            ipaconf.setOption('enable_ra', 'True'),
            ipaconf.setOption('ra_plugin', 'dogtag'),
            ipaconf.setOption('dogtag_version', '10')
        ])

        if not config.setup_ca:
            gopts.append(ipaconf.setOption('ca_host', config.ca_host_name))

    else:
        gopts.extend([
            ipaconf.setOption('enable_ra', 'False'),
            ipaconf.setOption('ra_plugin', 'None')
        ])

    opts = [
        ipaconf.setSection('global', gopts), {
            'name': 'empty',
            'type': 'empty'
        }
    ]
    ipaconf.newConf(target_fname, opts)
    # the new file must be readable for httpd
    # Also, umask applies when creating a new file but we want 0o644 here
    os.chmod(target_fname, 0o644)
Ejemplo n.º 42
0
                              '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()
Ejemplo n.º 43
0
def replica_krb_init_info(ansible_log,
                          fstore,
                          realm_name,
                          master_host_name,
                          host_name,
                          domain_name,
                          admin_password,
                          no_pkinit,
                          subject_base,
                          pkcs12_info=None):
    # promote is not needed here

    # From replicainstall.install_krb
    krb = krbinstance.KrbInstance(fstore=fstore)
    krb.set_output(ansible_log)

    # pkinit files
    if pkcs12_info is None:
        pkcs12_info = make_pkcs12_info(config.dir, "pkinitcert.p12",
                                       "pkinit_pin.txt")

    #krb.create_replica(realm_name,
    #                   master_host_name, host_name,
    #                   domain_name, dirman_password,
    #                   setup_pkinit, pkcs12_info,
    #                   subject_base=subject_base,
    #                   promote=promote)
    with redirect_stdout(ansible_log):
        krb.init_info(realm_name,
                      host_name,
                      setup_pkinit=not no_pkinit,
                      subject_base=subject_base)

        # From ipaserver.install.krbinstance.create_replica

        krb.pkcs12_info = pkcs12_info
        krb.subject_base = subject_base
        krb.master_fqdn = master_host_name
        krb.config_pkinit = not no_pkinit

        #krb.__common_setup(realm_name, host_name, domain_name, admin_password)
        krb.fqdn = host_name
        krb.realm = realm_name.upper()
        krb.host = host_name.split(".")[0]
        krb.ip = socket.getaddrinfo(host_name, None, socket.AF_UNSPEC,
                                    socket.SOCK_STREAM)[0][4][0]
        krb.domain = domain_name
        krb.suffix = ipautil.realm_to_suffix(krb.realm)
        krb.kdc_password = ipautil.ipa_generate_password()
        krb.admin_password = admin_password
        krb.dm_password = admin_password

        #krb.__setup_sub_dict()
        if os.path.exists(paths.COMMON_KRB5_CONF_DIR):
            includes = 'includedir {}'.format(paths.COMMON_KRB5_CONF_DIR)
        else:
            includes = ''

        krb.sub_dict = dict(FQDN=krb.fqdn,
                            IP=krb.ip,
                            PASSWORD=krb.kdc_password,
                            SUFFIX=krb.suffix,
                            DOMAIN=krb.domain,
                            HOST=krb.host,
                            SERVER_ID=installutils.realm_to_serverid(
                                krb.realm),
                            REALM=krb.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 = dnsname.from_text(krb.domain)
        fqdn = dnsname.from_text(krb.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=krb.realm)
        else:
            dr_map = ""
        krb.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")
            krb.sub_dict['OTHER_LIBDEFAULTS'] = \
                " default_ccache_name = KEYRING:persistent:%{uid}\n"
        else:
            logger.debug("Persistent keyring CCACHE is not enabled")
            krb.sub_dict['OTHER_LIBDEFAULTS'] = ''

    return krb
Ejemplo n.º 44
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.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 = installutils.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)
            self.finalize_backup(options.data_only, options.gpg,
                                 options.gpg_keyring)

            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'])

        finally:
            try:
                os.chdir(cwd)
            except Exception as e:
                logger.error('Cannot change directory to %s: %s', cwd, e)
            shutil.rmtree(self.top_dir)
Ejemplo n.º 45
0
    def run(self):
        options = self.options
        super(Backup, self).run()

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

        self.log.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.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:
                    self.log.info('Stopping Directory Server')
                    dirsrv.stop(capture_output=False)
            else:
                self.log.info('Stopping IPA services')
                run(['ipactl', 'stop'])

            instance = installutils.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)
            self.finalize_backup(options.data_only, options.gpg, options.gpg_keyring)

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

        finally:
            try:
                os.chdir(cwd)
            except Exception as e:
                self.log.error('Cannot change directory to %s: %s' % (cwd, e))
            shutil.rmtree(self.top_dir)
Ejemplo n.º 46
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()
Ejemplo n.º 47
0
    def find_subject_base(self):
        """
        Try to find the current value of certificate subject base.
        1) Look in sysupgrade first
        2) If no value is found there, look in DS (start DS if necessary)
        3) Last resort, look in the certmap.conf itself
        4) If all fails, log loudly and return None

        Note that this method can only be executed AFTER the ipa server
        is configured, the api is initialized elsewhere and
        that a ticket already have been acquired.
        """
        root_logger.debug(
            'Trying to find certificate subject base in sysupgrade')
        subject_base = sysupgrade.get_upgrade_state(
            'certmap.conf', 'subject_base')

        if subject_base:
            root_logger.debug(
                'Found certificate subject base in sysupgrade: %s',
                subject_base)
            return subject_base

        root_logger.debug(
            'Unable to find certificate subject base in sysupgrade')
        root_logger.debug(
            'Trying to find certificate subject base in DS')

        ds_is_running = is_ds_running()
        if not ds_is_running:
            try:
                self.start()
                ds_is_running = True
            except ipautil.CalledProcessError as e:
                root_logger.error('Cannot start DS to find certificate '
                                  'subject base: %s', e)

        if ds_is_running:
            try:
                ret = api.Command['config_show']()
                subject_base = str(
                    ret['result']['ipacertificatesubjectbase'][0])
                root_logger.debug(
                    'Found certificate subject base in DS: %s', subject_base)
            except errors.PublicError as e:
                root_logger.error('Cannot connect to DS to find certificate '
                                  'subject base: %s', e)

        if not subject_base:
            root_logger.debug('Unable to find certificate subject base in DS')
            root_logger.debug('Trying to find certificate subject base in '
                              'certmap.conf')

            certmap_dir = config_dirname(
                installutils.realm_to_serverid(api.env.realm)
            )
            try:
                with open(os.path.join(certmap_dir, 'certmap.conf')) as f:
                    for line in f:
                        if line.startswith('certmap ipaca'):
                            subject_base = line.strip().split(',')[-1]
                            root_logger.debug(
                                'Found certificate subject base in certmap.conf: '
                                '%s', subject_base)

            except IOError as e:
                root_logger.error('Cannot open certmap.conf to find certificate '
                                  'subject base: %s', e.strerror)

        if subject_base:
            return subject_base

        root_logger.debug('Unable to find certificate subject base in '
                          'certmap.conf')
        return None
Ejemplo n.º 48
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()
Ejemplo n.º 49
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':
            raise ScriptError('A selfsign CA can not be added')

        if ((not options.promote
             and not ipautil.file_exists(replica_config.dir + "/cacert.p12"))):
            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.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']:
            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',
                                'Signing-Cert'):
                    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(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)):
                    raise ScriptError(
                        "Certificate with subject %s is present in %s, "
                        "cannot continue." % (subject, db.secdir))
Ejemplo n.º 50
0
def install(options):
    global dirsrv_pkcs12_info
    global http_pkcs12_info
    global pkinit_pkcs12_info
    global external_cert_file
    global external_ca_file
    global http_ca_cert

    realm_name = options.realm_name
    domain_name = options.domain_name
    dm_password = options.dm_password
    master_password = options.master_password
    admin_password = options.admin_password
    host_name = options.host_name
    ip_addresses = options.ip_address
    setup_ca = options.setup_ca
    setup_kra = options.setup_kra

    global ds
    global installation_cleanup

    # Installation has started. No IPA sysrestore items are restored in case of
    # failure to enable root cause investigation
    installation_cleanup = False

    # Configuration for ipalib, we will bootstrap and finalize later, after
    # we are sure we have the configuration file ready.
    cfg = dict(
        context='installer',
        in_server=True,
        debug=options.debug
    )

    # Figure out what external CA step we're in. See cainstance.py for more
    # info on the 3 states.
    if options.external_cert_files:
        external = 2
    elif options.external_ca:
        external = 1
    else:
        external = 0

    # Create the management framework config file and finalize api
    target_fname = paths.IPA_DEFAULT_CONF
    fd = open(target_fname, "w")
    fd.write("[global]\n")
    fd.write("host=%s\n" % host_name)
    fd.write("basedn=%s\n" % ipautil.realm_to_suffix(realm_name))
    fd.write("realm=%s\n" % realm_name)
    fd.write("domain=%s\n" % domain_name)
    fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % format_netloc(host_name))
    fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" %
             installutils.realm_to_serverid(realm_name))
    if setup_ca:
        fd.write("enable_ra=True\n")
        fd.write("ra_plugin=dogtag\n")
        fd.write("dogtag_version=%s\n" %
                 dogtag.install_constants.DOGTAG_VERSION)
    else:
        fd.write("enable_ra=False\n")
        fd.write("ra_plugin=none\n")
    fd.write("enable_kra=%s\n" % setup_kra)
    fd.write("mode=production\n")
    fd.close()

    # Must be readable for everyone
    os.chmod(target_fname, 0644)

    if not options.unattended:
        print ""
        print "The following operations may take some minutes to complete."
        print "Please wait until the prompt is returned."
        print ""

    system_hostname = get_fqdn()
    if host_name != system_hostname:
        root_logger.debug("Chosen hostname (%s) differs from system hostname "
                          "(%s) - change it" % (host_name, system_hostname))
        # configure /etc/sysconfig/network to contain the custom hostname
        tasks.backup_and_replace_hostname(fstore, sstore, host_name)
        # update `api.env.ca_host` to correct hostname
        # https://fedorahosted.org/freeipa/ticket/4936
        api.env.ca_host = host_name

    api.bootstrap(**cfg)
    if setup_ca:
        # ensure profile backend is available
        import ipaserver.plugins.dogtag
    api.finalize()

    # Create DS user/group if it doesn't exist yet
    dsinstance.create_ds_user()

    # Create a directory server instance
    if external != 2:
        # Configure ntpd
        if options.conf_ntp:
            ipaclient.ntpconf.force_ntpd(sstore)
            ntp = ntpinstance.NTPInstance(fstore)
            if not ntp.is_configured():
                ntp.create_instance()

        if options.dirsrv_cert_files:
            ds = dsinstance.DsInstance(fstore=fstore,
                                       domainlevel=options.domainlevel)
            ds.create_instance(realm_name, host_name, domain_name,
                               dm_password, dirsrv_pkcs12_info,
                               idstart=options.idstart, idmax=options.idmax,
                               subject_base=options.subject,
                               hbac_allow=not options.hbac_allow)
        else:
            ds = dsinstance.DsInstance(fstore=fstore,
                                       domainlevel=options.domainlevel)
            ds.create_instance(realm_name, host_name, domain_name,
                               dm_password,
                               idstart=options.idstart, idmax=options.idmax,
                               subject_base=options.subject,
                               hbac_allow=not options.hbac_allow)
    else:
        ds = dsinstance.DsInstance(fstore=fstore,
                                   domainlevel=options.domainlevel)
        ds.init_info(
            realm_name, host_name, domain_name, dm_password,
            options.subject, 1101, 1100, None)

    if setup_ca:
        ca = cainstance.CAInstance(realm_name, certs.NSS_DIR,
                                   dogtag_constants=dogtag.install_constants)
        if external == 0:
            ca.configure_instance(
                host_name, domain_name, dm_password, dm_password,
                subject_base=options.subject,
                ca_signing_algorithm=options.ca_signing_algorithm)
        elif external == 1:
            # stage 1 of external CA installation
            options.realm_name = realm_name
            options.domain_name = domain_name
            options.master_password = master_password
            options.dm_password = dm_password
            options.admin_password = admin_password
            options.host_name = host_name
            options.unattended = True
            options.forwarders = dns.dns_forwarders
            options.reverse_zones = dns.reverse_zones
            write_cache(vars(options))
            ca.configure_instance(
                host_name, domain_name, dm_password, dm_password,
                csr_file=paths.ROOT_IPA_CSR,
                subject_base=options.subject,
                ca_signing_algorithm=options.ca_signing_algorithm,
                ca_type=options.external_ca_type)
        else:
            # stage 2 of external CA installation
            ca.configure_instance(
                host_name, domain_name, dm_password, dm_password,
                cert_file=external_cert_file.name,
                cert_chain_file=external_ca_file.name,
                subject_base=options.subject,
                ca_signing_algorithm=options.ca_signing_algorithm)

        # Now put the CA cert where other instances exepct it
        ca.publish_ca_cert(CACERT)
    else:
        # Put the CA cert where other instances expect it
        x509.write_certificate(http_ca_cert, CACERT)
        os.chmod(CACERT, 0444)

    # we now need to enable ssl on the ds
    ds.enable_ssl()

    if setup_ca:
        # We need to ldap_enable the CA now that DS is up and running
        ca.ldap_enable('CA', host_name, dm_password,
                       ipautil.realm_to_suffix(realm_name),
                       ['caRenewalMaster'])

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

    krb = krbinstance.KrbInstance(fstore)
    if options.pkinit_cert_files:
        krb.create_instance(realm_name, host_name, domain_name,
                            dm_password, master_password,
                            setup_pkinit=options.setup_pkinit,
                            pkcs12_info=pkinit_pkcs12_info,
                            subject_base=options.subject)
    else:
        krb.create_instance(realm_name, host_name, domain_name,
                            dm_password, master_password,
                            setup_pkinit=options.setup_pkinit,
                            subject_base=options.subject)

    # The DS instance is created before the keytab, add the SSL cert we
    # generated
    ds.add_cert_to_service()

    memcache = memcacheinstance.MemcacheInstance()
    memcache.create_instance('MEMCACHE', host_name, dm_password,
                             ipautil.realm_to_suffix(realm_name))

    otpd = otpdinstance.OtpdInstance()
    otpd.create_instance('OTPD', host_name, dm_password,
                         ipautil.realm_to_suffix(realm_name))

    # Create a HTTP instance
    http = httpinstance.HTTPInstance(fstore)
    if options.http_cert_files:
        http.create_instance(
            realm_name, host_name, domain_name, dm_password,
            pkcs12_info=http_pkcs12_info, subject_base=options.subject,
            auto_redirect=options.ui_redirect,
            ca_is_configured=setup_ca)
    else:
        http.create_instance(
            realm_name, host_name, domain_name, dm_password,
            subject_base=options.subject, auto_redirect=options.ui_redirect,
            ca_is_configured=setup_ca)
    tasks.restore_context(paths.CACHE_IPA_SESSIONS)

    # Export full CA chain
    ca_db = certs.CertDB(realm_name)
    os.chmod(CACERT, 0644)
    ca_db.publish_ca_cert(CACERT)

    set_subject_in_config(realm_name, dm_password,
                          ipautil.realm_to_suffix(realm_name), options.subject)

    # Apply any LDAP updates. Needs to be done after the configuration file
    # is created
    service.print_msg("Applying LDAP updates")
    ds.apply_updates()

    # Restart ds and krb after configurations have been changed
    service.print_msg("Restarting the directory server")
    ds.restart()

    service.print_msg("Restarting the KDC")
    krb.restart()

    if setup_ca:
        service.print_msg("Restarting the certificate server")
        ca.restart(dogtag.configured_constants().PKI_INSTANCE_NAME)

        service.print_msg("Importing certificate profiles")
        cainstance.import_included_profiles()

    if options.setup_dns:
        api.Backend.ldap2.connect(autobind=True)
        dns.install(False, False, options)
    else:
        # Create a BIND instance
        bind = bindinstance.BindInstance(fstore, dm_password)
        bind.setup(host_name, ip_addresses, realm_name,
                   domain_name, (), options.conf_ntp, (),
                   zonemgr=options.zonemgr, ca_configured=setup_ca,
                   no_dnssec_validation=options.no_dnssec_validation)
        bind.create_sample_bind_zone()

    # Restart httpd to pick up the new IPA configuration
    service.print_msg("Restarting the web server")
    http.restart()

    if setup_kra:
        kra.install(None, options, dm_password)

    # Set the admin user kerberos password
    ds.change_admin_password(admin_password)

    # Call client install script
    try:
        args = [paths.IPA_CLIENT_INSTALL, "--on-master", "--unattended",
                "--domain", domain_name, "--server", host_name,
                "--realm", realm_name, "--hostname", host_name]
        if not options.create_sshfp:
            args.append("--no-dns-sshfp")
        if options.trust_sshfp:
            args.append("--ssh-trust-dns")
        if not options.conf_ssh:
            args.append("--no-ssh")
        if not options.conf_sshd:
            args.append("--no-sshd")
        if options.mkhomedir:
            args.append("--mkhomedir")
        run(args)
    except Exception, e:
        sys.exit("Configuration of client side components failed!\n"
                 "ipa-client-install returned: " + str(e))
Ejemplo n.º 51
0
def install_check(installer):
    options = installer
    dirsrv_pkcs12_file = installer._dirsrv_pkcs12_file
    http_pkcs12_file = installer._http_pkcs12_file
    pkinit_pkcs12_file = installer._pkinit_pkcs12_file
    dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
    http_pkcs12_info = installer._http_pkcs12_info
    pkinit_pkcs12_info = installer._pkinit_pkcs12_info
    external_cert_file = installer._external_cert_file
    external_ca_file = installer._external_ca_file
    http_ca_cert = installer._ca_cert

    tasks.check_ipv6_stack_enabled()
    tasks.check_selinux_status()

    if options.master_password:
        msg = ("WARNING:\noption '-P/--master-password' is deprecated. "
               "KDC master password of sufficient strength is autogenerated "
               "during IPA server installation and should not be set "
               "manually.")
        print(textwrap.fill(msg, width=79, replace_whitespace=False))

    installer._installation_cleanup = True

    print("\nThe log file for this installation can be found in "
          "/var/log/ipaserver-install.log")
    if (not options.external_ca and not options.external_cert_files
            and is_ipa_configured()):
        installer._installation_cleanup = False
        raise ScriptError(
            "IPA server is already configured on this system.\n"
            "If you want to reinstall the IPA server, please uninstall "
            "it first using 'ipa-server-install --uninstall'.")

    client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
    if client_fstore.has_files():
        installer._installation_cleanup = False
        raise ScriptError(
            "IPA client is already configured on this system.\n"
            "Please uninstall it before configuring the IPA server, "
            "using 'ipa-client-install --uninstall'")

    fstore = sysrestore.FileStore(SYSRESTORE_DIR_PATH)
    sstore = sysrestore.StateFile(SYSRESTORE_DIR_PATH)

    # This will override any settings passed in on the cmdline
    if ipautil.file_exists(paths.ROOT_IPA_CACHE):
        if options.dm_password is not None:
            dm_password = options.dm_password
        else:
            dm_password = read_password("Directory Manager", confirm=False)
        if dm_password is None:
            raise ScriptError("Directory Manager password required")
        try:
            cache_vars = read_cache(dm_password)
            options.__dict__.update(cache_vars)
            if cache_vars.get('external_ca', False):
                options.external_ca = False
                options.interactive = False
        except Exception as e:
            raise ScriptError("Cannot process the cache file: %s" % str(e))

    # We only set up the CA if the PKCS#12 options are not given.
    if options.dirsrv_cert_files:
        setup_ca = False
    else:
        setup_ca = True
    options.setup_ca = setup_ca

    if not setup_ca and options.ca_subject:
        raise ScriptError(
            "--ca-subject cannot be used with CA-less installation")
    if not setup_ca and options.subject_base:
        raise ScriptError(
            "--subject-base cannot be used with CA-less installation")
    if not setup_ca and options.setup_kra:
        raise ScriptError(
            "--setup-kra cannot be used with CA-less installation")

    print("======================================="
          "=======================================")
    print("This program will set up the FreeIPA Server.")
    print("")
    print("This includes:")
    if setup_ca:
        print("  * Configure a stand-alone CA (dogtag) for certificate "
              "management")
    if not options.no_ntp:
        print("  * Configure the Network Time Daemon (ntpd)")
    print("  * Create and configure an instance of Directory Server")
    print("  * Create and configure a Kerberos Key Distribution Center (KDC)")
    print("  * Configure Apache (httpd)")
    if options.setup_kra:
        print("  * Configure KRA (dogtag) for secret management")
    if options.setup_dns:
        print("  * Configure DNS (bind)")
    if options.setup_adtrust:
        print("  * Configure Samba (smb) and winbind for managing AD trusts")
    if not options.no_pkinit:
        print("  * Configure the KDC to enable PKINIT")
    if options.no_ntp:
        print("")
        print("Excluded by options:")
        print("  * Configure the Network Time Daemon (ntpd)")
    if installer.interactive:
        print("")
        print("To accept the default shown in brackets, press the Enter key.")
    print("")

    if not options.external_cert_files:
        # Make sure the 389-ds ports are available
        check_dirsrv(not installer.interactive)

    if not options.no_ntp:
        try:
            ipaclient.install.ntpconf.check_timedate_services()
        except ipaclient.install.ntpconf.NTPConflictingService as e:
            print(
                ("WARNING: conflicting time&date synchronization service '%s'"
                 " will be disabled" % e.conflicting_service))
            print("in favor of ntpd")
            print("")
        except ipaclient.install.ntpconf.NTPConfigurationError:
            pass

    # Check to see if httpd is already configured to listen on 443
    if httpinstance.httpd_443_configured():
        raise ScriptError("Aborting installation")

    if not options.setup_dns and installer.interactive:
        if ipautil.user_input(
                "Do you want to configure integrated DNS "
                "(BIND)?", False):
            options.setup_dns = True
        print("")

    # check bind packages are installed
    if options.setup_dns:
        # Don't require an external DNS to say who we are if we are
        # setting up a local DNS server.
        options.no_host_dns = True

    # check the hostname is correctly configured, it must be as the kldap
    # utilities just use the hostname as returned by getaddrinfo to set
    # up some of the standard entries

    if options.host_name:
        host_default = options.host_name
    else:
        host_default = get_fqdn()

    try:
        if not installer.interactive or options.host_name:
            verify_fqdn(host_default, options.no_host_dns)
            host_name = host_default
        else:
            host_name = read_host_name(host_default, options.no_host_dns)
    except BadHostError as e:
        raise ScriptError(e)

    host_name = host_name.lower()
    root_logger.debug("will use host_name: %s\n" % host_name)

    if not options.domain_name:
        domain_name = read_domain_name(host_name[host_name.find(".") + 1:],
                                       not installer.interactive)
        root_logger.debug("read domain_name: %s\n" % domain_name)
        try:
            validate_domain_name(domain_name)
        except ValueError as e:
            raise ScriptError("Invalid domain name: %s" % unicode(e))
    else:
        domain_name = options.domain_name

    domain_name = domain_name.lower()

    if not options.realm_name:
        realm_name = read_realm_name(domain_name, not installer.interactive)
        root_logger.debug("read realm_name: %s\n" % realm_name)
    else:
        realm_name = options.realm_name.upper()

    if not options.subject_base:
        options.subject_base = installutils.default_subject_base(realm_name)

    if not options.ca_subject:
        options.ca_subject = \
            installutils.default_ca_subject_dn(options.subject_base)

    if options.http_cert_files:
        if options.http_pin is None:
            options.http_pin = installutils.read_password(
                "Enter Apache Server private key unlock",
                confirm=False,
                validate=False,
                retry=False)
            if options.http_pin is None:
                raise ScriptError(
                    "Apache Server private key unlock password required")
        http_pkcs12_file, http_pin, http_ca_cert = load_pkcs12(
            cert_files=options.http_cert_files,
            key_password=options.http_pin,
            key_nickname=options.http_cert_name,
            ca_cert_files=options.ca_cert_files,
            host_name=host_name)
        http_pkcs12_info = (http_pkcs12_file.name, http_pin)

    if options.dirsrv_cert_files:
        if options.dirsrv_pin is None:
            options.dirsrv_pin = read_password(
                "Enter Directory Server private key unlock",
                confirm=False,
                validate=False,
                retry=False)
            if options.dirsrv_pin is None:
                raise ScriptError(
                    "Directory Server private key unlock password required")
        dirsrv_pkcs12_file, dirsrv_pin, dirsrv_ca_cert = load_pkcs12(
            cert_files=options.dirsrv_cert_files,
            key_password=options.dirsrv_pin,
            key_nickname=options.dirsrv_cert_name,
            ca_cert_files=options.ca_cert_files,
            host_name=host_name)
        dirsrv_pkcs12_info = (dirsrv_pkcs12_file.name, dirsrv_pin)

    if options.pkinit_cert_files:
        if options.pkinit_pin is None:
            options.pkinit_pin = read_password(
                "Enter Kerberos KDC private key unlock",
                confirm=False,
                validate=False,
                retry=False)
            if options.pkinit_pin is None:
                raise ScriptError(
                    "Kerberos KDC private key unlock password required")
        pkinit_pkcs12_file, pkinit_pin, _pkinit_ca_cert = load_pkcs12(
            cert_files=options.pkinit_cert_files,
            key_password=options.pkinit_pin,
            key_nickname=options.pkinit_cert_name,
            ca_cert_files=options.ca_cert_files,
            host_name=host_name)
        pkinit_pkcs12_info = (pkinit_pkcs12_file.name, pkinit_pin)

    if (options.http_cert_files and options.dirsrv_cert_files
            and http_ca_cert != dirsrv_ca_cert):
        raise ScriptError(
            "Apache Server SSL certificate and Directory Server SSL "
            "certificate are not signed by the same CA certificate")

    if not options.dm_password:
        dm_password = read_dm_password()

        if dm_password is None:
            raise ScriptError("Directory Manager password required")
    else:
        dm_password = options.dm_password

    if not options.master_password:
        master_password = ipa_generate_password()
    else:
        master_password = options.master_password

    if not options.admin_password:
        admin_password = read_admin_password()
        if admin_password is None:
            raise ScriptError("IPA admin password required")
    else:
        admin_password = options.admin_password

    # Configuration for ipalib, we will bootstrap and finalize later, after
    # we are sure we have the configuration file ready.
    cfg = dict(
        context='installer',
        confdir=paths.ETC_IPA,
        in_server=True,
        # make sure host name specified by user is used instead of default
        host=host_name,
    )
    if setup_ca:
        # we have an IPA-integrated CA
        cfg['ca_host'] = host_name

    # Create the management framework config file and finalize api
    target_fname = paths.IPA_DEFAULT_CONF
    fd = open(target_fname, "w")
    fd.write("[global]\n")
    fd.write("host=%s\n" % host_name)
    fd.write("basedn=%s\n" % ipautil.realm_to_suffix(realm_name))
    fd.write("realm=%s\n" % realm_name)
    fd.write("domain=%s\n" % domain_name)
    fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % format_netloc(host_name))
    fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" %
             installutils.realm_to_serverid(realm_name))
    if setup_ca:
        fd.write("enable_ra=True\n")
        fd.write("ra_plugin=dogtag\n")
        fd.write("dogtag_version=10\n")
    else:
        fd.write("enable_ra=False\n")
        fd.write("ra_plugin=none\n")
    fd.write("mode=production\n")
    fd.close()

    # Must be readable for everyone
    os.chmod(target_fname, 0o644)

    api.bootstrap(**cfg)
    api.finalize()

    if setup_ca:
        ca.install_check(False, None, options)
    if options.setup_kra:
        kra.install_check(api, None, options)

    if options.setup_dns:
        dns.install_check(False, api, False, options, host_name)
        ip_addresses = dns.ip_addresses
    else:
        ip_addresses = get_server_ip_address(host_name,
                                             not installer.interactive, False,
                                             options.ip_addresses)

        # check addresses here, dns module is doing own check
        network_ip_address_warning(ip_addresses)
        broadcast_ip_address_warning(ip_addresses)

    if options.setup_adtrust:
        adtrust.install_check(False, options, api)

    # installer needs to update hosts file when DNS subsystem will be
    # installed or custom addresses are used
    if options.ip_addresses or options.setup_dns:
        installer._update_hosts_file = True

    print()
    print("The IPA Master Server will be configured with:")
    print("Hostname:       %s" % host_name)
    print("IP address(es): %s" % ", ".join(str(ip) for ip in ip_addresses))
    print("Domain name:    %s" % domain_name)
    print("Realm name:     %s" % realm_name)
    print()

    if options.setup_dns:
        print("BIND DNS server will be configured to serve IPA domain with:")
        print("Forwarders:       %s" %
              ("No forwarders" if not options.forwarders else ", ".join(
                  [str(ip) for ip in options.forwarders])))
        print('Forward policy:   %s' % options.forward_policy)
        print("Reverse zone(s):  %s" %
              ("No reverse zone" if options.no_reverse or not dns.reverse_zones
               else ", ".join(str(rz) for rz in dns.reverse_zones)))
        print()

    if not options.setup_adtrust:
        # If domain name and realm does not match, IPA server will not be able
        # to estabilish trust with Active Directory. Print big fat warning.

        realm_not_matching_domain = (domain_name.upper() != realm_name)

        if realm_not_matching_domain:
            print("WARNING: Realm name does not match the domain name.\n"
                  "You will not be able to estabilish trusts with Active "
                  "Directory unless\nthe realm name of the IPA server matches "
                  "its domain name.\n\n")

    if installer.interactive and not user_input(
            "Continue to configure the system with these values?", False):
        raise ScriptError("Installation aborted")

    options.realm_name = realm_name
    options.domain_name = domain_name
    options.dm_password = dm_password
    options.master_password = master_password
    options.admin_password = admin_password
    options._host_name_overridden = bool(options.host_name)
    options.host_name = host_name
    options.ip_addresses = ip_addresses

    installer._fstore = fstore
    installer._sstore = sstore
    installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file
    installer._http_pkcs12_file = http_pkcs12_file
    installer._pkinit_pkcs12_file = pkinit_pkcs12_file
    installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info
    installer._http_pkcs12_info = http_pkcs12_info
    installer._pkinit_pkcs12_info = pkinit_pkcs12_info
    installer._external_cert_file = external_cert_file
    installer._external_ca_file = external_ca_file
    installer._ca_cert = http_ca_cert
Ejemplo n.º 52
0
    def init_api(self, **overrides):
        api.bootstrap(in_server=True, context='restore', **overrides)
        api.finalize()

        self.instances = [installutils.realm_to_serverid(api.env.realm)]
        self.backends = ['userRoot', 'ipaca']
Ejemplo n.º 53
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 = six.text_type(replica_config.subject_base)
        options._ca_subject = lookup_ca_subject(_api, options._subject_base)

    if replica_config is not None and not replica_config.setup_ca:
        return

    if replica_config is not None:
        if standalone and api.env.ra_plugin == 'selfsign':
            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._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 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, nssdir=paths.PKI_TOMCAT_ALIAS_DIR,
                            subject_base=options._subject_base)
        dsdb = certs.CertDB(
            realm_name, nssdir=dirname, subject_base=options._subject_base)

        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(x509.load_certificate(cert).subject)
                if subject == DN(options._ca_subject):
                    raise ScriptError(
                        "Certificate with subject %s is present in %s, "
                        "cannot continue." % (subject, db.secdir))
Ejemplo n.º 54
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)
Ejemplo n.º 55
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, []
Ejemplo n.º 56
0
    def run(self):
        """Execute the tests"""

        api.Backend.ldap2.connect()

        self.serverid = installutils.realm_to_serverid(api.env.realm)

        self.ca = cainstance.CAInstance(api.env.realm, host_name=api.env.host)
        self.http = httpinstance.HTTPInstance()
        self.ds = dsinstance.DsInstance()

        self.conn = api.Backend.ldap2

        logger.info("Check CA status")
        self.check_ca_status()

        logger.info("Check tracking")
        self.check_tracking()

        logger.info("Check NSS trust")
        self.check_trust()

        logger.info("Check dates")
        self.check_dates()

        logger.info("Checking certificates in CS.cfg")
        self.check_cs_cfg()

        logger.info("Comparing certificates to requests in LDAP")
        self.compare_requests()

        logger.info("Checking RA certificate")
        self.check_ra_cert()

        logger.info("Checking authorities")
        self.check_ipa_to_cs_authorities()
        self.check_cs_to_ipa_authorities()

        logger.info("Checking host keytab")
        self.check_hostkeytab()

        logger.info("Validating certificates")
        self.validate_certs()

        logger.info("Checking renewal master")
        self.check_renewal_master()

        logger.info("End-to-end cert API test")
        self.cert_api_test()

        logger.info("Checking permissions and ownership")
        self.check_permissions()

        if self.conn is not None and self.conn.isconnected():
            self.conn.disconnect()

        if self.failures:
            logger.info("Failures:")
            for f in self.failures:
                logger.info(f)
        else:
            logger.info("All checks passed")

        if self.warnings:
            logger.info("Warnings:")
            for f in self.warnings:
                logger.info(f)

        return self.failures != []
Ejemplo n.º 57
0
def install_step_1(standalone, replica_config, options):
    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_name, host_name=host_name)

    ca.stop('pki-tomcat')

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

    serverid = installutils.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', pem=False)
        nickname = certdb.get_ca_nickname(realm_name)
        trust_flags = 'CT,C,C'
        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()