Esempio n. 1
0
def install_check(standalone, replica_config, options):
    global external_cert_file
    global external_ca_file

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

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

        if ((not options.promote
             and not ipautil.file_exists(replica_config.dir + "/cacert.p12"))):
            print('CA cannot be installed in CA-less setup.')
            sys.exit(1)

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

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

        return

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

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

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

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

    if standalone:
        dirname = dsinstance.config_dirname(
            installutils.realm_to_serverid(realm_name))
        cadb = certs.CertDB(realm_name, subject_base=subject_base)
        dsdb = certs.CertDB(realm_name, nssdir=dirname, subject_base=subject_base)

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

                cert = db.get_cert_from_db(nickname)
                if not cert:
                    continue
                subject = DN(str(x509.get_subject(cert)))
                if subject in (DN('CN=Certificate Authority', subject_base),
                               DN('CN=IPA RA', subject_base),
                               DN('CN=Object Signing Cert', subject_base)):
                    print(("Certificate with subject %s is present in %s, "
                           "cannot continue." % (subject, db.secdir)))
                    sys.exit(1)
Esempio n. 2
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))
Esempio n. 3
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))
Esempio n. 4
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 os.path.isfile(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:
            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 os.path.isfile(paths.ROOT_IPA_CSR):
            raise ScriptError(
                "CA CSR file %s already exists.\nIn order to continue "
                "remove the file and run the installer again." %
                paths.ROOT_IPA_CSR)

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

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

    if not options.external_cert_files:
        if not cainstance.check_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)

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

                cert = db.get_cert_from_db(nickname)
                if not cert:
                    continue
                subject = DN(cert.subject)
                if subject == DN(options._ca_subject):
                    raise ScriptError(
                        "Certificate with subject %s is present in %s, "
                        "cannot continue." % (subject, db.secdir))
Esempio n. 5
0
def install(filename, options):
    global config

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

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

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

        # Configure dirsrv
        ds = install_replica_ds(config)

        # Configure the CA if necessary
        CA = cainstance.install_replica_ca(config)

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

    # We need to ldap_enable the CA now that DS is up and running
    if CA and config.setup_ca:
        CA.ldap_enable('CA', config.host_name, config.dirman_password,
                       ipautil.realm_to_suffix(config.realm_name))

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

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

    if CA:
        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(config, options, config.dirman_password)
    else:
        service.print_msg("Restarting the directory server")
        ds.restart()

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

    if CA and config.setup_ca:
        service.print_msg("Restarting the certificate server")
        CA.restart(dogtag.configured_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")