Ejemplo n.º 1
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.º 2
0
def install(filename, options):
    global config

    dogtag_constants = dogtag.install_constants

    # Create the management framework config file
    # Note: We must do this before bootstraping and finalizing ipalib.api
    old_umask = os.umask(022)   # must be readable for httpd
    try:
        fd = open(paths.IPA_DEFAULT_CONF, "w")
        fd.write("[global]\n")
        fd.write("host=%s\n" % config.host_name)
        fd.write("basedn=%s\n" %
                 str(ipautil.realm_to_suffix(config.realm_name)))
        fd.write("realm=%s\n" % config.realm_name)
        fd.write("domain=%s\n" % config.domain_name)
        fd.write("xmlrpc_uri=https://%s/ipa/xml\n" %
                 ipautil.format_netloc(config.host_name))
        fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" %
                 installutils.realm_to_serverid(config.realm_name))
        if ipautil.file_exists(config.dir + "/cacert.p12"):
            fd.write("enable_ra=True\n")
            fd.write("ra_plugin=dogtag\n")
            fd.write("dogtag_version=%s\n" % dogtag_constants.DOGTAG_VERSION)
        else:
            fd.write("enable_ra=False\n")
            fd.write("ra_plugin=none\n")

        fd.write("enable_kra=%s\n" % config.setup_kra)

        fd.write("mode=production\n")
        fd.close()
    finally:
        os.umask(old_umask)

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

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

    cafile = config.dir + "/ca.crt"

    ldapuri = 'ldaps://%s' % ipautil.format_netloc(config.master_host_name)
    remote_api = create_api(mode=None)
    remote_api.bootstrap(in_server=True, context='installer',
                         ldap_uri=ldapuri, basedn=DN())
    remote_api.finalize()
    conn = remote_api.Backend.ldap2
    replman = None
    try:
        try:
            # Try out the password
            conn.connect(bind_dn=DIRMAN_DN, bind_pw=config.dirman_password,
                         tls_cacertfile=cafile)
            replman = ReplicationManager(config.realm_name,
                                         config.master_host_name,
                                         config.dirman_password)

            # Check that we don't already have a replication agreement
            try:
                (agreement_cn, agreement_dn) = replman.agreement_dn(
                    config.host_name)
                entry = conn.get_entry(agreement_dn, ['*'])
            except errors.NotFound:
                pass
            else:
                root_logger.info('Error: A replication agreement for this '
                                 'host already exists.')
                print('A replication agreement for this host already exists. '
                      'It needs to be removed.')
                print "Run this on the master that generated the info file:"
                print("    %% ipa-replica-manage del %s --force" %
                      config.host_name)
                sys.exit(3)

            # Detect the current domain level
            try:
                current = remote_api.Command['domainlevel_get']()['result']
            except errors.NotFound:
                # If we're joining an older master, domain entry is not
                # available
                current = 0

            # Detect if current level is out of supported range
            # for this IPA version
            under_lower_bound = current < constants.MIN_DOMAIN_LEVEL
            above_upper_bound = current > constants.MAX_DOMAIN_LEVEL

            if under_lower_bound or above_upper_bound:
                message = ("This version of FreeIPA does not support "
                           "the Domain Level which is currently set for "
                           "this domain. The Domain Level needs to be "
                           "raised before installing a replica with "
                           "this version is allowed to be installed "
                           "within this domain.")
                root_logger.error(message)
                print(message)
                sys.exit(3)

            # Check pre-existing host entry
            try:
                entry = conn.find_entries(u'fqdn=%s' % config.host_name,
                                          ['fqdn'], DN(api.env.container_host,
                                                       api.env.basedn))
            except errors.NotFound:
                pass
            else:
                root_logger.info('Error: Host %s already exists on the master '
                                 'server.' % config.host_name)
                print('The host %s already exists on the master server.' %
                      config.host_name)
                print "You should remove it before proceeding:"
                print "    %% ipa host-del %s" % config.host_name
                sys.exit(3)

            # Install CA cert so that we can do SSL connections with ldap
            install_ca_cert(conn, api.env.basedn, api.env.realm, cafile)

            dns_masters = remote_api.Object['dnsrecord'].get_dns_masters()
            if dns_masters:
                if not options.no_host_dns:
                    master = config.master_host_name
                    root_logger.debug('Check forward/reverse DNS resolution')
                    resolution_ok = (
                        check_dns_resolution(master, dns_masters) and
                        check_dns_resolution(config.host_name, dns_masters))
                    if not resolution_ok and not options.unattended:
                        if not ipautil.user_input("Continue?", False):
                            sys.exit(0)
            else:
                root_logger.debug('No IPA DNS servers, '
                                  'skipping forward/reverse resolution check')

        except errors.ACIError:
            sys.exit("\nThe password provided is incorrect for LDAP server "
                     "%s" % config.master_host_name)
        except errors.LDAPError:
            sys.exit("\nUnable to connect to LDAP server %s" %
                     config.master_host_name)
        finally:
            if replman and replman.conn:
                replman.conn.unbind()

        # Configure ntpd
        if options.conf_ntp:
            ipaclient.ntpconf.force_ntpd(sstore)
            ntp = ntpinstance.NTPInstance()
            ntp.create_instance()

        # Configure dirsrv
        ds = install_replica_ds(config)

        # Always try to install DNS records
        install_dns_records(config, options, remote_api)
    finally:
        if conn.isconnected():
            conn.disconnect()

    if config.setup_ca:
        options.realm_name = config.realm_name
        options.domain_name = config.domain_name
        options.dm_password = config.dirman_password
        options.host_name = config.host_name

        ca.install(False, config, options)

    krb = install_krb(config, setup_pkinit=options.setup_pkinit)
    http = install_http(config, auto_redirect=options.ui_redirect)

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

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

    # Apply any LDAP updates. Needs to be done after the replica is synced-up
    service.print_msg("Applying LDAP updates")
    ds.apply_updates()

    if options.setup_kra:
        kra.install(config, options, config.dirman_password)
    else:
        service.print_msg("Restarting the directory server")
        ds.restart()

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

    if config.setup_ca:
        dogtag_service = services.knownservices[dogtag_constants.SERVICE_NAME]
        dogtag_service.restart(dogtag_constants.PKI_INSTANCE_NAME)

    if options.setup_dns:
        api.Backend.ldap2.connect(autobind=True)
        dns.install(False, True, options)

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

    # Call client install script
    try:
        args = [paths.IPA_CLIENT_INSTALL, "--on-master", "--unattended",
                "--domain", config.domain_name, "--server", config.host_name,
                "--realm", config.realm_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")
        ipautil.run(args)
    except Exception, e:
        print "Configuration of client side components failed!"
        print "ipa-client-install returned: " + str(e)
        raise RuntimeError("Failed to configure the client")
Ejemplo n.º 3
0
    def run(self):
        options = self.options
        super(Restore, self).run()

        self.backup_dir = self.args[0]
        if not os.path.isabs(self.backup_dir):
            self.backup_dir = os.path.join(paths.IPA_BACKUP_DIR, self.backup_dir)

        self.log.info("Preparing restore from %s on %s",
                      self.backup_dir, constants.FQDN)

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

        try:
            self.read_header()
        except IOError as e:
            raise admintool.ScriptError("Cannot read backup metadata: %s" % e)

        if options.data_only:
            restore_type = 'DATA'
        else:
            restore_type = self.backup_type

        # These checks would normally be in the validate method but
        # we need to know the type of backup we're dealing with.
        if restore_type == 'FULL':
            if options.online:
                raise admintool.ScriptError(
                    "File restoration cannot be done online")
            if options.instance or options.backend:
                raise admintool.ScriptError(
                    "Restore must be in data-only mode when restoring a "
                    "specific instance or backend")
        else:
            installutils.check_server_configuration()

            self.init_api()

            if options.instance:
                instance_dir = (paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE %
                                options.instance)
                if not os.path.exists(instance_dir):
                    raise admintool.ScriptError(
                        "Instance %s does not exist" % options.instance)

                self.instances = [options.instance]

            if options.backend:
                for instance in self.instances:
                    db_dir = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
                              (instance, options.backend))
                    if os.path.exists(db_dir):
                        break
                else:
                    raise admintool.ScriptError(
                        "Backend %s does not exist" % options.backend)

                self.backends = [options.backend]

            for instance, backend in itertools.product(self.instances,
                                                       self.backends):
                db_dir = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
                          (instance, backend))
                if os.path.exists(db_dir):
                    break
            else:
                raise admintool.ScriptError(
                    "Cannot restore a data backup into an empty system")

        self.log.info("Performing %s restore from %s backup" %
                      (restore_type, self.backup_type))

        if self.backup_host != constants.FQDN:
            raise admintool.ScriptError(
                "Host name %s does not match backup name %s" %
                (constants.FQDN, self.backup_host))

        if self.backup_ipa_version != str(version.VERSION):
            self.log.warning(
                "Restoring data from a different release of IPA.\n"
                "Data is version %s.\n"
                "Server is running %s." %
                (self.backup_ipa_version, str(version.VERSION)))
            if (not options.unattended and
                    not user_input("Continue to restore?", False)):
                raise admintool.ScriptError("Aborted")

        create_ds_user()
        pent = pwd.getpwnam(DS_USER)

        # Temporary directory for decrypting files before restoring
        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, 0o750)

        os.chown(self.dir, pent.pw_uid, pent.pw_gid)

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

            self.extract_backup(options.gpg_keyring)

            if restore_type == 'FULL':
                self.restore_default_conf()
                self.init_api(confdir=self.dir + paths.ETC_IPA)

            databases = []
            for instance in self.instances:
                for backend in self.backends:
                    database = (instance, backend)
                    ldiffile = os.path.join(self.dir, '%s-%s.ldif' % database)
                    if os.path.exists(ldiffile):
                        databases.append(database)

            if options.instance:
                for instance, backend in databases:
                    if instance == options.instance:
                        break
                else:
                    raise admintool.ScriptError(
                        "Instance %s not found in backup" % options.instance)

            if options.backend:
                for instance, backend in databases:
                    if backend == options.backend:
                        break
                else:
                    raise admintool.ScriptError(
                        "Backend %s not found in backup" % options.backend)

            # Big fat warning
            if  (not options.unattended and
                not user_input("Restoring data will overwrite existing live data. Continue to restore?", False)):
                raise admintool.ScriptError("Aborted")

            self.log.info(
                "Each master will individually need to be re-initialized or")
            self.log.info(
                "re-created from this one. The replication agreements on")
            self.log.info(
                "masters running IPA 3.1 or earlier will need to be manually")
            self.log.info(
                "re-enabled. See the man page for details.")

            self.log.info("Disabling all replication.")
            self.disable_agreements()

            if restore_type != 'FULL':
                if not options.online:
                    self.log.info('Stopping Directory Server')
                    dirsrv.stop(capture_output=False)
                else:
                    self.log.info('Starting Directory Server')
                    dirsrv.start(capture_output=False)
            else:
                self.log.info('Stopping IPA services')
                (stdout, stderr, rc) = run(['ipactl', 'stop'], raiseonerr=False)
                if rc not in [0, 6]:
                    self.log.warn('Stopping IPA failed: %s' % stderr)

                self.restore_selinux_booleans()


            # We do either a full file restore or we restore data.
            if restore_type == 'FULL':
                if 'CA' in self.backup_services:
                    create_ca_user()
                self.cert_restore_prepare()
                self.file_restore(options.no_logs)
                self.cert_restore()
                if 'CA' in self.backup_services:
                    self.__create_dogtag_log_dirs()

            # Always restore the data from ldif
            # If we are restoring PKI-IPA then we need to restore the
            # userRoot backend in it and the main IPA instance. If we
            # have a unified instance we need to restore both userRoot and
            # ipaca.
            for instance, backend in databases:
                self.ldif2db(instance, backend, online=options.online)

            if restore_type != 'FULL':
                if not options.online:
                    self.log.info('Starting Directory Server')
                    dirsrv.start(capture_output=False)
            else:
                # restore access controll configuration
                auth_backup_path = os.path.join(paths.VAR_LIB_IPA, 'auth_backup')
                if os.path.exists(auth_backup_path):
                    tasks.restore_auth_configuration(auth_backup_path)
                # explicitly enable then disable the pki tomcatd service to
                # re-register its instance. FIXME, this is really wierd.
                services.knownservices.pki_tomcatd.enable()
                services.knownservices.pki_tomcatd.disable()

                self.log.info('Starting IPA services')
                run(['ipactl', 'start'])
                self.log.info('Restarting SSSD')
                sssd = services.service('sssd')
                sssd.restart()
                http = httpinstance.HTTPInstance()
                http.remove_httpd_ccache()
        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.º 4
0
    def run(self):
        options = self.options
        super(Restore, self).run()

        self.backup_dir = self.args[0]
        if not os.path.isabs(self.backup_dir):
            self.backup_dir = os.path.join(paths.IPA_BACKUP_DIR, self.backup_dir)

        self.log.info("Preparing restore from %s on %s",
                      self.backup_dir, FQDN)

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

        try:
            self.read_header()
        except IOError as e:
            raise admintool.ScriptError("Cannot read backup metadata: %s" % e)

        if options.data_only:
            restore_type = 'DATA'
        else:
            restore_type = self.backup_type

        # These checks would normally be in the validate method but
        # we need to know the type of backup we're dealing with.
        if restore_type == 'FULL':
            if options.online:
                raise admintool.ScriptError(
                    "File restoration cannot be done online")
            if options.instance or options.backend:
                raise admintool.ScriptError(
                    "Restore must be in data-only mode when restoring a "
                    "specific instance or backend")
        else:
            installutils.check_server_configuration()

            self.init_api()

            if options.instance:
                instance_dir = (paths.VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE %
                                options.instance)
                if not os.path.exists(instance_dir):
                    raise admintool.ScriptError(
                        "Instance %s does not exist" % options.instance)

                self.instances = [options.instance]

            if options.backend:
                for instance in self.instances:
                    db_dir = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
                              (instance, options.backend))
                    if os.path.exists(db_dir):
                        break
                else:
                    raise admintool.ScriptError(
                        "Backend %s does not exist" % options.backend)

                self.backends = [options.backend]

            for instance, backend in itertools.product(self.instances,
                                                       self.backends):
                db_dir = (paths.SLAPD_INSTANCE_DB_DIR_TEMPLATE %
                          (instance, backend))
                if os.path.exists(db_dir):
                    break
            else:
                raise admintool.ScriptError(
                    "Cannot restore a data backup into an empty system")

        self.log.info("Performing %s restore from %s backup" %
                      (restore_type, self.backup_type))

        if self.backup_host != FQDN:
            raise admintool.ScriptError(
                "Host name %s does not match backup name %s" %
                (FQDN, self.backup_host))

        if self.backup_ipa_version != str(version.VERSION):
            self.log.warning(
                "Restoring data from a different release of IPA.\n"
                "Data is version %s.\n"
                "Server is running %s." %
                (self.backup_ipa_version, str(version.VERSION)))
            if (not options.unattended and
                    not user_input("Continue to restore?", False)):
                raise admintool.ScriptError("Aborted")

        create_ds_user()
        pent = pwd.getpwnam(constants.DS_USER)

        # Temporary directory for decrypting files before restoring
        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)

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

            self.extract_backup(options.gpg_keyring)

            if restore_type == 'FULL':
                self.restore_default_conf()
                self.init_api(confdir=self.dir + paths.ETC_IPA)

            databases = []
            for instance in self.instances:
                for backend in self.backends:
                    database = (instance, backend)
                    ldiffile = os.path.join(self.dir, '%s-%s.ldif' % database)
                    if os.path.exists(ldiffile):
                        databases.append(database)

            if options.instance:
                for instance, backend in databases:
                    if instance == options.instance:
                        break
                else:
                    raise admintool.ScriptError(
                        "Instance %s not found in backup" % options.instance)

            if options.backend:
                for instance, backend in databases:
                    if backend == options.backend:
                        break
                else:
                    raise admintool.ScriptError(
                        "Backend %s not found in backup" % options.backend)

            # Big fat warning
            if  (not options.unattended and
                not user_input("Restoring data will overwrite existing live data. Continue to restore?", False)):
                raise admintool.ScriptError("Aborted")

            self.log.info(
                "Each master will individually need to be re-initialized or")
            self.log.info(
                "re-created from this one. The replication agreements on")
            self.log.info(
                "masters running IPA 3.1 or earlier will need to be manually")
            self.log.info(
                "re-enabled. See the man page for details.")

            self.log.info("Disabling all replication.")
            self.disable_agreements()

            if restore_type != 'FULL':
                if not options.online:
                    self.log.info('Stopping Directory Server')
                    dirsrv.stop(capture_output=False)
                else:
                    self.log.info('Starting Directory Server')
                    dirsrv.start(capture_output=False)
            else:
                self.log.info('Stopping IPA services')
                result = run(['ipactl', 'stop'], raiseonerr=False)
                if result.returncode not in [0, 6]:
                    self.log.warning('Stopping IPA failed: %s' % result.error_log)

                self.restore_selinux_booleans()

            http = httpinstance.HTTPInstance()

            # We do either a full file restore or we restore data.
            if restore_type == 'FULL':
                self.remove_old_files()
                if 'CA' in self.backup_services:
                    create_ca_user()
                self.cert_restore_prepare()
                self.file_restore(options.no_logs)
                self.cert_restore()
                if 'CA' in self.backup_services:
                    self.__create_dogtag_log_dirs()
                if http.is_kdcproxy_configured():
                    httpinstance.create_kdcproxy_user()

            # Always restore the data from ldif
            # We need to restore both userRoot and ipaca.
            for instance, backend in databases:
                self.ldif2db(instance, backend, online=options.online)

            if restore_type != 'FULL':
                if not options.online:
                    self.log.info('Starting Directory Server')
                    dirsrv.start(capture_output=False)
            else:
                # restore access controll configuration
                auth_backup_path = os.path.join(paths.VAR_LIB_IPA, 'auth_backup')
                if os.path.exists(auth_backup_path):
                    tasks.restore_auth_configuration(auth_backup_path)
                # explicitly enable then disable the pki tomcatd service to
                # re-register its instance. FIXME, this is really wierd.
                services.knownservices.pki_tomcatd.enable()
                services.knownservices.pki_tomcatd.disable()

                self.log.info('Starting IPA services')
                run(['ipactl', 'start'])
                self.log.info('Restarting SSSD')
                sssd = services.service('sssd', api)
                sssd.restart()
                http.remove_httpd_ccache()
        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.º 5
0
def install(installer):
    options = installer
    fstore = installer._fstore
    sstore = installer._sstore
    dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
    http_pkcs12_info = installer._http_pkcs12_info
    pkinit_pkcs12_info = installer._pkinit_pkcs12_info
    http_ca_cert = installer._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_addresses
    setup_ca = options.setup_ca

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

    if installer.interactive:
        print("")
        print("The following operations may take some minutes to complete.")
        print("Please wait until the prompt is returned.")
        print("")

    # set hostname (transient and static) if user instructed us to do so
    if options._host_name_overridden:
        tasks.backup_hostname(fstore, sstore)
        tasks.set_hostname(host_name)

    if installer._update_hosts_file:
        update_hosts_file(ip_addresses, host_name, fstore)

    http_instance = httpinstance.HTTPInstance()
    http_instance.create_cert_db()

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

    # Create a directory server instance
    if not options.external_cert_files:
        # Configure ntpd
        if not options.no_ntp:
            ipaclient.install.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,
                                       config_ldif=options.dirsrv_config_file)
            installer._ds = ds
            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.no_hbac_allow)
        else:
            ds = dsinstance.DsInstance(fstore=fstore,
                                       domainlevel=options.domainlevel,
                                       config_ldif=options.dirsrv_config_file)
            installer._ds = ds
            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.no_hbac_allow)

        ntpinstance.ntp_ldap_enable(host_name, ds.suffix, realm_name)

    else:
        api.Backend.ldap2.connect()
        ds = dsinstance.DsInstance(fstore=fstore,
                                   domainlevel=options.domainlevel)
        installer._ds = ds
        ds.init_info(
            realm_name, host_name, domain_name, dm_password,
            options.subject, 1101, 1100, None)

    if setup_ca:
        if not options.external_cert_files and options.external_ca:
            # 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.reverse_zones = dns.reverse_zones
            cache_vars = {n: options.__dict__[n] for o, n in installer.knobs()
                          if n in options.__dict__}
            write_cache(cache_vars)

        ca.install_step_0(False, None, options)

        # Now put the CA cert where other instances exepct it
        ca_instance = cainstance.CAInstance(realm_name, certs.NSS_DIR)
        ca_instance.publish_ca_cert(paths.IPA_CA_CRT)
    else:
        # Put the CA cert where other instances expect it
        x509.write_certificate(http_ca_cert, paths.IPA_CA_CRT)
        os.chmod(paths.IPA_CA_CRT, 0o444)

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

    krb = krbinstance.KrbInstance(fstore)
    krb.create_instance(realm_name, host_name, domain_name,
                        dm_password, master_password,
                        setup_pkinit=not options.no_pkinit,
                        pkcs12_info=pkinit_pkcs12_info,
                        subject_base=options.subject)

    # restart DS to enable ipa-pwd-extop plugin
    print("Restarting directory server to enable password extension plugin")
    ds.restart()

    if setup_ca:
        ca.install_step_1(False, None, options)
        kra.install(api, None, options)

    # 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,
                             ipautil.realm_to_suffix(realm_name))

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

    custodia = custodiainstance.CustodiaInstance(host_name, realm_name)
    custodia.create_instance()

    # Create a HTTP instance
    http = httpinstance.HTTPInstance(fstore)
    if options.http_cert_files:
        http.create_instance(
            realm_name, host_name, domain_name,
            pkcs12_info=http_pkcs12_info, subject_base=options.subject,
            auto_redirect=not options.no_ui_redirect,
            ca_is_configured=setup_ca)
    else:
        http.create_instance(
            realm_name, host_name, domain_name,
            subject_base=options.subject,
            auto_redirect=not options.no_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(paths.IPA_CA_CRT, 0o644)
    ca_db.publish_ca_cert(paths.IPA_CA_CRT)

    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. DS is restarted in the process.
    service.print_msg("Applying LDAP updates")
    ds.apply_updates()

    # Restart krb after configurations have been changed
    service.print_msg("Restarting the KDC")
    krb.restart()

    if options.setup_dns:
        dns.install(False, False, options)
    else:
        # Create a BIND instance
        bind = bindinstance.BindInstance(fstore)
        bind.setup(host_name, ip_addresses, realm_name,
                   domain_name, (), 'first', (),
                   zonemgr=options.zonemgr,
                   no_dnssec_validation=options.no_dnssec_validation)
        bind.create_file_with_system_records()

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

    # Call client install script
    service.print_msg("Configuring client side components")
    try:
        args = [paths.IPA_CLIENT_INSTALL, "--on-master", "--unattended",
                "--domain", domain_name, "--server", host_name,
                "--realm", realm_name, "--hostname", host_name]
        if options.no_dns_sshfp:
            args.append("--no-dns-sshfp")
        if options.ssh_trust_dns:
            args.append("--ssh-trust-dns")
        if options.no_ssh:
            args.append("--no-ssh")
        if options.no_sshd:
            args.append("--no-sshd")
        if options.mkhomedir:
            args.append("--mkhomedir")
        run(args, redirect_output=True)
        print()
    except Exception:
        raise ScriptError("Configuration of client side components failed!")

    # Everything installed properly, activate ipa service.
    services.knownservices.ipa.enable()

    print("======================================="
          "=======================================")
    print("Setup complete")
    print("")
    print("Next steps:")
    print("\t1. You must make sure these network ports are open:")
    print("\t\tTCP Ports:")
    print("\t\t  * 80, 443: HTTP/HTTPS")
    print("\t\t  * 389, 636: LDAP/LDAPS")
    print("\t\t  * 88, 464: kerberos")
    if options.setup_dns:
        print("\t\t  * 53: bind")
    print("\t\tUDP Ports:")
    print("\t\t  * 88, 464: kerberos")
    if options.setup_dns:
        print("\t\t  * 53: bind")
    if not options.no_ntp:
        print("\t\t  * 123: ntp")
    print("")
    print("\t2. You can now obtain a kerberos ticket using the command: "
          "'kinit admin'")
    print("\t   This ticket will allow you to use the IPA tools (e.g., ipa "
          "user-add)")
    print("\t   and the web user interface.")

    if not services.knownservices.ntpd.is_running():
        print("\t3. Kerberos requires time synchronization between clients")
        print("\t   and servers for correct operation. You should consider "
              "enabling ntpd.")

    print("")
    if setup_ca:
        print(("Be sure to back up the CA certificates stored in " +
              paths.CACERT_P12))
        print("These files are required to create replicas. The password for "
              "these")
        print("files is the Directory Manager password")
    else:
        print("In order for Firefox autoconfiguration to work you will need to")
        print("use a SSL signing certificate. See the IPA documentation for "
              "more details.")

    if ipautil.file_exists(paths.ROOT_IPA_CACHE):
        os.remove(paths.ROOT_IPA_CACHE)
Ejemplo n.º 6
0
def install(installer):
    options = installer
    fstore = installer._fstore
    sstore = installer._sstore
    config = installer._config

    dogtag_constants = dogtag.install_constants

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

    cafile = config.dir + "/ca.crt"

    remote_api = installer._remote_api
    conn = remote_api.Backend.ldap2
    try:
        conn.connect(bind_dn=DIRMAN_DN, bind_pw=config.dirman_password,
                     tls_cacertfile=cafile)

        # Install CA cert so that we can do SSL connections with ldap
        install_ca_cert(conn, api.env.basedn, api.env.realm, cafile)

        # Configure ntpd
        if not options.no_ntp:
            ipaclient.ntpconf.force_ntpd(sstore)
            ntp = ntpinstance.NTPInstance()
            ntp.create_instance()

        # Configure dirsrv
        ds = install_replica_ds(config)

        # Always try to install DNS records
        install_dns_records(config, options, remote_api)
    finally:
        if conn.isconnected():
            conn.disconnect()

    options.dm_password = config.dirman_password

    if config.setup_ca:
        options.realm_name = config.realm_name
        options.domain_name = config.domain_name
        options.host_name = config.host_name

        ca.install(False, config, options)

    krb = install_krb(config, setup_pkinit=not options.no_pkinit)
    http = install_http(config, auto_redirect=not options.no_ui_redirect)

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

    CA = cainstance.CAInstance(
        config.realm_name, certs.NSS_DIR,
        dogtag_constants=dogtag_constants)
    CA.dm_password = config.dirman_password

    CA.configure_certmonger_renewal()
    CA.import_ra_cert(config.dir + "/ra.p12")
    CA.fix_ra_perms()

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

    # Apply any LDAP updates. Needs to be done after the replica is synced-up
    service.print_msg("Applying LDAP updates")
    ds.apply_updates()

    if options.setup_kra:
        kra.install(api, config, options)
    else:
        service.print_msg("Restarting the directory server")
        ds.restart()

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

    if config.setup_ca:
        dogtag_service = services.knownservices[dogtag_constants.SERVICE_NAME]
        dogtag_service.restart(dogtag_constants.PKI_INSTANCE_NAME)

    if options.setup_dns:
        api.Backend.ldap2.connect(autobind=True)
        dns.install(False, True, options)

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

    # Call client install script
    try:
        args = [paths.IPA_CLIENT_INSTALL, "--on-master", "--unattended",
                "--domain", config.domain_name, "--server", config.host_name,
                "--realm", config.realm_name]
        if options.no_dns_sshfp:
            args.append("--no-dns-sshfp")
        if options.ssh_trust_dns:
            args.append("--ssh-trust-dns")
        if options.no_ssh:
            args.append("--no-ssh")
        if options.no_sshd:
            args.append("--no-sshd")
        if options.mkhomedir:
            args.append("--mkhomedir")
        ipautil.run(args)
    except Exception, e:
        print "Configuration of client side components failed!"
        print "ipa-client-install returned: " + str(e)
        raise RuntimeError("Failed to configure the client")
Ejemplo n.º 7
0
def install(installer):
    options = installer
    fstore = installer._fstore
    sstore = installer._sstore
    dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
    http_pkcs12_info = installer._http_pkcs12_info
    pkinit_pkcs12_info = installer._pkinit_pkcs12_info
    http_ca_cert = installer._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_addresses
    setup_ca = options.setup_ca

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

    if installer.interactive:
        print("")
        print("The following operations may take some minutes to complete.")
        print("Please wait until the prompt is returned.")
        print("")

    # set hostname (transient and static) if user instructed us to do so
    if options._host_name_overridden:
        tasks.backup_hostname(fstore, sstore)
        tasks.set_hostname(host_name)

    if installer._update_hosts_file:
        update_hosts_file(ip_addresses, host_name, fstore)

    http_instance = httpinstance.HTTPInstance()
    http_instance.create_cert_db()

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

    # Create a directory server instance
    if not options.external_cert_files:
        # Configure ntpd
        if not options.no_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,
                                       config_ldif=options.dirsrv_config_file)
            installer._ds = ds
            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.no_hbac_allow)
        else:
            ds = dsinstance.DsInstance(fstore=fstore,
                                       domainlevel=options.domainlevel,
                                       config_ldif=options.dirsrv_config_file)
            installer._ds = ds
            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.no_hbac_allow)

        ntpinstance.ntp_ldap_enable(host_name, ds.suffix, realm_name)

    else:
        api.Backend.ldap2.connect()
        ds = dsinstance.DsInstance(fstore=fstore,
                                   domainlevel=options.domainlevel)
        installer._ds = ds
        ds.init_info(realm_name, host_name, domain_name, dm_password,
                     options.subject, 1101, 1100, None)

    if setup_ca:
        if not options.external_cert_files and options.external_ca:
            # 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.reverse_zones = dns.reverse_zones
            cache_vars = {
                n: options.__dict__[n]
                for o, n in installer.knobs() if n in options.__dict__
            }
            write_cache(cache_vars)

        ca.install_step_0(False, None, options)

        # Now put the CA cert where other instances exepct it
        ca_instance = cainstance.CAInstance(realm_name, certs.NSS_DIR)
        ca_instance.publish_ca_cert(CACERT)
    else:
        # Put the CA cert where other instances expect it
        x509.write_certificate(http_ca_cert, CACERT)
        os.chmod(CACERT, 0o444)

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

    krb = krbinstance.KrbInstance(fstore)
    if options.pkinit_cert_files:
        krb.create_instance(realm_name,
                            host_name,
                            domain_name,
                            dm_password,
                            master_password,
                            setup_pkinit=not options.no_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=not options.no_pkinit,
                            subject_base=options.subject)

    # restart DS to enable ipa-pwd-extop plugin
    print("Restarting directory server to enable password extension plugin")
    ds.restart()

    if setup_ca:
        ca.install_step_1(False, None, options)

    # 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,
                             ipautil.realm_to_suffix(realm_name))

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

    custodia = custodiainstance.CustodiaInstance(host_name, realm_name)
    custodia.create_instance()

    # Create a HTTP instance
    http = httpinstance.HTTPInstance(fstore)
    if options.http_cert_files:
        http.create_instance(realm_name,
                             host_name,
                             domain_name,
                             pkcs12_info=http_pkcs12_info,
                             subject_base=options.subject,
                             auto_redirect=not options.no_ui_redirect,
                             ca_is_configured=setup_ca)
    else:
        http.create_instance(realm_name,
                             host_name,
                             domain_name,
                             subject_base=options.subject,
                             auto_redirect=not options.no_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, 0o644)
    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. DS is restarted in the process.
    service.print_msg("Applying LDAP updates")
    ds.apply_updates()

    # Restart krb after configurations have been changed
    service.print_msg("Restarting the KDC")
    krb.restart()

    if options.setup_dns:
        dns.install(False, False, options)
    else:
        # Create a BIND instance
        bind = bindinstance.BindInstance(fstore)
        bind.setup(host_name,
                   ip_addresses,
                   realm_name,
                   domain_name, (),
                   'first', (),
                   zonemgr=options.zonemgr,
                   no_dnssec_validation=options.no_dnssec_validation)
        bind.create_file_with_system_records()

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

    # Call client install script
    service.print_msg("Configuring client side components")
    try:
        args = [
            paths.IPA_CLIENT_INSTALL, "--on-master", "--unattended",
            "--domain", domain_name, "--server", host_name, "--realm",
            realm_name, "--hostname", host_name
        ]
        if options.no_dns_sshfp:
            args.append("--no-dns-sshfp")
        if options.ssh_trust_dns:
            args.append("--ssh-trust-dns")
        if options.no_ssh:
            args.append("--no-ssh")
        if options.no_sshd:
            args.append("--no-sshd")
        if options.mkhomedir:
            args.append("--mkhomedir")
        run(args, redirect_output=True)
        print()
    except Exception:
        raise ScriptError("Configuration of client side components failed!")

    # Everything installed properly, activate ipa service.
    services.knownservices.ipa.enable()

    print("======================================="
          "=======================================")
    print("Setup complete")
    print("")
    print("Next steps:")
    print("\t1. You must make sure these network ports are open:")
    print("\t\tTCP Ports:")
    print("\t\t  * 80, 443: HTTP/HTTPS")
    print("\t\t  * 389, 636: LDAP/LDAPS")
    print("\t\t  * 88, 464: kerberos")
    if options.setup_dns:
        print("\t\t  * 53: bind")
    print("\t\tUDP Ports:")
    print("\t\t  * 88, 464: kerberos")
    if options.setup_dns:
        print("\t\t  * 53: bind")
    if not options.no_ntp:
        print("\t\t  * 123: ntp")
    print("")
    print("\t2. You can now obtain a kerberos ticket using the command: "
          "'kinit admin'")
    print("\t   This ticket will allow you to use the IPA tools (e.g., ipa "
          "user-add)")
    print("\t   and the web user interface.")

    if not services.knownservices.ntpd.is_running():
        print("\t3. Kerberos requires time synchronization between clients")
        print("\t   and servers for correct operation. You should consider "
              "enabling ntpd.")

    print("")
    if setup_ca:
        print(("Be sure to back up the CA certificates stored in " +
               paths.CACERT_P12))
        print("These files are required to create replicas. The password for "
              "these")
        print("files is the Directory Manager password")
    else:
        print(
            "In order for Firefox autoconfiguration to work you will need to")
        print("use a SSL signing certificate. See the IPA documentation for "
              "more details.")

    if ipautil.file_exists(paths.ROOT_IPA_CACHE):
        os.remove(paths.ROOT_IPA_CACHE)
Ejemplo n.º 8
0
    def run(self):
        options = self.options
        super(Restore, self).run()

        api.bootstrap(in_server=False, context='restore')
        api.finalize()

        self.log.info("Preparing restore from %s on %s",
            self.backup_dir, api.env.host)

        if not options.instance:
            instances = []
            for instance in [realm_to_serverid(api.env.realm), 'PKI-IPA']:
                if os.path.exists('/var/lib/dirsrv/slapd-%s' % instance):
                    instances.append(instance)
        else:
            instances = [options.instance]
        if options.data_only and not instances:
            raise admintool.ScriptError('No instances to restore to')

        create_ds_group()
        create_ds_user()
        pent = pwd.getpwnam(DS_USER)

        # Temporary directory for decrypting files before restoring
        self.top_dir = tempfile.mkdtemp("ipa")
        os.chown(self.top_dir, pent.pw_uid, pent.pw_gid)
        os.chmod(self.top_dir, 0750)
        self.dir = os.path.join(self.top_dir, "ipa")
        os.mkdir(self.dir, 0750)

        os.chown(self.dir, pent.pw_uid, pent.pw_gid)

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

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

            self.read_header()
            # These two checks would normally be in the validate method but
            # we need to know the type of backup we're dealing with.
            if (self.backup_type != 'FULL' and not options.data_only and
                not instances):
                raise admintool.ScriptError('Cannot restore a data backup into an empty system')
            if (self.backup_type == 'FULL' and not options.data_only and
                (options.instance or options.backend)):
                raise admintool.ScriptError('Restore must be in data-only mode when restoring a specific instance or backend.')
            if self.backup_host != api.env.host:
                self.log.warning('Host name %s does not match backup name %s' %
                    (api.env.host, self.backup_host))
                if (not options.unattended and
                    not user_input("Continue to restore?", False)):
                    raise admintool.ScriptError("Aborted")
            if self.backup_ipa_version != str(version.VERSION):
                self.log.warning(
                    "Restoring data from a different release of IPA.\n"
                    "Data is version %s.\n"
                    "Server is running %s." %
                    (self.backup_ipa_version, str(version.VERSION)))
                if (not options.unattended and
                    not user_input("Continue to restore?", False)):
                    raise admintool.ScriptError("Aborted")

            # Big fat warning
            if  (not options.unattended and
                not user_input("Restoring data will overwrite existing live data. Continue to restore?", False)):
                raise admintool.ScriptError("Aborted")

            self.log.info(
                "Each master will individually need to be re-initialized or")
            self.log.info(
                "re-created from this one. The replication agreements on")
            self.log.info(
                "masters running IPA 3.1 or earlier will need to be manually")
            self.log.info(
                "re-enabled. See the man page for details.")

            self.log.info("Disabling all replication.")
            self.disable_agreements()

            self.extract_backup(options.gpg_keyring)
            if options.data_only:
                if not options.online:
                    self.log.info('Stopping Directory Server')
                    dirsrv.stop(capture_output=False)
                else:
                    self.log.info('Starting Directory Server')
                    dirsrv.start(capture_output=False)
            else:
                self.log.info('Stopping IPA services')
                (stdout, stderr, rc) = run(['ipactl', 'stop'], raiseonerr=False)
                if rc not in [0, 6]:
                    self.log.warn('Stopping IPA failed: %s' % stderr)


            # We do either a full file restore or we restore data.
            if self.backup_type == 'FULL' and not options.data_only:
                if options.online:
                    raise admintool.ScriptError('File restoration cannot be done online.')
                self.file_restore(options.no_logs)
                if 'CA' in self.backup_services:
                    self.__create_dogtag_log_dirs()

            # Always restore the data from ldif
            # If we are restoring PKI-IPA then we need to restore the
            # userRoot backend in it and the main IPA instance. If we
            # have a unified instance we need to restore both userRoot and
            # ipaca.
            for instance in instances:
                if os.path.exists('/var/lib/dirsrv/slapd-%s' % instance):
                    if options.backend is None:
                        self.ldif2db(instance, 'userRoot', online=options.online)
                        if os.path.exists('/var/lib/dirsrv/slapd-%s/db/ipaca' % instance):
                            self.ldif2db(instance, 'ipaca', online=options.online)
                    else:
                        self.ldif2db(instance, options.backend, online=options.online)
                else:
                    raise admintool.ScriptError('389-ds instance %s does not exist' % instance)

            if options.data_only:
                if not options.online:
                    self.log.info('Starting Directory Server')
                    dirsrv.start(capture_output=False)
            else:
                # explicitly enable then disable the pki tomcatd service to
                # re-register its instance. FIXME, this is really wierd.
                ipaservices.knownservices.pki_tomcatd.enable()
                ipaservices.knownservices.pki_tomcatd.disable()

                self.log.info('Starting IPA services')
                run(['ipactl', 'start'])
                self.log.info('Restarting SSSD')
                sssd = ipaservices.service('sssd')
                sssd.restart()
        finally:
            try:
                os.chdir(cwd)
            except Exception, e:
                self.log.error('Cannot change directory to %s: %s' % (cwd, e))
            shutil.rmtree(self.top_dir)