Пример #1
0
def read_dns_forwarders():
    addrs = []
    if ipautil.user_input("Do you want to configure DNS forwarders?", True):
        print("Following DNS servers are configured in /etc/resolv.conf: %s" %
                ", ".join(resolver.get_default_resolver().nameservers))
        if ipautil.user_input("Do you want to configure these servers as DNS "
                "forwarders?", True):
            addrs = resolver.default_resolver.nameservers[:]
            print("All DNS servers from /etc/resolv.conf were added. You can "
                  "enter additional addresses now:")
        while True:
            ip = ipautil.user_input("Enter an IP address for a DNS forwarder, "
                                    "or press Enter to skip", allow_empty=True)
            if not ip:
                break
            try:
                ip_parsed = ipautil.CheckedIPAddress(ip, parse_netmask=False)
            except Exception as e:
                print("Error: Invalid IP Address %s: %s" % (ip, e))
                print("DNS forwarder %s not added." % ip)
                continue

            print("DNS forwarder %s added. You may add another." % ip)
            addrs.append(str(ip_parsed))

    if not addrs:
        print("No DNS forwarders configured")

    return addrs
Пример #2
0
def install_check(standalone, options, api):
    global netbios_name
    global reset_netbios_name

    if not standalone:
        check_for_installed_deps()

    realm_not_matching_domain = (api.env.domain.upper() != api.env.realm)

    if realm_not_matching_domain:
        print("WARNING: Realm name does not match the domain name.\n"
              "You will not be able to estabilish trusts with Active "
              "Directory unless\nthe realm name of the IPA server matches its "
              "domain name.\n\n")
        if not options.unattended:
            if not ipautil.user_input("Do you wish to continue?",
                                      default=False,
                                      allow_empty=False):
                raise ScriptError("Aborting installation.")

    # Check if /etc/samba/smb.conf already exists. In case it was not generated
    # by IPA, print a warning that we will break existing configuration.

    if adtrustinstance.ipa_smb_conf_exists():
        if not options.unattended:
            print("IPA generated smb.conf detected.")
            if not ipautil.user_input("Overwrite smb.conf?",
                                      default=False,
                                      allow_empty=False):
                raise ScriptError("Aborting installation.")

    elif os.path.exists(paths.SMB_CONF):
        print("WARNING: The smb.conf already exists. Running "
              "ipa-adtrust-install will break your existing samba "
              "configuration.\n\n")
        if not options.unattended:
            if not ipautil.user_input("Do you wish to continue?",
                                      default=False,
                                      allow_empty=False):
                raise ScriptError("Aborting installation.")
    elif os.path.exists(paths.SMB_CONF):
        print("WARNING: The smb.conf already exists. Running "
              "ipa-adtrust-install will break your existing samba "
              "configuration.\n\n")
        if not options.unattended:
            if not ipautil.user_input("Do you wish to continue?",
                                      default=False,
                                      allow_empty=False):
                raise ScriptError("Aborting installation.")

    if not options.unattended and not options.enable_compat:
        options.enable_compat = enable_compat_tree()

    netbios_name, reset_netbios_name = set_and_check_netbios_name(
        options.netbios_name, options.unattended, api)

    if not options.add_sids:
        retrieve_and_ask_about_sids(api, options)
Пример #3
0
def uninstall_check(options):
    """Check if the host is CRL generation master"""
    # Skip the checks if the host is not a CA instance
    ca = cainstance.CAInstance(api.env.realm)
    if not (api.Command.ca_is_enabled()['result'] and
       cainstance.is_ca_installed_locally()):
        return

    # skip the checks if the host is the last master
    ipa_config = api.Command.config_show()['result']
    ipa_masters = ipa_config.get('ipa_master_server', [])
    if len(ipa_masters) <= 1:
        return

    try:
        crlgen_enabled = ca.is_crlgen_enabled()
    except cainstance.InconsistentCRLGenConfigException:
        # If config is inconsistent, let's be safe and act as if
        # crl gen was enabled
        crlgen_enabled = True

    if crlgen_enabled:
        print("Deleting this server will leave your installation "
              "without a CRL generation master.")
        if (options.unattended and not options.ignore_last_of_role) or \
           not (options.unattended or ipautil.user_input(
                "Are you sure you want to continue with the uninstall "
                "procedure?", False)):
            raise ScriptError("Aborting uninstall operation.")
Пример #4
0
def retrieve_and_ask_about_sids(api, options):
    entries = []
    if api.Backend.ldap2.isconnected():
        entries = retrieve_entries_without_sid(api)
    else:
        logger.debug(
            "LDAP backend not connected, can not retrieve entries "
            "with missing SID")

    object_count = len(entries)
    if object_count > 0:
        print("")
        print("WARNING: %d existing users or groups do not have "
              "a SID identifier assigned." % len(entries))
        print("Installer can run a task to have ipa-sidgen "
              "Directory Server plugin generate")
        print("the SID identifier for all these users. Please note, "
              "in case of a high")
        print("number of users and groups, the operation might "
              "lead to high replication")
        print("traffic and performance degradation. Refer to "
              "ipa-adtrust-install(1) man page")
        print("for details.")
        print("")
        if options.unattended:
            print("Unattended mode was selected, installer will "
                  "NOT run ipa-sidgen task!")
        else:
            if ipautil.user_input(
                    "Do you want to run the ipa-sidgen task?",
                    default=False,
                    allow_empty=False):
                options.add_sids = True
Пример #5
0
def add_ca_schema():
    """Copy IPA schema files into the CA DS instance
    """
    pki_pent = pwd.getpwnam(PKI_USER)
    ds_pent = pwd.getpwnam(DS_USER)
    for schema_fname in SCHEMA_FILENAMES:
        source_fname = os.path.join(paths.USR_SHARE_IPA_DIR, schema_fname)
        target_fname = os.path.join(schema_dirname(SERVERID), schema_fname)
        if not os.path.exists(source_fname):
            root_logger.debug("File does not exist: %s", source_fname)
            continue
        if os.path.exists(target_fname):
            target_sha1 = _sha1_file(target_fname)
            source_sha1 = _sha1_file(source_fname)
            if target_sha1 != source_sha1:
                target_size = os.stat(target_fname).st_size
                source_size = os.stat(source_fname).st_size
                root_logger.info("Target file %s exists but the content is " "different", target_fname)
                root_logger.info("\tTarget file: sha1: %s, size: %s B", target_sha1, target_size)
                root_logger.info("\tSource file: sha1: %s, size: %s B", source_sha1, source_size)
                if not ipautil.user_input("Do you want replace %s file?" % target_fname, True):
                    continue

            else:
                root_logger.info("Target exists, not overwriting: %s", target_fname)
                continue
        try:
            shutil.copyfile(source_fname, target_fname)
        except IOError as e:
            root_logger.warning("Could not install %s: %s", target_fname, e)
        else:
            root_logger.info("Installed %s", target_fname)
        os.chmod(target_fname, 0o440)  # read access for dirsrv user/group
        os.chown(target_fname, pki_pent.pw_uid, ds_pent.pw_gid)
Пример #6
0
def read_domain_name(domain_name, unattended):
    print("The domain name has been determined based on the host name.")
    print("")
    if not unattended:
        domain_name = str(user_input("Please confirm the domain name",
                                     domain_name))
        print("")
    return domain_name
Пример #7
0
def read_dns_forwarders():
    addrs = []
    if ipautil.user_input("Do you want to configure DNS forwarders?", True):
        while True:
            ip = ipautil.user_input("Enter an IP address for a DNS forwarder, "
                                    "or press Enter to skip", allow_empty=True)
            if not ip:
                break
            try:
                ip_parsed = ipautil.CheckedIPAddress(ip, parse_netmask=False)
            except Exception, e:
                print "Error: Invalid IP Address %s: %s" % (ip, e)
                print "DNS forwarder %s not added." % ip
                continue

            print "DNS forwarder %s added. You may add another." % ip
            addrs.append(str(ip_parsed))
Пример #8
0
def check_reverse_zones(ip_addresses, reverse_zones, options, unattended,
                        search_reverse_zones=False):
    checked_reverse_zones = []

    if (not options.no_reverse and not reverse_zones
            and not options.auto_reverse):
        if unattended:
            options.no_reverse = True
        else:
            options.no_reverse = not create_reverse()

    # shortcut
    if options.no_reverse:
        return []

    # verify zones passed in options
    for rz in reverse_zones:
        # isn't the zone managed by someone else
        if not options.allow_zone_overlap:
            try:
                ipautil.check_zone_overlap(rz)
            except ValueError as e:
                msg = "Reverse zone %s will not be used: %s" % (rz, e)
                if unattended:
                    sys.exit(msg)
                else:
                    root_logger.warning(msg)
                continue
        checked_reverse_zones.append(normalize_zone(rz))

    # check that there is reverse zone for every IP
    ips_missing_reverse = []
    for ip in ip_addresses:
        if search_reverse_zones and find_reverse_zone(str(ip)):
            # reverse zone is already in LDAP
            continue
        for rz in checked_reverse_zones:
            if verify_reverse_zone(rz, ip):
                # reverse zone was entered by user
                break
        else:
            ips_missing_reverse.append(ip)

    # create reverse zone for IP addresses that does not have one
    for (ip, rz) in get_auto_reverse_zones(ips_missing_reverse):
        if options.auto_reverse:
            root_logger.info("Reverse zone %s will be created" % rz)
            checked_reverse_zones.append(rz)
        elif unattended:
            root_logger.warning("Missing reverse record for IP address %s"
                                % ip)
        else:
            if ipautil.user_input("Do you want to create reverse zone for IP "
                                  "%s" % ip, True):
                rz = read_reverse_zone(rz, str(ip), options.allow_zone_overlap)
                checked_reverse_zones.append(rz)

    return checked_reverse_zones
Пример #9
0
def read_reverse_zone(default, ip_address):
    while True:
        zone = ipautil.user_input("Please specify the reverse zone name", default=default)
        if not zone:
            return None
        if verify_reverse_zone(zone, ip_address):
            break

    return normalize_zone(zone)
Пример #10
0
def read_ip_address(host_name, fstore):
    while True:
        ip = ipautil.user_input("Please provide the IP address to be used for this host name", allow_empty = False)
        try:
            ip_parsed = ipautil.CheckedIPAddress(ip, match_local=True)
        except Exception, e:
            print "Error: Invalid IP Address %s: %s" % (ip, e)
            continue
        else:
            break
Пример #11
0
def read_reverse_zone(default, ip_address):
    while True:
        zone = ipautil.user_input("Please specify the reverse zone name", default=default)
        if not zone:
            return None
        if verify_reverse_zone(zone, ip_address):
            break
        else:
            print "Invalid reverse zone %s for IP address %s" % (zone, ip_address)

    return normalize_zone(zone)
Пример #12
0
def read_realm_name(domain_name, unattended):
    print("The kerberos protocol requires a Realm name to be defined.")
    print("This is typically the domain name converted to uppercase.")
    print("")

    if unattended:
        return domain_name.upper()
    realm_name = str(user_input("Please provide a realm name",
                                domain_name.upper()))
    upper_dom = realm_name.upper()
    if upper_dom != realm_name:
        print("An upper-case realm name is required.")
        if not user_input("Do you want to use " + upper_dom +
                          " as realm name?", True):
            raise ScriptError(
                "An upper-case realm name is required. Unable to continue.")
        else:
            realm_name = upper_dom
        print("")
    return realm_name
Пример #13
0
def uninstall_check(options):
    # test if server is DNSSEC key master
    masters = opendnssecinstance.get_dnssec_key_masters(api.Backend.ldap2)
    if api.env.host in masters:
        print("This server is active DNSSEC key master. Uninstall could break your DNS system.")
        if not (options.unattended or user_input(
                "Are you sure you want to continue with the uninstall "
                "procedure?", False)):
            print("")
            print("Aborting uninstall operation.")
            sys.exit(1)
Пример #14
0
def enable_compat_tree():
    print("Do you want to enable support for trusted domains in Schema "
          "Compatibility plugin?")
    print("This will allow clients older than SSSD 1.9 and non-Linux "
          "clients to work with trusted users.")
    print("")
    enable_compat = ipautil.user_input(
        "Enable trusted domains support in slapi-nis?",
        default=False,
        allow_empty=False)
    print("")
    return enable_compat
Пример #15
0
def read_ip_addresses(host_name, fstore):
    ips = []
    print "Enter the IP address to use, or press Enter to finish."
    while True:
        ip = ipautil.user_input("Please provide the IP address to be used for this host name", allow_empty = True)
        if not ip:
            break
        try:
            ip_parsed = ipautil.CheckedIPAddress(ip, match_local=True)
        except Exception, e:
            print "Error: Invalid IP Address %s: %s" % (ip, e)
            continue
        ips.append(ip_parsed)
Пример #16
0
def read_host_name(host_default, no_host_dns=False):
    print("Enter the fully qualified domain name of the computer")
    print("on which you're setting up server software. Using the form")
    print("<hostname>.<domainname>")
    print("Example: master.example.com.")
    print("")
    print("")
    if host_default == "":
        host_default = "master.example.com"
    host_name = user_input("Server host name", host_default, allow_empty=False)
    print("")
    verify_fqdn(host_name, no_host_dns)

    return host_name
Пример #17
0
def read_host_name(host_default, no_host_dns=False):
    print("Enter the fully qualified domain name of the computer")
    print("on which you're setting up server software. Using the form")
    print("<hostname>.<domainname>")
    print("Example: master.example.com.")
    print("")
    print("")
    if host_default == "":
        host_default = "master.example.com"
    host_name = user_input("Server host name", host_default, allow_empty=False)
    print("")
    verify_fqdn(host_name, no_host_dns)

    return host_name
Пример #18
0
def read_ip_addresses(host_name, fstore):
    ips = []
    print "Enter the IP address to use, or press Enter to finish."
    while True:
        ip = ipautil.user_input(
            "Please provide the IP address to be used for this host name",
            allow_empty=True)
        if not ip:
            break
        try:
            ip_parsed = ipautil.CheckedIPAddress(ip, match_local=True)
        except Exception, e:
            print "Error: Invalid IP Address %s: %s" % (ip, e)
            continue
        ips.append(ip_parsed)
Пример #19
0
def read_host_name(host_default):
    """
    Prompt user to input FQDN.  Does not verify it.

    """
    print("Enter the fully qualified domain name of the computer")
    print("on which you're setting up server software. Using the form")
    print("<hostname>.<domainname>")
    print("Example: master.example.com.")
    print("")
    print("")
    if host_default == "":
        host_default = "master.example.com"
    host_name = user_input("Server host name", host_default, allow_empty=False)
    print("")

    return host_name
Пример #20
0
def read_ip_addresses():
    ips = []
    msg_first = "Please provide the IP address to be used for this host name"
    msg_other = "Enter an additional IP address, or press Enter to skip"
    while True:
        msg = msg_other if ips else msg_first
        ip = ipautil.user_input(msg, allow_empty=True)
        if not ip:
            break
        try:
            ip_parsed = ipautil.CheckedIPAddress(ip)
        except Exception as e:
            print("Error: Invalid IP Address %s: %s" % (ip, e))
            continue
        ips.append(ip_parsed)

    return ips
Пример #21
0
def read_ip_addresses():
    ips = []
    msg_first = "Please provide the IP address to be used for this host name"
    msg_other = "Enter an additional IP address, or press Enter to skip"
    while True:
        msg = msg_other if ips else msg_first
        ip = ipautil.user_input(msg, allow_empty=True)
        if not ip:
            break
        try:
            ip_parsed = ipautil.CheckedIPAddress(ip)
        except Exception as e:
            print("Error: Invalid IP Address %s: %s" % (ip, e))
            continue
        ips.append(ip_parsed)

    return ips
Пример #22
0
def add_new_adtrust_agents(api, options):
    """
    Find out IPA masters which are not part of the cn=adtrust agents
    and propose them to be added to the list
    :param api: API instance
    :param options: parsed CLI options
    """
    potential_agents_cns = retrieve_potential_adtrust_agents(api)

    if potential_agents_cns:
        print("")
        print("WARNING: %d IPA masters are not yet able to serve "
              "information about users from trusted forests." %
              len(potential_agents_cns))
        print("Installer can add them to the list of IPA masters "
              "allowed to access information about trusts.")
        print("If you choose to do so, you also need to restart "
              "LDAP service on those masters.")
        print("Refer to ipa-adtrust-install(1) man page for details.")
        print("")
        if options.unattended:
            print("Unattended mode was selected, installer will NOT "
                  "add other IPA masters to the list of allowed to")
            print("access information about trusted forests!")
            return

    new_agents = []

    for name in sorted(potential_agents_cns):
        if ipautil.user_input("IPA master [%s]?" % (name),
                              default=False,
                              allow_empty=False):
            new_agents.append(name)

    if new_agents:
        add_hosts_to_adtrust_agents(api, new_agents)

        print("""
WARNING: you MUST restart (both "ipactl restart" and "systemctl restart sssd")
the following IPA masters in order to activate them to serve information about
users from trusted forests:
""")
        for x in new_agents:
            print(x)
Пример #23
0
def add_new_adtrust_agents(api, options):
    """
    Find out IPA masters which are not part of the cn=adtrust agents
    and propose them to be added to the list
    :param api: API instance
    :param options: parsed CLI options
    """
    potential_agents_cns = retrieve_potential_adtrust_agents(api)

    if potential_agents_cns:
        print("")
        print("WARNING: %d IPA masters are not yet able to serve "
              "information about users from trusted forests."
              % len(potential_agents_cns))
        print("Installer can add them to the list of IPA masters "
              "allowed to access information about trusts.")
        print("If you choose to do so, you also need to restart "
              "LDAP service on those masters.")
        print("Refer to ipa-adtrust-install(1) man page for details.")
        print("")
        if options.unattended:
            print("Unattended mode was selected, installer will NOT "
                  "add other IPA masters to the list of allowed to")
            print("access information about trusted forests!")
            return

    new_agents = []

    for name in sorted(potential_agents_cns):
        if ipautil.user_input(
                "IPA master [%s]?" % (name),
                default=False,
                allow_empty=False):
            new_agents.append(name)

    if new_agents:
        add_hosts_to_adtrust_agents(api, new_agents)

        print("""
WARNING: you MUST restart (e.g. ipactl restart) the following IPA masters in
order to activate them to serve information about users from trusted forests:
""")
        for x in new_agents:
            print(x)
Пример #24
0
def create_replica_config(dirman_password, filename, options):
    top_dir = None
    try:
        top_dir, dir = expand_replica_info(filename, dirman_password)
    except Exception as e:
        logger.error("Failed to decrypt or open the replica file.")
        raise ScriptError(
            "ERROR: Failed to decrypt or open the replica file.\n"
            "Verify you entered the correct Directory Manager password.")
    config = ReplicaConfig(top_dir)
    read_replica_info(dir, config)
    logger.debug(
        'Installing replica file with version %d '
        '(0 means no version in prepared file).',
        config.version)
    if config.version and config.version > version.NUM_VERSION:
        logger.error(
            'A replica file from a newer release (%d) cannot be installed on '
            'an older version (%d)',
            config.version, version.NUM_VERSION)
        raise ScriptError()
    config.dirman_password = dirman_password
    try:
        host = get_host_name(options.no_host_dns)
    except BadHostError as e:
        logger.error("%s", str(e))
        raise ScriptError()
    if config.host_name != host:
        try:
            print("This replica was created for '%s' but this machine is named '%s'" % (config.host_name, host))
            if not ipautil.user_input("This may cause problems. Continue?", False):
                logger.debug(
                    "Replica was created for %s but machine is named %s  "
                    "User chose to exit",
                    config.host_name, host)
                sys.exit(0)
            config.host_name = host
            print("")
        except KeyboardInterrupt:
            logger.debug("Keyboard Interrupt")
            raise ScriptError(rval=0)
    config.dir = dir
    config.ca_ds_port = read_replica_info_dogtag_port(config.dir)
    return config
Пример #25
0
def create_replica_config(dirman_password, filename, options):
    top_dir = None
    try:
        top_dir, dir = expand_replica_info(filename, dirman_password)
    except Exception as e:
        logger.error("Failed to decrypt or open the replica file.")
        raise ScriptError(
            "ERROR: Failed to decrypt or open the replica file.\n"
            "Verify you entered the correct Directory Manager password.")
    config = ReplicaConfig(top_dir)
    read_replica_info(dir, config)
    logger.debug(
        'Installing replica file with version %d '
        '(0 means no version in prepared file).', config.version)
    if config.version and config.version > version.NUM_VERSION:
        logger.error(
            'A replica file from a newer release (%d) cannot be installed on '
            'an older version (%d)', config.version, version.NUM_VERSION)
        raise ScriptError()
    config.dirman_password = dirman_password
    try:
        host = get_host_name(options.no_host_dns)
    except BadHostError as e:
        logger.error("%s", str(e))
        raise ScriptError()
    if config.host_name != host:
        try:
            print(
                "This replica was created for '%s' but this machine is named '%s'"
                % (config.host_name, host))
            if not ipautil.user_input("This may cause problems. Continue?",
                                      False):
                logger.debug(
                    "Replica was created for %s but machine is named %s  "
                    "User chose to exit", config.host_name, host)
                sys.exit(0)
            config.host_name = host
            print("")
        except KeyboardInterrupt:
            logger.debug("Keyboard Interrupt")
            raise ScriptError(rval=0)
    config.dir = dir
    config.ca_ds_port = read_replica_info_dogtag_port(config.dir)
    return config
Пример #26
0
def read_reverse_zone(default, ip_address, allow_zone_overlap=False):
    while True:
        zone = ipautil.user_input("Please specify the reverse zone name", default=default)
        if not zone:
            return None
        if not verify_reverse_zone(zone, ip_address):
            logger.error("Invalid reverse zone %s for IP address %s",
                         zone, ip_address)
            continue
        if not allow_zone_overlap:
            try:
                dnsutil.check_zone_overlap(zone, raise_on_error=False)
            except ValueError as e:
                logger.error("Reverse zone %s will not be used: %s",
                             zone, e)
                continue
        break

    return normalize_zone(zone)
Пример #27
0
def read_reverse_zone(default, ip_address, allow_zone_overlap=False):
    while True:
        zone = ipautil.user_input("Please specify the reverse zone name", default=default)
        if not zone:
            return None
        if not verify_reverse_zone(zone, ip_address):
            logger.error("Invalid reverse zone %s for IP address %s",
                         zone, ip_address)
            continue
        if not allow_zone_overlap:
            try:
                dnsutil.check_zone_overlap(zone, raise_on_error=False)
            except dnsutil.DNSZoneAlreadyExists as e:
                logger.error("Reverse zone %s will not be used: %s",
                             zone, e)
                continue
        break

    return normalize_zone(zone)
Пример #28
0
def read_netbios_name(netbios_default):
    netbios_name = ""

    print("Enter the NetBIOS name for the IPA domain.")
    print("Only up to 15 uppercase ASCII letters, digits "
          "and dashes are allowed.")
    print("Example: EXAMPLE.")
    print("")
    print("")
    if not netbios_default:
        netbios_default = "EXAMPLE"
    while True:
        netbios_name = ipautil.user_input(
            "NetBIOS domain name", netbios_default, allow_empty=False)
        print("")
        if adtrustinstance.check_netbios_name(netbios_name):
            break

        netbios_name_error(netbios_name)

    return netbios_name
Пример #29
0
def read_netbios_name(netbios_default):
    netbios_name = ""

    print("Enter the NetBIOS name for the IPA domain.")
    print("Only up to 15 uppercase ASCII letters, digits "
          "and dashes are allowed.")
    print("Example: EXAMPLE.")
    print("")
    print("")
    if not netbios_default:
        netbios_default = "EXAMPLE"
    while True:
        netbios_name = ipautil.user_input(
            "NetBIOS domain name", netbios_default, allow_empty=False)
        print("")
        if adtrustinstance.check_netbios_name(netbios_name):
            break

        netbios_name_error(netbios_name)

    return netbios_name
def add_ca_schema():
    """Copy IPA schema files into the CA DS instance
    """
    pki_pent = pwd.getpwnam(PKI_USER)
    ds_pent = pwd.getpwnam(DS_USER)
    for schema_fname in SCHEMA_FILENAMES:
        source_fname = os.path.join(ipautil.SHARE_DIR, schema_fname)
        target_fname = os.path.join(schema_dirname(SERVERID), schema_fname)
        if not os.path.exists(source_fname):
            root_logger.debug('File does not exist: %s', source_fname)
            continue
        if os.path.exists(target_fname):
            target_sha1 = _sha1_file(target_fname)
            source_sha1 = _sha1_file(source_fname)
            if target_sha1 != source_sha1:
                target_size = os.stat(target_fname).st_size
                source_size = os.stat(source_fname).st_size
                root_logger.info(
                    'Target file %s exists but the content is '
                    'different', target_fname)
                root_logger.info('\tTarget file: sha1: %s, size: %s B',
                                 target_sha1, target_size)
                root_logger.info('\tSource file: sha1: %s, size: %s B',
                                 source_sha1, source_size)
                if not ipautil.user_input(
                        "Do you want replace %s file?" % target_fname, True):
                    continue

            else:
                root_logger.info('Target exists, not overwriting: %s',
                                 target_fname)
                continue
        try:
            shutil.copyfile(source_fname, target_fname)
        except IOError as e:
            root_logger.warning('Could not install %s: %s', target_fname, e)
        else:
            root_logger.info('Installed %s', target_fname)
        os.chmod(target_fname, 0o440)  # read access for dirsrv user/group
        os.chown(target_fname, pki_pent.pw_uid, ds_pent.pw_gid)
Пример #31
0
def check_inst(unattended):
    has_bind = True
    # So far this file is always present in both RHEL5 and Fedora if all the necessary
    # bind packages are installed (RHEL5 requires also the pkg: caching-nameserver)
    if not os.path.exists('/etc/named.rfc1912.zones'):
        print "BIND was not found on this system"
        print "Please install the 'bind' package and start the installation again"
        has_bind = False

    # Also check for the LDAP BIND plug-in
    if not os.path.exists('/usr/lib/bind/ldap.so') and \
       not os.path.exists('/usr/lib64/bind/ldap.so'):
        print "The BIND LDAP plug-in was not found on this system"
        print "Please install the 'bind-dyndb-ldap' package and start the installation again"
        has_bind = False

    if not has_bind:
        return False

    if not unattended and os.path.exists(NAMED_CONF):
        msg = "Existing BIND configuration detected, overwrite?"
        return ipautil.user_input(msg, False)

    return True
Пример #32
0
def check_inst(unattended):
    has_bind = True
    named = services.knownservices.named
    if not os.path.exists(named.get_binary_path()):
        print "BIND was not found on this system"
        print ("Please install the '%s' package and start the installation again"
              % named.get_package_name())
        has_bind = False

    # Also check for the LDAP BIND plug-in
    if not os.path.exists(paths.BIND_LDAP_SO) and \
       not os.path.exists(paths.BIND_LDAP_SO_64):
        print "The BIND LDAP plug-in was not found on this system"
        print "Please install the 'bind-dyndb-ldap' package and start the installation again"
        has_bind = False

    if not has_bind:
        return False

    if not unattended and os.path.exists(NAMED_CONF):
        msg = "Existing BIND configuration detected, overwrite?"
        return ipautil.user_input(msg, False)

    return True
Пример #33
0
def check_inst(unattended):
    has_bind = True
    named = services.knownservices.named
    if not os.path.exists(named.get_binary_path()):
        print "BIND was not found on this system"
        print ("Please install the '%s' package and start the installation again"
              % named.get_package_name())
        has_bind = False

    # Also check for the LDAP BIND plug-in
    if not os.path.exists(paths.BIND_LDAP_SO) and \
       not os.path.exists(paths.BIND_LDAP_SO_64):
        print "The BIND LDAP plug-in was not found on this system"
        print "Please install the 'bind-dyndb-ldap' package and start the installation again"
        has_bind = False

    if not has_bind:
        return False

    if not unattended and os.path.exists(NAMED_CONF):
        msg = "Existing BIND configuration detected, overwrite?"
        return ipautil.user_input(msg, False)

    return True
Пример #34
0
def set_and_check_netbios_name(netbios_name, unattended, api):
    """
    Depending on whether a trust is already configured or not, the passed
    NetBIOS domain name must be handled differently.

    If trust is not configured, the given NetBIOS is used. The NetBIOS is
    generated if none was given on the command line.

    If trust is already configured, the given NetBIOS name is used to reset
    the stored NetBIOS name in case it differs from the current one.
    """

    cur_netbios_name = None
    gen_netbios_name = None
    reset_netbios_name = False

    if api.Backend.ldap2.isconnected():
        cur_netbios_name = retrieve_netbios_name(api)
    else:
        logger.debug(
            "LDAP is not connected, can not retrieve NetBIOS name")

    if cur_netbios_name and not netbios_name:
        # keep the current NetBIOS name
        netbios_name = cur_netbios_name
        reset_netbios_name = False
    elif cur_netbios_name and cur_netbios_name != netbios_name:
        # change the NetBIOS name
        print("Current NetBIOS domain name is %s, new name is %s.\n"
              % (cur_netbios_name, netbios_name))
        print("Please note that changing the NetBIOS name might "
              "break existing trust relationships.")
        if unattended:
            reset_netbios_name = True
            print("NetBIOS domain name will be changed to %s.\n"
                  % netbios_name)
        else:
            print("Say 'yes' if the NetBIOS shall be changed and "
                  "'no' if the old one shall be kept.")
            reset_netbios_name = ipautil.user_input(
                            'Do you want to reset the NetBIOS domain name?',
                            default=False, allow_empty=False)
        if not reset_netbios_name:
            netbios_name = cur_netbios_name
    elif cur_netbios_name and cur_netbios_name == netbios_name:
        # keep the current NetBIOS name
        reset_netbios_name = False
    elif not cur_netbios_name:
        if not netbios_name:
            gen_netbios_name = adtrustinstance.make_netbios_name(
                api.env.domain)

        if gen_netbios_name is not None:
            # Fix existing trust configuration
            print("Trust is configured but no NetBIOS domain name found, "
                  "setting it now.")
            reset_netbios_name = True
        else:
            # initial trust configuration
            reset_netbios_name = False
    else:
        # all possible cases should be covered above
        raise Exception('Unexpected state while checking NetBIOS domain name')

    if unattended and netbios_name is None and gen_netbios_name:
        netbios_name = gen_netbios_name

    if not adtrustinstance.check_netbios_name(netbios_name):
        if unattended:
            netbios_name_error(netbios_name)
            raise ScriptError("Aborting installation.")
        else:
            if netbios_name:
                netbios_name_error(netbios_name)
                netbios_name = None

    if not unattended and not netbios_name:
        netbios_name = read_netbios_name(gen_netbios_name)

    return (netbios_name, reset_netbios_name)
Пример #35
0
def uninstall_check(installer):
    options = installer

    tasks.check_selinux_status()

    installer._installation_cleanup = False

    if not is_ipa_configured():
        print("WARNING:\nIPA server is not configured on this system. "
              "If you want to install the\nIPA server, please install "
              "it using 'ipa-server-install'.")

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

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

    # We will need at least api.env, finalize api now. This system is
    # already installed, so the configuration file is there.
    api.bootstrap(**cfg)
    api.finalize()

    if installer.interactive:
        print(
            "\nThis is a NON REVERSIBLE operation and will delete all data "
            "and configuration!\nIt is highly recommended to take a backup of "
            "existing data and configuration using ipa-backup utility "
            "before proceeding.\n")
        if not user_input(
                "Are you sure you want to continue with the "
                "uninstall procedure?", False):
            raise ScriptError("Aborting uninstall operation.")

    try:
        api.Backend.ldap2.connect(autobind=True)

        domain_level = dsinstance.get_domain_level(api)
    except Exception:
        msg = ("\nWARNING: Failed to connect to Directory Server to find "
               "information about replication agreements. Uninstallation "
               "will continue despite the possible existing replication "
               "agreements.\n\n"
               "If this server is the last instance of CA, KRA, or DNSSEC "
               "master, uninstallation may result in data loss.\n\n")
        print(textwrap.fill(msg, width=80, replace_whitespace=False))

        if (installer.interactive and not user_input(
                "Are you sure you want to continue with the uninstall "
                "procedure?", False)):
            raise ScriptError("Aborting uninstall operation.")
    else:
        dns.uninstall_check(options)

        if domain_level == DOMAIN_LEVEL_0:
            rm = replication.ReplicationManager(realm=api.env.realm,
                                                hostname=api.env.host,
                                                dirman_passwd=None,
                                                conn=api.Backend.ldap2)
            agreements = rm.find_ipa_replication_agreements()

            if agreements:
                other_masters = [a.get('cn')[0][4:] for a in agreements]
                msg = (
                    "\nReplication agreements with the following IPA masters "
                    "found: %s. Removing any replication agreements before "
                    "uninstalling the server is strongly recommended. You can "
                    "remove replication agreements by running the following "
                    "command on any other IPA master:\n" %
                    ", ".join(other_masters))
                cmd = "$ ipa-replica-manage del %s\n" % api.env.host
                print(textwrap.fill(msg, width=80, replace_whitespace=False))
                print(cmd)
                if (installer.interactive and not user_input(
                        "Are you sure you want to continue with"
                        " the uninstall procedure?", False)):
                    raise ScriptError("Aborting uninstall operation.")
        else:
            remove_master_from_managed_topology(api, options)

        api.Backend.ldap2.disconnect()

    installer._fstore = fstore
    installer._sstore = sstore
Пример #36
0
def install_check(installer):
    options = installer
    dirsrv_pkcs12_file = installer._dirsrv_pkcs12_file
    http_pkcs12_file = installer._http_pkcs12_file
    pkinit_pkcs12_file = installer._pkinit_pkcs12_file
    dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
    http_pkcs12_info = installer._http_pkcs12_info
    pkinit_pkcs12_info = installer._pkinit_pkcs12_info
    external_cert_file = installer._external_cert_file
    external_ca_file = installer._external_ca_file
    http_ca_cert = installer._ca_cert

    tasks.check_ipv6_stack_enabled()
    tasks.check_selinux_status()

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

    installer._installation_cleanup = True

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    domain_name = domain_name.lower()

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

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

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

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

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

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

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

    if not options.dm_password:
        dm_password = read_dm_password()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    installer._fstore = fstore
    installer._sstore = sstore
    installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file
    installer._http_pkcs12_file = http_pkcs12_file
    installer._pkinit_pkcs12_file = pkinit_pkcs12_file
    installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info
    installer._http_pkcs12_info = http_pkcs12_info
    installer._pkinit_pkcs12_info = pkinit_pkcs12_info
    installer._external_cert_file = external_cert_file
    installer._external_ca_file = external_ca_file
    installer._ca_cert = http_ca_cert
Пример #37
0
def configure_automount():
    try:
        check_client_configuration()
    except ScriptError as e:
        print(e.msg)
        sys.exit(e.rval)

    fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
    statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE)

    options, _args = parse_options()

    standard_logging_setup(
        paths.IPACLIENT_INSTALL_LOG,
        verbose=False,
        debug=options.debug,
        filemode='a',
        console_format='%(message)s',
    )

    cfg = dict(
        context='cli_installer',
        confdir=paths.ETC_IPA,
        in_server=False,
        debug=options.debug,
        verbose=0,
    )

    # Bootstrap API early so that env object is available
    api.bootstrap(**cfg)

    if options.uninstall:
        return uninstall(fstore, statestore)

    ca_cert_path = None
    if os.path.exists(paths.IPA_CA_CRT):
        ca_cert_path = paths.IPA_CA_CRT

    if statestore.has_state('autofs'):
        print('An automount location is already configured')
        sys.exit(CLIENT_ALREADY_CONFIGURED)

    autodiscover = False
    ds = ipadiscovery.IPADiscovery()
    if not options.server:
        print("Searching for IPA server...")
        ret = ds.search(ca_cert_path=ca_cert_path)
        logger.debug('Executing DNS discovery')
        if ret == ipadiscovery.NO_LDAP_SERVER:
            logger.debug('Autodiscovery did not find LDAP server')
            s = urlsplit(api.env.xmlrpc_uri)
            server = [s.netloc]
            logger.debug('Setting server to %s', s.netloc)
        else:
            autodiscover = True
            if not ds.servers:
                sys.exit(
                    'Autodiscovery was successful but didn\'t return a server'
                )
            logger.debug(
                'Autodiscovery success, possible servers %s',
                ','.join(ds.servers),
            )
            server = ds.servers[0]
    else:
        server = options.server
        logger.debug("Verifying that %s is an IPA server", server)
        ldapret = ds.ipacheckldap(server, api.env.realm, ca_cert_path)
        if ldapret[0] == ipadiscovery.NO_ACCESS_TO_LDAP:
            print("Anonymous access to the LDAP server is disabled.")
            print("Proceeding without strict verification.")
            print(
                "Note: This is not an error if anonymous access has been "
                "explicitly restricted."
            )
        elif ldapret[0] == ipadiscovery.NO_TLS_LDAP:
            logger.warning("Unencrypted access to LDAP is not supported.")
        elif ldapret[0] != 0:
            sys.exit('Unable to confirm that %s is an IPA server' % server)

    if not autodiscover:
        print("IPA server: %s" % server)
        logger.debug('Using fixed server %s', server)
    else:
        print("IPA server: DNS discovery")
        logger.debug('Configuring to use DNS discovery')

    print("Location: %s" % options.location)
    logger.debug('Using automount location %s', options.location)

    ccache_dir = tempfile.mkdtemp()
    ccache_name = os.path.join(ccache_dir, 'ccache')
    try:
        try:
            host_princ = str('host/%s@%s' % (api.env.host, api.env.realm))
            kinit_keytab(host_princ, paths.KRB5_KEYTAB, ccache_name)
            os.environ['KRB5CCNAME'] = ccache_name
        except gssapi.exceptions.GSSError as e:
            sys.exit("Failed to obtain host TGT: %s" % e)

        # Finalize API when TGT obtained using host keytab exists
        api.finalize()

        # Now we have a TGT, connect to IPA
        try:
            api.Backend.rpcclient.connect()
        except errors.KerberosError as e:
            sys.exit('Cannot connect to the server due to ' + str(e))
        try:
            # Use the RPC directly so older servers are supported
            api.Backend.rpcclient.forward(
                'automountlocation_show',
                ipautil.fsdecode(options.location),
                version=u'2.0',
            )
        except errors.VersionError as e:
            sys.exit('This client is incompatible: ' + str(e))
        except errors.NotFound:
            sys.exit(
                "Automount location '%s' does not exist" % options.location
            )
        except errors.PublicError as e:
            sys.exit(
                "Cannot connect to the server due to generic error: %s"
                % str(e)
            )
    finally:
        shutil.rmtree(ccache_dir)

    if not options.unattended and not ipautil.user_input(
        "Continue to configure the system with these values?", False
    ):
        sys.exit("Installation aborted")

    try:
        if not options.sssd:
            tasks.enable_ldap_automount(statestore)
        configure_nfs(fstore, statestore, options)
        if options.sssd:
            configure_autofs_sssd(fstore, statestore, autodiscover, options)
        else:
            configure_xml(fstore)
            configure_autofs(
                fstore, statestore, autodiscover, server, options
            )
        configure_autofs_common(fstore, statestore, options)
    except Exception as e:
        logger.debug('Raised exception %s', e)
        print("Installation failed. Rolling back changes.")
        uninstall(fstore, statestore)
        return 1

    return 0
Пример #38
0
def install_check(standalone, api, replica, options, hostname):
    global ip_addresses
    global reverse_zones
    fstore = sysrestore.FileStore(paths.SYSRESTORE)

    if not ipautil.file_exists(paths.IPA_DNS_INSTALL):
        raise RuntimeError("Integrated DNS requires '%s' package" %
                           constants.IPA_DNS_PACKAGE_NAME)

    # when installing first DNS instance we need to check zone overlap
    if replica or standalone:
        already_enabled = api.Command.dns_is_enabled()['result']
    else:
        already_enabled = False

    if not already_enabled:
        domain = dnsutil.DNSName(util.normalize_zone(api.env.domain))
        print("Checking DNS domain %s, please wait ..." % domain)
        try:
            dnsutil.check_zone_overlap(domain, raise_on_error=False)
        except ValueError as e:
            if options.force or options.allow_zone_overlap:
                root_logger.warning("%s Please make sure that the domain is "
                                    "properly delegated to this IPA server.",
                                    e.message)
            else:
                raise e

    for reverse_zone in options.reverse_zones:
        try:
            dnsutil.check_zone_overlap(reverse_zone)
        except ValueError as e:
            if options.force or options.allow_zone_overlap:
                root_logger.warning(e.message)
            else:
                raise e

    if standalone:
        print("==============================================================================")
        print("This program will setup DNS for the FreeIPA Server.")
        print("")
        print("This includes:")
        print("  * Configure DNS (bind)")
        print("  * Configure SoftHSM (required by DNSSEC)")
        print("  * Configure ipa-dnskeysyncd (required by DNSSEC)")
        if options.dnssec_master:
            print("  * Configure ipa-ods-exporter (required by DNSSEC key master)")
            print("  * Configure OpenDNSSEC (required by DNSSEC key master)")
            print("  * Generate DNSSEC master key (required by DNSSEC key master)")
        elif options.disable_dnssec_master:
            print("  * Unconfigure ipa-ods-exporter")
            print("  * Unconfigure OpenDNSSEC")
            print("")
            print("No new zones will be signed without DNSSEC key master IPA server.")
            print("")
            print(("Please copy file from %s after uninstallation. This file is needed "
                   "on new DNSSEC key " % paths.IPA_KASP_DB_BACKUP))
            print("master server")
        print("")
        print("NOTE: DNSSEC zone signing is not enabled by default")
        print("")
        if options.dnssec_master:
            print("Plan carefully, replacing DNSSEC key master is not recommended")
            print("")
        print("")
        print("To accept the default shown in brackets, press the Enter key.")
        print("")

    if (options.dnssec_master and not options.unattended and not
        ipautil.user_input(
            "Do you want to setup this IPA server as DNSSEC key master?",
            False)):
        sys.exit("Aborted")
    elif (options.disable_dnssec_master and not options.unattended and not
          ipautil.user_input(
            "Do you want to disable current DNSSEC key master?",
            False)):
        sys.exit("Aborted")

    if options.disable_dnssec_master:
        _is_master()

    if options.disable_dnssec_master or options.dnssec_master:
        dnssec_zones = _find_dnssec_enabled_zones(api.Backend.ldap2)

    if options.disable_dnssec_master:
        if dnssec_zones and not options.force:
            raise RuntimeError(
                "Cannot disable DNSSEC key master, DNSSEC signing is still "
                "enabled for following zone(s):\n"
                "%s\n"
                "It is possible to move DNSSEC key master role to a different "
                "server by using --force option to skip this check.\n\n"
                "WARNING: You have to immediatelly copy kasp.db file to a new "
                "server and run command 'ipa-dns-install --dnssec-master "
                "--kasp-db'.\n"
                "Your DNS zones will become unavailable if you "
                "do not reinstall the DNSSEC key master role immediatelly." %
                ", ".join([str(zone) for zone in dnssec_zones]))

    elif options.dnssec_master:
        ods = opendnssecinstance.OpenDNSSECInstance(fstore)
        ods.realm = api.env.realm
        dnssec_masters = ods.get_masters()
        # we can reinstall current server if it is dnssec master
        if dnssec_masters and api.env.host not in dnssec_masters:
            print("DNSSEC key master(s):", u','.join(dnssec_masters))
            raise ScriptError(
                "Only one DNSSEC key master is supported in current version.")

        if options.kasp_db_file:
            dnskeysyncd = services.service('ipa-dnskeysyncd')

            if not dnskeysyncd.is_installed():
                raise RuntimeError("ipa-dnskeysyncd is not configured on this "
                                   "server, you cannot reuse OpenDNSSEC "
                                   "database (kasp.db file)")

            # check if replica can be the DNSSEC master
            cmd = [paths.IPA_DNSKEYSYNCD_REPLICA]
            environment = {
                "SOFTHSM2_CONF": paths.DNSSEC_SOFTHSM2_CONF,
            }

            # stop dnskeysyncd before test
            dnskeysyncd_running = dnskeysyncd.is_running()
            dnskeysyncd.stop()
            try:
                ipautil.run(cmd, env=environment,
                            runas=constants.ODS_USER,
                            suplementary_groups=[constants.NAMED_GROUP])
            except CalledProcessError as e:
                root_logger.debug("%s", e)
                raise RuntimeError("This IPA server cannot be promoted to "
                                   "DNSSEC master role because some keys were "
                                   "not replicated from the original "
                                   "DNSSEC master server")
            finally:
                if dnskeysyncd_running:
                    dnskeysyncd.start()
        elif dnssec_zones and not options.force:
            # some zones have --dnssec=true, make sure a user really want to
            # install new database
            raise RuntimeError(
                "DNSSEC signing is already enabled for following zone(s): %s\n"
                "Installation cannot continue without the OpenDNSSEC database "
                "file from the original DNSSEC master server.\n"
                "Please use option --kasp-db to specify location "
                "of the kasp.db file copied from the original "
                "DNSSEC master server.\n"
                "WARNING: Zones will become unavailable if you do not provide "
                "the original kasp.db file." %
                ", ".join([str(zone) for zone in dnssec_zones]))

    ip_addresses = get_server_ip_address(hostname, options.unattended,
                                         True, options.ip_addresses)

    util.network_ip_address_warning(ip_addresses)
    util.broadcast_ip_address_warning(ip_addresses)

    if not options.forward_policy:
        # user did not specify policy, derive it: default is 'first' but
        # if any of local IP addresses belongs to private ranges use 'only'
        options.forward_policy = 'first'
        for ip in ip_addresses:
            if dnsutil.inside_auto_empty_zone(dnsutil.DNSName(ip.reverse_dns)):
                options.forward_policy = 'only'
                root_logger.debug('IP address %s belongs to a private range, '
                                  'using forward policy only', ip)
                break

    if options.no_forwarders:
        options.forwarders = []
    elif options.forwarders or options.auto_forwarders:
        if not options.forwarders:
            options.forwarders = []
        if options.auto_forwarders:
            options.forwarders += resolver.get_default_resolver().nameservers
    elif standalone or not replica:
        options.forwarders = read_dns_forwarders()

    # test DNSSEC forwarders
    if options.forwarders:
        if (not bindinstance.check_forwarders(options.forwarders,
                                              root_logger)
                and not options.no_dnssec_validation):
            options.no_dnssec_validation = True
            print("WARNING: DNSSEC validation will be disabled")

    root_logger.debug("will use DNS forwarders: %s\n", options.forwarders)

    if not standalone:
        search_reverse_zones = False
    else:
        search_reverse_zones = True

    if not standalone and replica:
        reverse_zones_unattended_check = True
    else:
        reverse_zones_unattended_check = options.unattended

    reverse_zones = bindinstance.check_reverse_zones(
        ip_addresses, options.reverse_zones, options,
        reverse_zones_unattended_check, search_reverse_zones
    )

    if reverse_zones:
        print("Using reverse zone(s) %s" % ', '.join(reverse_zones))
Пример #39
0
def install(options, fstore, api):
    if not options.unattended:
        print("")
        print("The following operations may take some minutes to complete.")
        print("Please wait until the prompt is returned.")
        print("")

    smb = adtrustinstance.ADTRUSTInstance(fstore)
    smb.realm = api.env.realm
    smb.autobind = ipaldap.AUTOBIND_ENABLED
    smb.setup(api.env.host,
              api.env.realm,
              netbios_name,
              reset_netbios_name,
              options.rid_base,
              options.secondary_rid_base,
              options.add_sids,
              enable_compat=options.enable_compat)
    smb.find_local_id_range()
    smb.create_instance()

    if options.add_agents:
        # Find out IPA masters which are not part of the cn=adtrust agents
        # and propose them to be added to the list
        base_dn = api.env.basedn
        masters_dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'),
                        base_dn)
        agents_dn = DN(('cn', 'adtrust agents'), ('cn', 'sysaccounts'),
                       ('cn', 'etc'), base_dn)
        new_agents = []
        entries_m = []
        entries_a = []
        try:
            # Search only masters which have support for domain levels
            # because only these masters will have SSSD recent enough
            # to support AD trust agents
            entries_m, _truncated = api.Backend.ldap2.find_entries(
                filter=("(&(objectclass=ipaSupportedDomainLevelConfig)"
                        "(ipaMaxDomainLevel=*)(ipaMinDomainLevel=*))"),
                base_dn=masters_dn,
                attrs_list=['cn'],
                scope=ldap.SCOPE_ONELEVEL)
        except errors.NotFound:
            pass
        except (errors.DatabaseError, errors.NetworkError) as e:
            print("Could not retrieve a list of existing IPA masters:")
            print(unicode(e))

        try:
            entries_a, _truncated = api.Backend.ldap2.find_entries(
                filter="",
                base_dn=agents_dn,
                attrs_list=['member'],
                scope=ldap.SCOPE_BASE)
        except errors.NotFound:
            pass
        except (errors.DatabaseError, errors.NetworkError) as e:
            print("Could not retrieve a list of adtrust agents:")
            print(unicode(e))

        if len(entries_m) > 0:
            existing_masters = [x['cn'][0] for x in entries_m]
            adtrust_agents = entries_a[0]['member']
            potential_agents = []
            for m in existing_masters:
                mdn = DN(('fqdn', m), api.env.container_host, api.env.basedn)
                found = False
                for a in adtrust_agents:
                    if mdn == a:
                        found = True
                        break
                if not found:
                    potential_agents += [[m, mdn]]

            object_count = len(potential_agents)
            if object_count > 0:
                print("")
                print("WARNING: %d IPA masters are not yet able to serve "
                      "information about users from trusted forests." %
                      (object_count))
                print("Installer can add them to the list of IPA masters "
                      "allowed to access information about trusts.")
                print("If you choose to do so, you also need to restart "
                      "LDAP service on those masters.")
                print("Refer to ipa-adtrust-install(1) man page for details.")
                print("")
                if options.unattended:
                    print("Unattended mode was selected, installer will NOT "
                          "add other IPA masters to the list of allowed to")
                    print("access information about trusted forests!")
                else:
                    print(
                        "Do you want to allow following IPA masters to "
                        "serve information about users from trusted forests?")
                    for (name, dn) in potential_agents:
                        if name == api.env.host:
                            # Don't add this host here
                            # it shouldn't be here as it was added by the
                            # adtrustinstance setup code
                            continue
                        if ipautil.user_input("IPA master [%s]?" % (name),
                                              default=False,
                                              allow_empty=False):
                            new_agents += [[name, dn]]

            if len(new_agents) > 0:
                # Add the CIFS and host principals to the 'adtrust agents'
                # group as 389-ds only operates with GroupOfNames, we have to
                # use the principal's proper dn as defined in self.cifs_agent
                service.add_principals_to_group(api.Backend.ldap2, agents_dn,
                                                "member",
                                                [x[1] for x in new_agents])
Пример #40
0
    if config.version and config.version > version.NUM_VERSION:
        root_logger.error(
            'A replica file from a newer release (%d) cannot be installed on an older version (%d)',
            config.version, version.NUM_VERSION)
        sys.exit(1)
    config.dirman_password = dirman_password
    try:
        host = get_host_name(options.no_host_dns)
    except BadHostError, e:
        root_logger.error(str(e))
        sys.exit(1)
    if config.host_name != host:
        try:
            print "This replica was created for '%s' but this machine is named '%s'" % (
                config.host_name, host)
            if not ipautil.user_input("This may cause problems. Continue?",
                                      False):
                root_logger.debug(
                    "Replica was created for %s but machine is named %s  "
                    "User chose to exit", config.host_name, host)
                sys.exit(0)
            config.host_name = host
            print ""
        except KeyboardInterrupt:
            root_logger.debug("Keyboard Interrupt")
            sys.exit(0)
    config.dir = dir
    config.ca_ds_port = read_replica_info_dogtag_port(config.dir)
    return config


def check_server_configuration():
Пример #41
0
def install_check(installer):
    options = installer
    dirsrv_pkcs12_file = installer._dirsrv_pkcs12_file
    http_pkcs12_file = installer._http_pkcs12_file
    pkinit_pkcs12_file = installer._pkinit_pkcs12_file
    dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
    http_pkcs12_info = installer._http_pkcs12_info
    pkinit_pkcs12_info = installer._pkinit_pkcs12_info
    external_cert_file = installer._external_cert_file
    external_ca_file = installer._external_ca_file
    http_ca_cert = installer._ca_cert
    dirsrv_ca_cert = None
    pkinit_ca_cert = None

    tasks.check_ipv6_stack_enabled()
    tasks.check_selinux_status()
    check_ldap_conf()

    mask_str = validate_mask()
    if mask_str:
        print("Unexpected system mask: %s, expected 0022" % mask_str)
        if installer.interactive:
            if not user_input("Do you want to continue anyway?", True):
                raise ScriptError(
                    "Unexpected system mask: %s" % mask_str)
        else:
            raise ScriptError("Unexpected system mask: %s" % mask_str)

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

    installer._installation_cleanup = True

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

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

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

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

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

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

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

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

    if not options.no_ntp:
        try:
            ipaclient.install.timeconf.check_timedate_services()
        except ipaclient.install.timeconf.NTPConflictingService as e:
            print("WARNING: conflicting time&date synchronization service '{}'"
                  " will be disabled".format(e.conflicting_service))
            print("in favor of chronyd")
            print("")
        except ipaclient.install.timeconf.NTPConfigurationError:
            pass

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

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

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

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

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

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

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

    domain_name = domain_name.lower()

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

        try:
            validate_domain_name(realm_name, entity="realm")
        except ValueError as e:
            raise ScriptError("Invalid realm name: {}".format(unicode(e)))
    else:
        realm_name = options.realm_name.upper()

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

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

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

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

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

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

    if (options.http_cert_files and
            options.pkinit_cert_files and
            http_ca_cert != pkinit_ca_cert):
        raise ScriptError(
            "Apache Server SSL certificate and PKINIT KDC "
            "certificate are not signed by the same CA certificate")

    if not options.dm_password:
        dm_password = read_dm_password()

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

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

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

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

    # Create the management framework config file and finalize api
    target_fname = paths.IPA_DEFAULT_CONF
    ipaconf = IPAChangeConf("IPA Server Install")
    ipaconf.setOptionAssignment(" = ")
    ipaconf.setSectionNameDelimiters(("[", "]"))

    xmlrpc_uri = 'https://{0}/ipa/xml'.format(
                    ipautil.format_netloc(host_name))
    ldapi_uri = ipaldap.realm_to_ldapi_uri(realm_name)

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

    if setup_ca:
        gopts.extend([
            ipaconf.setOption('enable_ra', 'True'),
            ipaconf.setOption('ra_plugin', 'dogtag'),
            ipaconf.setOption('dogtag_version', '10')
        ])
    else:
        gopts.extend([
            ipaconf.setOption('enable_ra', 'False'),
            ipaconf.setOption('ra_plugin', 'None')
        ])

    opts = [
        ipaconf.setSection('global', gopts),
        {'name': 'empty', 'type': 'empty'}
    ]

    ipaconf.newConf(target_fname, opts)

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

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

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

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

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

    instance_name = "-".join(realm_name.split("."))
    dirsrv = services.knownservices.dirsrv
    if (options.external_cert_files
           and dirsrv.is_installed(instance_name)
           and not dirsrv.is_running(instance_name)):
        logger.debug('Starting Directory Server')
        services.knownservices.dirsrv.start(instance_name)

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

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

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

    if setup_ca:
        ca.print_ca_configuration(options)
        print()

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

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

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

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

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

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

    installer._fstore = fstore
    installer._sstore = sstore
    installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file
    installer._http_pkcs12_file = http_pkcs12_file
    installer._pkinit_pkcs12_file = pkinit_pkcs12_file
    installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info
    installer._http_pkcs12_info = http_pkcs12_info
    installer._pkinit_pkcs12_info = pkinit_pkcs12_info
    installer._external_cert_file = external_cert_file
    installer._external_ca_file = external_ca_file
    installer._ca_cert = http_ca_cert
Пример #42
0
def install_check(standalone, api, replica, options, hostname):
    global ip_addresses
    global reverse_zones
    fstore = sysrestore.FileStore(paths.SYSRESTORE)

    if not os.path.isfile(paths.IPA_DNS_INSTALL):
        raise RuntimeError("Integrated DNS requires '%s' package" %
                           constants.IPA_DNS_PACKAGE_NAME)

    # when installing first DNS instance we need to check zone overlap
    if replica or standalone:
        already_enabled = api.Command.dns_is_enabled()['result']
    else:
        already_enabled = False

    if not already_enabled:
        domain = dnsutil.DNSName(util.normalize_zone(api.env.domain))
        print("Checking DNS domain %s, please wait ..." % domain)
        try:
            dnsutil.check_zone_overlap(domain, raise_on_error=False)
        except ValueError as e:
            if options.force or options.allow_zone_overlap:
                logger.warning("%s Please make sure that the domain is "
                               "properly delegated to this IPA server.",
                               e)
            else:
                raise e

    for reverse_zone in options.reverse_zones:
        try:
            dnsutil.check_zone_overlap(reverse_zone)
        except ValueError as e:
            if options.force or options.allow_zone_overlap:
                logger.warning('%s', six.text_type(e))
            else:
                raise e

    if standalone:
        print("==============================================================================")
        print("This program will setup DNS for the FreeIPA Server.")
        print("")
        print("This includes:")
        print("  * Configure DNS (bind)")
        print("  * Configure SoftHSM (required by DNSSEC)")
        print("  * Configure ipa-dnskeysyncd (required by DNSSEC)")
        if options.dnssec_master:
            print("  * Configure ipa-ods-exporter (required by DNSSEC key master)")
            print("  * Configure OpenDNSSEC (required by DNSSEC key master)")
            print("  * Generate DNSSEC master key (required by DNSSEC key master)")
        elif options.disable_dnssec_master:
            print("  * Unconfigure ipa-ods-exporter")
            print("  * Unconfigure OpenDNSSEC")
            print("")
            print("No new zones will be signed without DNSSEC key master IPA server.")
            print("")
            print(("Please copy file from %s after uninstallation. This file is needed "
                   "on new DNSSEC key " % paths.IPA_KASP_DB_BACKUP))
            print("master server")
        print("")
        print("NOTE: DNSSEC zone signing is not enabled by default")
        print("")
        if options.dnssec_master:
            print("Plan carefully, replacing DNSSEC key master is not recommended")
            print("")
        print("")
        print("To accept the default shown in brackets, press the Enter key.")
        print("")

    if (options.dnssec_master and not options.unattended and not
        ipautil.user_input(
            "Do you want to setup this IPA server as DNSSEC key master?",
            False)):
        sys.exit("Aborted")
    elif (options.disable_dnssec_master and not options.unattended and not
          ipautil.user_input(
            "Do you want to disable current DNSSEC key master?",
            False)):
        sys.exit("Aborted")

    if options.disable_dnssec_master:
        _is_master()

    if options.disable_dnssec_master or options.dnssec_master:
        dnssec_zones = _find_dnssec_enabled_zones(api.Backend.ldap2)

    if options.disable_dnssec_master:
        if dnssec_zones and not options.force:
            raise RuntimeError(
                "Cannot disable DNSSEC key master, DNSSEC signing is still "
                "enabled for following zone(s):\n"
                "%s\n"
                "It is possible to move DNSSEC key master role to a different "
                "server by using --force option to skip this check.\n\n"
                "WARNING: You have to immediately copy kasp.db file to a new "
                "server and run command 'ipa-dns-install --dnssec-master "
                "--kasp-db'.\n"
                "Your DNS zones will become unavailable if you "
                "do not reinstall the DNSSEC key master role immediately." %
                ", ".join([str(zone) for zone in dnssec_zones]))

    elif options.dnssec_master:
        ods = opendnssecinstance.OpenDNSSECInstance(fstore)
        ods.realm = api.env.realm
        dnssec_masters = ods.get_masters()
        # we can reinstall current server if it is dnssec master
        if dnssec_masters and api.env.host not in dnssec_masters:
            print("DNSSEC key master(s):", u','.join(dnssec_masters))
            raise ScriptError(
                "Only one DNSSEC key master is supported in current version.")

        if options.kasp_db_file:
            dnskeysyncd = services.service('ipa-dnskeysyncd', api)

            if not dnskeysyncd.is_installed():
                raise RuntimeError("ipa-dnskeysyncd is not configured on this "
                                   "server, you cannot reuse OpenDNSSEC "
                                   "database (kasp.db file)")

            # check if replica can be the DNSSEC master
            cmd = [paths.IPA_DNSKEYSYNCD_REPLICA]
            environment = {
                "SOFTHSM2_CONF": paths.DNSSEC_SOFTHSM2_CONF,
            }

            # stop dnskeysyncd before test
            dnskeysyncd_running = dnskeysyncd.is_running()
            dnskeysyncd.stop()
            try:
                ipautil.run(cmd, env=environment,
                            runas=constants.ODS_USER,
                            suplementary_groups=[constants.NAMED_GROUP])
            except CalledProcessError as e:
                logger.debug("%s", e)
                raise RuntimeError("This IPA server cannot be promoted to "
                                   "DNSSEC master role because some keys were "
                                   "not replicated from the original "
                                   "DNSSEC master server")
            finally:
                if dnskeysyncd_running:
                    dnskeysyncd.start()
        elif dnssec_zones and not options.force:
            # some zones have --dnssec=true, make sure a user really want to
            # install new database
            raise RuntimeError(
                "DNSSEC signing is already enabled for following zone(s): %s\n"
                "Installation cannot continue without the OpenDNSSEC database "
                "file from the original DNSSEC master server.\n"
                "Please use option --kasp-db to specify location "
                "of the kasp.db file copied from the original "
                "DNSSEC master server.\n"
                "WARNING: Zones will become unavailable if you do not provide "
                "the original kasp.db file." %
                ", ".join([str(zone) for zone in dnssec_zones]))

    ip_addresses = get_server_ip_address(hostname, options.unattended,
                                         True, options.ip_addresses)

    util.no_matching_interface_for_ip_address_warning(ip_addresses)

    if not options.forward_policy:
        # user did not specify policy, derive it: default is 'first' but
        # if any of local IP addresses belongs to private ranges use 'only'
        options.forward_policy = 'first'
        for ip in ip_addresses:
            if dnsutil.inside_auto_empty_zone(dnsutil.DNSName(ip.reverse_dns)):
                options.forward_policy = 'only'
                logger.debug('IP address %s belongs to a private range, '
                             'using forward policy only', ip)
                break

    if options.no_forwarders:
        options.forwarders = []
    elif options.forwarders or options.auto_forwarders:
        if not options.forwarders:
            options.forwarders = []
        if options.auto_forwarders:
            options.forwarders += resolver.get_default_resolver().nameservers
    elif standalone or not replica:
        options.forwarders = read_dns_forwarders()

    # test DNSSEC forwarders
    if options.forwarders:
        if (not bindinstance.check_forwarders(options.forwarders)
                and not options.no_dnssec_validation):
            options.no_dnssec_validation = True
            print("WARNING: DNSSEC validation will be disabled")

    logger.debug("will use DNS forwarders: %s\n", options.forwarders)

    if not standalone:
        search_reverse_zones = False
    else:
        search_reverse_zones = True

    if not standalone and replica:
        reverse_zones_unattended_check = True
    else:
        reverse_zones_unattended_check = options.unattended

    reverse_zones = bindinstance.check_reverse_zones(
        ip_addresses, options.reverse_zones, options,
        reverse_zones_unattended_check, search_reverse_zones
    )

    if reverse_zones:
        print("Using reverse zone(s) %s" % ', '.join(reverse_zones))
Пример #43
0
def create_reverse():
    return ipautil.user_input(
        "Do you want to search for missing reverse zones?", True)
Пример #44
0
def check_reverse_zones(ip_addresses,
                        reverse_zones,
                        options,
                        unattended,
                        search_reverse_zones=False):
    checked_reverse_zones = []

    if (not options.no_reverse and not reverse_zones
            and not options.auto_reverse):
        if unattended:
            options.no_reverse = True
        else:
            options.no_reverse = not create_reverse()

    # shortcut
    if options.no_reverse:
        return []

    # verify zones passed in options
    for rz in reverse_zones:
        # isn't the zone managed by someone else
        if not options.allow_zone_overlap:
            try:
                dnsutil.check_zone_overlap(rz)
            except ValueError as e:
                msg = "Reverse zone %s will not be used: %s" % (rz, e)
                if unattended:
                    raise ScriptError(msg)
                else:
                    root_logger.warning(msg)
                continue
        checked_reverse_zones.append(normalize_zone(rz))

    # check that there is reverse zone for every IP
    ips_missing_reverse = []
    for ip in ip_addresses:
        if search_reverse_zones and find_reverse_zone(str(ip)):
            # reverse zone is already in LDAP
            continue
        for rz in checked_reverse_zones:
            if verify_reverse_zone(rz, ip):
                # reverse zone was entered by user
                break
        else:
            ips_missing_reverse.append(ip)

    # create reverse zone for IP addresses that does not have one
    for (ip, rz) in get_auto_reverse_zones(ips_missing_reverse):
        if options.auto_reverse:
            root_logger.info("Reverse zone %s will be created" % rz)
            checked_reverse_zones.append(rz)
        elif unattended:
            root_logger.warning("Missing reverse record for IP address %s" %
                                ip)
        else:
            if ipautil.user_input(
                    "Do you want to create reverse zone for IP "
                    "%s" % ip, True):
                rz = read_reverse_zone(rz, str(ip), options.allow_zone_overlap)
                checked_reverse_zones.append(rz)

    return checked_reverse_zones
Пример #45
0
def promote_check(installer):
    options = installer
    installer._enrollment_performed = False
    installer._top_dir = tempfile.mkdtemp("ipa")

    # check selinux status, http and DS ports, NTP conflicting services
    common_check(options.no_ntp)

    client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
    if not client_fstore.has_files():
        ensure_enrolled(installer)
    else:
        if (options.domain_name or options.server or options.realm_name
                or options.host_name or options.password or options.keytab):
            print("IPA client is already configured on this system, ignoring "
                  "the --domain, --server, --realm, --hostname, --password "
                  "and --keytab options.")

        # The NTP configuration can not be touched on pre-installed client:
        if options.no_ntp or options.ntp_servers or options.ntp_pool:
            raise ScriptError(
                "NTP configuration cannot be updated during promotion")

    sstore = sysrestore.StateFile(paths.SYSRESTORE)

    fstore = sysrestore.FileStore(paths.SYSRESTORE)

    env = Env()
    env._bootstrap(context='installer', confdir=paths.ETC_IPA, log=None)
    env._finalize_core(**dict(constants.DEFAULT_CONFIG))

    # pylint: disable=no-member
    xmlrpc_uri = 'https://{}/ipa/xml'.format(ipautil.format_netloc(env.host))
    api.bootstrap(in_server=True,
                  context='installer',
                  confdir=paths.ETC_IPA,
                  ldap_uri=installutils.realm_to_ldapi_uri(env.realm),
                  xmlrpc_uri=xmlrpc_uri)
    # pylint: enable=no-member
    api.finalize()

    config = ReplicaConfig()
    config.realm_name = api.env.realm
    config.host_name = api.env.host
    config.domain_name = api.env.domain
    config.master_host_name = api.env.server
    config.ca_host_name = api.env.ca_host
    config.kra_host_name = config.ca_host_name
    config.ca_ds_port = 389
    config.setup_ca = options.setup_ca
    config.setup_kra = options.setup_kra
    config.dir = installer._top_dir
    config.basedn = api.env.basedn

    http_pkcs12_file = None
    http_pkcs12_info = None
    http_ca_cert = None
    dirsrv_pkcs12_file = None
    dirsrv_pkcs12_info = None
    dirsrv_ca_cert = None
    pkinit_pkcs12_file = None
    pkinit_pkcs12_info = None
    pkinit_ca_cert = None

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

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

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

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

    if (options.http_cert_files and options.pkinit_cert_files
            and http_ca_cert != pkinit_ca_cert):
        raise RuntimeError("Apache Server SSL certificate and PKINIT KDC "
                           "certificate are not signed by the same CA "
                           "certificate")

    installutils.verify_fqdn(config.host_name, options.no_host_dns)
    installutils.verify_fqdn(config.master_host_name, options.no_host_dns)

    ccache = os.environ['KRB5CCNAME']
    kinit_keytab('host/{env.host}@{env.realm}'.format(env=api.env),
                 paths.KRB5_KEYTAB, ccache)

    cafile = paths.IPA_CA_CRT
    if not os.path.isfile(cafile):
        raise RuntimeError("CA cert file is not available! Please reinstall"
                           "the client and try again.")

    ldapuri = 'ldaps://%s' % ipautil.format_netloc(config.master_host_name)
    xmlrpc_uri = 'https://{}/ipa/xml'.format(
        ipautil.format_netloc(config.master_host_name))
    remote_api = create_api(mode=None)
    remote_api.bootstrap(in_server=True,
                         context='installer',
                         confdir=paths.ETC_IPA,
                         ldap_uri=ldapuri,
                         xmlrpc_uri=xmlrpc_uri)
    remote_api.finalize()
    installer._remote_api = remote_api

    with rpc_client(remote_api) as client:
        check_remote_version(client, parse_version(api.env.version))
        check_remote_fips_mode(client, api.env.fips_mode)

    conn = remote_api.Backend.ldap2
    replman = None
    try:
        # Try out authentication
        conn.connect(ccache=ccache)
        replman = ReplicationManager(config.realm_name,
                                     config.master_host_name, None)

        promotion_check_ipa_domain(conn, remote_api.env.basedn)

        # Make sure that domain fulfills minimal domain level
        # requirement
        domain_level = current_domain_level(remote_api)
        check_domain_level_is_supported(domain_level)
        if domain_level < constants.MIN_DOMAIN_LEVEL:
            raise RuntimeError(
                "Cannot promote this client to a replica. The domain level "
                "must be raised to {mindomainlevel} before the replica can be "
                "installed".format(mindomainlevel=constants.MIN_DOMAIN_LEVEL))

        # Check authorization
        result = remote_api.Command['hostgroup_find'](
            cn=u'ipaservers', host=[unicode(api.env.host)])['result']
        add_to_ipaservers = not result

        if add_to_ipaservers:
            if options.password and not options.admin_password:
                raise errors.ACIError(info="Not authorized")

            if installer._ccache is None:
                del os.environ['KRB5CCNAME']
            else:
                os.environ['KRB5CCNAME'] = installer._ccache

            try:
                installutils.check_creds(options, config.realm_name)
                installer._ccache = os.environ.get('KRB5CCNAME')
            finally:
                os.environ['KRB5CCNAME'] = ccache

            conn.disconnect()
            conn.connect(ccache=installer._ccache)

            try:
                result = remote_api.Command['hostgroup_show'](
                    u'ipaservers', all=True, rights=True)['result']

                if 'w' not in result['attributelevelrights']['member']:
                    raise errors.ACIError(info="Not authorized")
            finally:
                conn.disconnect()
                conn.connect(ccache=ccache)

        # Check that we don't already have a replication agreement
        if replman.get_replication_agreement(config.host_name):
            msg = ("A replication agreement for this host already exists. "
                   "It needs to be removed.\n"
                   "Run this command:\n"
                   "    %% ipa-replica-manage del {host} --force".format(
                       host=config.host_name))
            raise ScriptError(msg, rval=3)

        # Detect if the other master can handle replication managers
        # cn=replication managers,cn=sysaccounts,cn=etc,$SUFFIX
        dn = DN(('cn', 'replication managers'), ('cn', 'sysaccounts'),
                ('cn', 'etc'), ipautil.realm_to_suffix(config.realm_name))
        try:
            conn.get_entry(dn)
        except errors.NotFound:
            msg = ("The Replication Managers group is not available in "
                   "the domain. Replica promotion requires the use of "
                   "Replication Managers to be able to replicate data. "
                   "Upgrade the peer master or use the ipa-replica-prepare "
                   "command on the master and use a prep file to install "
                   "this replica.")
            logger.error("%s", msg)
            raise ScriptError(rval=3)

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

        entry_attrs = conn.get_ipa_config()
        subject_base = entry_attrs.get('ipacertificatesubjectbase', [None])[0]
        if subject_base is not None:
            config.subject_base = DN(subject_base)

        # Find if any server has a CA
        ca_host = service.find_providing_server('CA', conn,
                                                config.ca_host_name)
        if ca_host is not None:
            config.ca_host_name = ca_host
            ca_enabled = True
            if options.dirsrv_cert_files:
                logger.error("Certificates could not be provided when "
                             "CA is present on some master.")
                raise ScriptError(rval=3)
        else:
            if options.setup_ca:
                logger.error("The remote master does not have a CA "
                             "installed, can't set up CA")
                raise ScriptError(rval=3)
            ca_enabled = False
            if not options.dirsrv_cert_files:
                logger.error("Cannot issue certificates: a CA is not "
                             "installed. Use the --http-cert-file, "
                             "--dirsrv-cert-file options to provide "
                             "custom certificates.")
                raise ScriptError(rval=3)

        kra_host = service.find_providing_server('KRA', conn,
                                                 config.kra_host_name)
        if kra_host is not None:
            config.kra_host_name = kra_host
            kra_enabled = True
        else:
            if options.setup_kra:
                logger.error("There is no KRA server in the domain, "
                             "can't setup a KRA clone")
                raise ScriptError(rval=3)
            kra_enabled = False

        if ca_enabled:
            options.realm_name = config.realm_name
            options.host_name = config.host_name
            ca.install_check(False, config, options)

        if kra_enabled:
            try:
                kra.install_check(remote_api, config, options)
            except RuntimeError as e:
                raise ScriptError(e)

        if options.setup_dns:
            dns.install_check(False, remote_api, True, options,
                              config.host_name)
            config.ips = dns.ip_addresses
        else:
            config.ips = installutils.get_server_ip_address(
                config.host_name, not installer.interactive, False,
                options.ip_addresses)

            # check addresses here, dns module is doing own check
            no_matching_interface_for_ip_address_warning(config.ips)

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

    except errors.ACIError:
        logger.debug("%s", traceback.format_exc())
        raise ScriptError("\nInsufficient privileges to promote the server."
                          "\nPossible issues:"
                          "\n- A user has insufficient privileges"
                          "\n- This client has insufficient privileges "
                          "to become an IPA replica")
    except errors.LDAPError:
        logger.debug("%s", traceback.format_exc())
        raise ScriptError("\nUnable to connect to LDAP server %s" %
                          config.master_host_name)
    finally:
        if replman and replman.conn:
            replman.conn.unbind()
        if conn.isconnected():
            conn.disconnect()

    # check connection
    if not options.skip_conncheck:
        if add_to_ipaservers:
            # use user's credentials when the server host is not ipaservers
            if installer._ccache is None:
                del os.environ['KRB5CCNAME']
            else:
                os.environ['KRB5CCNAME'] = installer._ccache

        try:
            replica_conn_check(config.master_host_name,
                               config.host_name,
                               config.realm_name,
                               options.setup_ca,
                               389,
                               options.admin_password,
                               principal=options.principal,
                               ca_cert_file=cafile)
        finally:
            if add_to_ipaservers:
                os.environ['KRB5CCNAME'] = ccache

    installer._ca_enabled = ca_enabled
    installer._kra_enabled = kra_enabled
    installer._ca_file = cafile
    installer._fstore = fstore
    installer._sstore = sstore
    installer._config = config
    installer._add_to_ipaservers = add_to_ipaservers
    installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file
    installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info
    installer._http_pkcs12_file = http_pkcs12_file
    installer._http_pkcs12_info = http_pkcs12_info
    installer._pkinit_pkcs12_file = pkinit_pkcs12_file
    installer._pkinit_pkcs12_info = pkinit_pkcs12_info
Пример #46
0
def create_reverse():
    return ipautil.user_input("Do you want to configure the reverse zone?", True)
Пример #47
0
def create_reverse():
    return ipautil.user_input("Do you want to configure the reverse zone?", True)
Пример #48
0
def run():
    try:
        check_client_configuration()
    except ScriptError as e:
        print(e.msg)
        return e.rval

    fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
    statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE)

    options, _args = parse_options()

    logfile = paths.IPACLIENTSAMBA_INSTALL_LOG
    if options.uninstall:
        logfile = paths.IPACLIENTSAMBA_UNINSTALL_LOG

    standard_logging_setup(
        logfile,
        verbose=False,
        debug=options.debug,
        filemode="a",
        console_format="%(message)s",
    )

    cfg = dict(
        context="cli_installer",
        confdir=paths.ETC_IPA,
        in_server=False,
        debug=options.debug,
        verbose=0,
    )

    # Bootstrap API early so that env object is available
    api.bootstrap(**cfg)

    local_config = dict(
        host_princ=str("host/%s@%s" % (api.env.host, api.env.realm)),
        smb_princ=str("cifs/%s@%s" % (api.env.host, api.env.realm)),
    )

    # Until api.finalize() is called, we can add our own configuration
    api.env._merge(**local_config)

    if options.uninstall:
        if statestore.has_state("domain_member"):
            uninstall(fstore, statestore, options)
            try:
                keys = ("configured", "hardening", "groupmap", "tdb",
                        "service.principal", "smb.conf")
                for key in keys:
                    statestore.delete_state("domain_member", key)
            except Exception as e:
                print("Error: Failed to remove the domain_member statestores: "
                      "%s" % e)
                return 1
            else:
                print("Samba configuration is reverted. "
                      "However, Samba databases were fully cleaned and "
                      "old configuration file will not be usable anymore.")
        else:
            print("Samba domain member is not configured yet")
        return 0

    ca_cert_path = None
    if os.path.exists(paths.IPA_CA_CRT):
        ca_cert_path = paths.IPA_CA_CRT

    if statestore.has_state("domain_member") and not options.force:
        print("Samba domain member is already configured")
        return CLIENT_ALREADY_CONFIGURED

    if not os.path.exists(paths.SMBD):
        print("Samba suite is not installed")
        return CLIENT_NOT_CONFIGURED

    autodiscover = False
    ds = discovery.IPADiscovery()
    if not options.server:
        print("Searching for IPA server...")
        ret = ds.search(ca_cert_path=ca_cert_path)
        logger.debug("Executing DNS discovery")
        if ret == discovery.NO_LDAP_SERVER:
            logger.debug("Autodiscovery did not find LDAP server")
            s = urlsplit(api.env.xmlrpc_uri)
            server = [s.netloc]
            logger.debug("Setting server to %s", s.netloc)
        else:
            autodiscover = True
            if not ds.servers:
                print(
                    "Autodiscovery was successful but didn't return a server")
                return 1
            logger.debug(
                "Autodiscovery success, possible servers %s",
                ",".join(ds.servers),
            )
            server = ds.servers[0]
    else:
        server = options.server
        logger.debug("Verifying that %s is an IPA server", server)
        ldapret = ds.ipacheckldap(server, api.env.realm, ca_cert_path)
        if ldapret[0] == discovery.NO_ACCESS_TO_LDAP:
            print("Anonymous access to the LDAP server is disabled.")
            print("Proceeding without strict verification.")
            print("Note: This is not an error if anonymous access has been "
                  "explicitly restricted.")
        elif ldapret[0] == discovery.NO_TLS_LDAP:
            logger.warning("Unencrypted access to LDAP is not supported.")
        elif ldapret[0] != 0:
            print("Unable to confirm that %s is an IPA server" % server)
            return 1

    if not autodiscover:
        print("IPA server: %s" % server)
        logger.debug("Using fixed server %s", server)
    else:
        print("IPA server: DNS discovery")
        logger.info("Configured to use DNS discovery")

    if api.env.host == server:
        logger.error("Cannot run on IPA master. "
                     "Cannot configure Samba as a domain member on a domain "
                     "controller. Please use ipa-adtrust-install for that!")
        return 1

    if not options.netbiosname:
        options.netbiosname = DNSName.from_text(api.env.host)[0].decode()
    options.netbiosname = options.netbiosname.upper()

    with use_api_as_principal(api.env.host_princ, paths.KRB5_KEYTAB):
        try:
            # Try to access 'service_add_smb' command, if it throws
            # AttributeError exception, the IPA server doesn't support
            # setting up Samba as a domain member.
            service_add_smb = api.Command.service_add_smb

            # Now try to see if SMB principal already exists
            api.Command.service_show(api.env.smb_princ)

            # If no exception was raised, the object exists.
            # We cannot continue because we would break existing configuration
            print("WARNING: SMB service principal %s already exists. "
                  "Please remove it before proceeding." % (api.env.smb_princ))
            if not options.force:
                return 1
            # For --force, we should then delete cifs/.. service object
            api.Command.service_del(api.env.smb_princ)
        except AttributeError:
            logger.error(
                "Chosen IPA master %s does not have support to "
                "set up Samba domain members",
                server,
            )
            return 1
        except errors.VersionError as e:
            print("This client is incompatible: " + str(e))
            return 1
        except errors.NotFound:
            logger.debug("No SMB service principal exists, OK to proceed")
        except errors.PublicError as e:
            logger.error(
                "Cannot connect to the server due to "
                "a generic error: %s",
                e,
            )
            return 1

        # At this point we have proper setup:
        # - we connected to IPA API end-point as a host principal
        # - no cifs/... principal exists so we can create it
        print("Chosen IPA master: %s" % server)
        print("SMB principal to be created: %s" % api.env.smb_princ)
        print("NetBIOS name to be used: %s" % options.netbiosname)
        logger.info("Chosen IPA master: %s", server)
        logger.info("SMB principal to be created: %s", api.env.smb_princ)
        logger.info("NetBIOS name to be used: %s", options.netbiosname)

        # 1. Pull down ID range and other details of known domains
        domains = retrieve_domain_information(api)
        if len(domains) == 0:
            # logger.error() produces both log file and stderr output
            logger.error("No configured trust controller detected "
                         "on IPA masters. Use ipa-adtrust-install on an IPA "
                         "master to configure trust controller role.")
            return 1

        str_info = pretty_print_domain_information(domains)
        logger.info("Discovered domains to use:\n%s", str_info)
        print("Discovered domains to use:\n%s" % str_info)

        if not options.unattended and not ipautil.user_input(
                "Continue to configure the system with these values?", False):
            print("Installation aborted")
            return 1

        # 2. Create SMB service principal, if we are here, the command exists
        if (not statestore.get_state("domain_member", "service.principal")
                or options.force):
            service_add_smb(api.env.host, options.netbiosname)
            statestore.backup_state("domain_member", "service.principal",
                                    "configured")

        # 3. Generate machine account password for reuse
        password = generate_smb_machine_account(fstore, statestore, options,
                                                domains[0])

        # 4. Now that we have all domains retrieved, we can generate smb.conf
        if (not statestore.get_state("domain_member", "smb.conf")
                or options.force):
            configure_smb_conf(fstore, statestore, options, domains)
            statestore.backup_state("domain_member", "smb.conf", "configured")

        # 5. Create SMB service
        if statestore.get_state("domain_member",
                                "service.principal") == "configured":
            retrieve_service_principal(fstore, statestore, options, domains[0],
                                       api.env.smb_princ, password)
            statestore.backup_state("domain_member", "service.principal",
                                    "configured")

        # 6. Configure databases to contain proper details
        if not statestore.get_state("domain_member", "tdb") or options.force:
            populate_samba_databases(fstore, statestore, options, domains[0],
                                     password)
            statestore.backup_state("domain_member", "tdb", "configured")

        # 7. Configure default group mapping
        if (not statestore.get_state("domain_member", "groupmap")
                or options.force):
            configure_default_groupmap(fstore, statestore, options, domains[0])
            statestore.backup_state("domain_member", "groupmap", "configured")

        # 8. Enable SELinux policies
        if (not statestore.get_state("domain_member", "hardening")
                or options.force):
            harden_configuration(fstore, statestore, options, domains[0])
            statestore.backup_state("domain_member", "hardening", "configured")

        # 9. Finally, store the state of upgrade
        statestore.backup_state("domain_member", "configured", True)

        # Suggest service start only after validating smb.conf
        print("Samba domain member is configured. "
              "Please check configuration at %s and "
              "start smb and winbind services" % paths.SMB_CONF)
        logger.info(
            "Samba domain member is configured. "
            "Please check configuration at %s and "
            "start smb and winbind services",
            paths.SMB_CONF,
        )

    return 0
Пример #49
0
    def run(self):
        if not is_ipa_configured():
            print("IPA is not configured.")
            return 2

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

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

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

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

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

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

        ca_subject_dn = ca.lookup_ca_subject(api, subject_base)

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

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

        print(msg)

        print_intentions(certs, extra_certs, non_renewed)

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

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

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

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

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

        print(renewal_note)
        return 0
Пример #50
0
def uninstall_check(installer):
    options = installer

    tasks.check_selinux_status()

    installer._installation_cleanup = False

    if not is_ipa_configured():
        print("WARNING:\nIPA server is not configured on this system. "
              "If you want to install the\nIPA server, please install "
              "it using 'ipa-server-install'.")

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

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

    # We will need at least api.env, finalize api now. This system is
    # already installed, so the configuration file is there.
    api.bootstrap(**cfg)
    api.finalize()

    if installer.interactive:
        print("\nThis is a NON REVERSIBLE operation and will delete all data "
              "and configuration!\nIt is highly recommended to take a backup of "
              "existing data and configuration using ipa-backup utility "
              "before proceeding.\n")
        if not user_input("Are you sure you want to continue with the "
                          "uninstall procedure?", False):
            raise ScriptError("Aborting uninstall operation.")

    try:
        api.Backend.ldap2.connect(autobind=True)

        domain_level = dsinstance.get_domain_level(api)
    except Exception:
        msg = ("\nWARNING: Failed to connect to Directory Server to find "
               "information about replication agreements. Uninstallation "
               "will continue despite the possible existing replication "
               "agreements.\n\n"
               "If this server is the last instance of CA, KRA, or DNSSEC "
               "master, uninstallation may result in data loss.\n\n"
        )
        print(textwrap.fill(msg, width=80, replace_whitespace=False))

        if (installer.interactive and not user_input(
                "Are you sure you want to continue with the uninstall "
                "procedure?", False)):
            raise ScriptError("Aborting uninstall operation.")
    else:
        dns.uninstall_check(options)

        ca.uninstall_check(options)

        if domain_level == DOMAIN_LEVEL_0:
            rm = replication.ReplicationManager(
                realm=api.env.realm,
                hostname=api.env.host,
                dirman_passwd=None,
                conn=api.Backend.ldap2
            )
            agreements = rm.find_ipa_replication_agreements()

            if agreements:
                other_masters = [a.get('cn')[0][4:] for a in agreements]
                msg = (
                    "\nReplication agreements with the following IPA masters "
                    "found: %s. Removing any replication agreements before "
                    "uninstalling the server is strongly recommended. You can "
                    "remove replication agreements by running the following "
                    "command on any other IPA master:\n" % ", ".join(
                        other_masters)
                )
                cmd = "$ ipa-replica-manage del %s\n" % api.env.host
                print(textwrap.fill(msg, width=80, replace_whitespace=False))
                print(cmd)
                if (installer.interactive and
                        not user_input("Are you sure you want to continue with"
                                       " the uninstall procedure?", False)):
                    raise ScriptError("Aborting uninstall operation.")
        else:
            remove_master_from_managed_topology(api, options)

        api.Backend.ldap2.disconnect()

    installer._fstore = fstore
    installer._sstore = sstore
Пример #51
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)

        logger.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")

        logger.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):
            logger.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")

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

        logger.info("Temporary setting umask to 022")
        old_umask = os.umask(0o022)
        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")

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

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

            if restore_type != 'FULL':
                if not options.online:
                    logger.info('Stopping Directory Server')
                    dirsrv.stop(capture_output=False)
                else:
                    logger.info('Starting Directory Server')
                    dirsrv.start(capture_output=False)
            else:
                logger.info('Stopping IPA services')
                result = run([paths.IPACTL, 'stop'], raiseonerr=False)
                if result.returncode not in [0, 6]:
                    logger.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()
                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
            # 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:
                    logger.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()

                logger.info('Restarting GSS-proxy')
                gssproxy = services.service('gssproxy', api)
                gssproxy.reload_or_restart()
                logger.info('Starting IPA services')
                run([paths.IPACTL, 'start'])
                logger.info('Restarting SSSD')
                sssd = services.service('sssd', api)
                sssd.restart()
                logger.info('Restarting oddjobd')
                oddjobd = services.service('oddjobd', api)
                if not oddjobd.is_enabled():
                    logger.info("Enabling oddjobd")
                    oddjobd.enable()
                oddjobd.start()
                http.remove_httpd_ccaches()
                # have the daemons pick up their restored configs
                run([paths.SYSTEMCTL, "--system", "daemon-reload"])
        finally:
            try:
                os.chdir(cwd)
            except Exception as e:
                logger.error('Cannot change directory to %s: %s', cwd, e)
            shutil.rmtree(self.top_dir)
            logger.info("Restoring umask to %s", old_umask)
            os.umask(old_umask)
Пример #52
0
    def run(self):
        if not is_ipa_configured():
            print("IPA is not configured.")
            return 2

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

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

        api.bootstrap(in_server=True, confdir=paths.ETC_IPA)
        api.finalize()
        api.Backend.ldap2.connect()  # ensure DS is up

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

        ca_subject_dn = ca.lookup_ca_subject(api, subject_base)

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

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

        print(msg)

        print_intentions(certs, extra_certs)

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

        try:
            run_cert_fix(certs, extra_certs)
        except ipautil.CalledProcessError:
            if any(x[0] is IPACertType.LDAPS for x in extra_certs):
                # The DS cert was expired.  This will cause
                # 'pki-server cert-fix' to fail at the final
                # restart.  Therefore ignore the CalledProcessError
                # and proceed to installing the IPA-specific certs.
                pass
            else:
                raise  # otherwise re-raise

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

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

        ipautil.run(['ipactl', 'restart'], raiseonerr=True)

        return 0
Пример #53
0
        try:
            ipaclient.ntpconf.check_timedate_services()
        except ipaclient.ntpconf.NTPConflictingService, e:
            print("WARNING: conflicting time&date synchronization service '%s'"
                  " will be disabled" % e.conflicting_service)
            print "in favor of ntpd"
            print ""
        except ipaclient.ntpconf.NTPConfigurationError:
            pass

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

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

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

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

    host_default = ""
    if options.host_name:
Пример #54
0
def check_inst(unattended):
    if not unattended and os.path.exists(NAMED_CONF):
        msg = "Existing BIND configuration detected, overwrite?"
        return ipautil.user_input(msg, False)

    return True
Пример #55
0
def uninstall_check(options):
    global ds
    global installation_cleanup

    # Use private ccache
    init_private_ccache()

    ds = None

    tasks.check_selinux_status()

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

    installation_cleanup = False

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

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

    # We will need at least api.env, finalize api now. This system is
    # already installed, so the configuration file is there.
    api.bootstrap(**cfg)
    api.finalize()

    if not options.unattended:
        print("\nThis is a NON REVERSIBLE operation and will delete all data "
              "and configuration!\n")
        if not user_input("Are you sure you want to continue with the "
                          "uninstall procedure?", False):
            print ""
            print "Aborting uninstall operation."
            sys.exit(1)

    try:
        conn = ipaldap.IPAdmin(
            api.env.host,
            ldapi=True,
            realm=api.env.realm
        )
        conn.do_external_bind(pwd.getpwuid(os.geteuid()).pw_name)
    except Exception:
        msg = ("\nWARNING: Failed to connect to Directory Server to find "
               "information about replication agreements. Uninstallation "
               "will continue despite the possible existing replication "
               "agreements.\n\n")
        print textwrap.fill(msg, width=80, replace_whitespace=False)
    else:
        api.Backend.ldap2.connect(autobind=True)
        dns.uninstall_check(options)

        rm = replication.ReplicationManager(
            realm=api.env.realm,
            hostname=api.env.host,
            dirman_passwd=None,
            conn=conn
        )
        agreements = rm.find_ipa_replication_agreements()

        if agreements:
            other_masters = [a.get('cn')[0][4:] for a in agreements]
            msg = (
                "\nReplication agreements with the following IPA masters "
                "found: %s. Removing any replication agreements before "
                "uninstalling the server is strongly recommended. You can "
                "remove replication agreements by running the following "
                "command on any other IPA master:\n" % ", ".join(
                    other_masters)
            )
            cmd = "$ ipa-replica-manage del %s\n" % api.env.host
            print textwrap.fill(msg, width=80, replace_whitespace=False)
            print cmd
            if not (options.unattended or user_input("Are you sure you "
                                                     "want to continue "
                                                     "with the uninstall "
                                                     "procedure?",
                                                     False)):
                print ""
                print "Aborting uninstall operation."
                sys.exit(1)
Пример #56
0
def install_check(standalone, options, api):
    global netbios_name
    global reset_netbios_name

    if standalone:
        check_for_installed_deps()

    realm_not_matching_domain = (api.env.domain.upper() != api.env.realm)

    if realm_not_matching_domain:
        print("WARNING: Realm name does not match the domain name.\n"
              "You will not be able to estabilish trusts with Active "
              "Directory unless\nthe realm name of the IPA server matches its "
              "domain name.\n\n")
        if not options.unattended:
            if not ipautil.user_input("Do you wish to continue?",
                                      default=False,
                                      allow_empty=False):
                raise ScriptError("Aborting installation.")

    # Check if /etc/samba/smb.conf already exists. In case it was not generated
    # by IPA, print a warning that we will break existing configuration.

    if adtrustinstance.ipa_smb_conf_exists():
        if not options.unattended:
            print("IPA generated smb.conf detected.")
            if not ipautil.user_input(
                    "Overwrite smb.conf?", default=False, allow_empty=False):
                raise ScriptError("Aborting installation.")

    elif os.path.exists(paths.SMB_CONF):
        print("WARNING: The smb.conf already exists. Running "
              "ipa-adtrust-install will break your existing samba "
              "configuration.\n\n")
        if not options.unattended:
            if not ipautil.user_input("Do you wish to continue?",
                                      default=False,
                                      allow_empty=False):
                raise ScriptError("Aborting installation.")
    elif os.path.exists(paths.SMB_CONF):
        print("WARNING: The smb.conf already exists. Running "
              "ipa-adtrust-install will break your existing samba "
              "configuration.\n\n")
        if not options.unattended:
            if not ipautil.user_input("Do you wish to continue?",
                                      default=False,
                                      allow_empty=False):
                raise ScriptError("Aborting installation.")

    if not options.unattended and not options.enable_compat:
        options.enable_compat = enable_compat_tree()

    netbios_name, reset_netbios_name = set_and_check_netbios_name(
        options.netbios_name, options.unattended, api)

    if not options.add_sids:
        # The filter corresponds to ipa_sidgen_task.c LDAP search filter
        filter = '(&(objectclass=ipaobject)(!(objectclass=mepmanagedentry))' \
                 '(|(objectclass=posixaccount)(objectclass=posixgroup)' \
                 '(objectclass=ipaidobject))(!(ipantsecurityidentifier=*)))'
        base_dn = api.env.basedn
        try:
            root_logger.debug(
                "Searching for objects with missing SID with "
                "filter=%s, base_dn=%s", filter, base_dn)
            entries, _truncated = api.Backend.ldap2.find_entries(
                filter=filter, base_dn=base_dn, attrs_list=[''])
        except errors.NotFound:
            # All objects have SIDs assigned
            pass
        except (errors.DatabaseError, errors.NetworkError) as e:
            print("Could not retrieve a list of objects that need a SID "
                  "identifier assigned:")
            print(unicode(e))
        else:
            object_count = len(entries)
            if object_count > 0:
                print("")
                print("WARNING: %d existing users or groups do not have "
                      "a SID identifier assigned." % len(entries))
                print("Installer can run a task to have ipa-sidgen "
                      "Directory Server plugin generate")
                print("the SID identifier for all these users. Please note, "
                      "the in case of a high")
                print("number of users and groups, the operation might "
                      "lead to high replication")
                print("traffic and performance degradation. Refer to "
                      "ipa-adtrust-install(1) man page")
                print("for details.")
                print("")
                if options.unattended:
                    print("Unattended mode was selected, installer will "
                          "NOT run ipa-sidgen task!")
                else:
                    if ipautil.user_input(
                            "Do you want to run the ipa-sidgen task?",
                            default=False,
                            allow_empty=False):
                        options.add_sids = True
Пример #57
0
def install_check(installer):
    options = installer
    dirsrv_pkcs12_file = installer._dirsrv_pkcs12_file
    http_pkcs12_file = installer._http_pkcs12_file
    pkinit_pkcs12_file = installer._pkinit_pkcs12_file
    dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
    http_pkcs12_info = installer._http_pkcs12_info
    pkinit_pkcs12_info = installer._pkinit_pkcs12_info
    external_cert_file = installer._external_cert_file
    external_ca_file = installer._external_ca_file
    http_ca_cert = installer._ca_cert
    dirsrv_ca_cert = None
    pkinit_ca_cert = None

    tasks.check_ipv6_stack_enabled()
    tasks.check_selinux_status()
    check_ldap_conf()

    mask_str = validate_mask()
    if mask_str:
        print("Unexpected system mask: %s, expected 0022" % mask_str)
        if installer.interactive:
            if not user_input("Do you want to continue anyway?", True):
                raise ScriptError(
                    "Unexpected system mask: %s" % mask_str)
        else:
            raise ScriptError("Unexpected system mask: %s" % mask_str)

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

    installer._installation_cleanup = True

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

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

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

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

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

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

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

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

    if not options.no_ntp:
        try:
            timeconf.check_timedate_services()
        except timeconf.NTPConflictingService as e:
            print(
                "WARNING: conflicting time&date synchronization service "
                "'{}' will be disabled in favor of chronyd\n".format(
                    e.conflicting_service
                )
            )
        except timeconf.NTPConfigurationError:
            pass

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

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

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

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

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

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

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

    domain_name = domain_name.lower()

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

        try:
            validate_domain_name(realm_name, entity="realm")
        except ValueError as e:
            raise ScriptError("Invalid realm name: {}".format(unicode(e)))
    else:
        realm_name = options.realm_name.upper()

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

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

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

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

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

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

    if (options.http_cert_files and
            options.pkinit_cert_files and
            http_ca_cert != pkinit_ca_cert):
        raise ScriptError(
            "Apache Server SSL certificate and PKINIT KDC "
            "certificate are not signed by the same CA certificate")

    if not options.dm_password:
        dm_password = read_dm_password()

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

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

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

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

    # Create the management framework config file and finalize api
    target_fname = paths.IPA_DEFAULT_CONF
    ipaconf = IPAChangeConf("IPA Server Install")
    ipaconf.setOptionAssignment(" = ")
    ipaconf.setSectionNameDelimiters(("[", "]"))

    xmlrpc_uri = 'https://{0}/ipa/xml'.format(
                    ipautil.format_netloc(host_name))
    ldapi_uri = ipaldap.realm_to_ldapi_uri(realm_name)

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

    if setup_ca:
        gopts.extend([
            ipaconf.setOption('enable_ra', 'True'),
            ipaconf.setOption('ra_plugin', 'dogtag'),
            ipaconf.setOption('dogtag_version', '10')
        ])
    else:
        gopts.extend([
            ipaconf.setOption('enable_ra', 'False'),
            ipaconf.setOption('ra_plugin', 'None')
        ])

    opts = [
        ipaconf.setSection('global', gopts),
        {'name': 'empty', 'type': 'empty'}
    ]

    ipaconf.newConf(target_fname, opts)

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

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

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

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

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

    instance_name = "-".join(realm_name.split("."))
    dirsrv = services.knownservices.dirsrv
    if (options.external_cert_files
           and dirsrv.is_installed(instance_name)
           and not dirsrv.is_running(instance_name)):
        logger.debug('Starting Directory Server')
        services.knownservices.dirsrv.start(instance_name)

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

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

    if not options.no_ntp and not options.unattended and not (
            options.ntp_servers or options.ntp_pool):
        options.ntp_servers, options.ntp_pool = timeconf.get_time_source()

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

    if setup_ca:
        ca.print_ca_configuration(options)
        print()

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

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

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

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

    if options.ntp_servers or options.ntp_pool:
        if options.ntp_servers:
            for server in options.ntp_servers:
                print("NTP server:\t{}".format(server))

        if options.ntp_pool:
            print("NTP pool:\t{}".format(options.ntp_pool))

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

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

    installer._fstore = fstore
    installer._sstore = sstore
    installer._dirsrv_pkcs12_file = dirsrv_pkcs12_file
    installer._http_pkcs12_file = http_pkcs12_file
    installer._pkinit_pkcs12_file = pkinit_pkcs12_file
    installer._dirsrv_pkcs12_info = dirsrv_pkcs12_info
    installer._http_pkcs12_info = http_pkcs12_info
    installer._pkinit_pkcs12_info = pkinit_pkcs12_info
    installer._external_cert_file = external_cert_file
    installer._external_ca_file = external_ca_file
    installer._ca_cert = http_ca_cert
Пример #58
0
def set_and_check_netbios_name(netbios_name, unattended, api):
    """
    Depending if trust in already configured or not a given NetBIOS domain
    name must be handled differently.

    If trust is not configured the given NetBIOS is used or the NetBIOS is
    generated if none was given on the command line.

    If trust is  already configured the given NetBIOS name is used to reset
    the stored NetBIOS name it it differs from the current one.
    """

    flat_name_attr = 'ipantflatname'
    cur_netbios_name = None
    gen_netbios_name = None
    reset_netbios_name = False
    entry = None

    try:
        entry = api.Backend.ldap2.get_entry(
            DN(('cn', api.env.domain), api.env.container_cifsdomains,
               ipautil.realm_to_suffix(api.env.realm)), [flat_name_attr])
    except errors.NotFound:
        # trust not configured
        pass
    else:
        cur_netbios_name = entry.get(flat_name_attr)[0]

    if cur_netbios_name and not netbios_name:
        # keep the current NetBIOS name
        netbios_name = cur_netbios_name
        reset_netbios_name = False
    elif cur_netbios_name and cur_netbios_name != netbios_name:
        # change the NetBIOS name
        print("Current NetBIOS domain name is %s, new name is %s.\n" %
              (cur_netbios_name, netbios_name))
        print("Please note that changing the NetBIOS name might "
              "break existing trust relationships.")
        if unattended:
            reset_netbios_name = True
            print("NetBIOS domain name will be changed to %s.\n" %
                  netbios_name)
        else:
            print("Say 'yes' if the NetBIOS shall be changed and "
                  "'no' if the old one shall be kept.")
            reset_netbios_name = ipautil.user_input(
                'Do you want to reset the NetBIOS domain name?',
                default=False,
                allow_empty=False)
        if not reset_netbios_name:
            netbios_name = cur_netbios_name
    elif cur_netbios_name and cur_netbios_name == netbios_name:
        # keep the current NetBIOS name
        reset_netbios_name = False
    elif not cur_netbios_name:
        if not netbios_name:
            gen_netbios_name = adtrustinstance.make_netbios_name(
                api.env.domain)

        if entry is not None:
            # Fix existing trust configuration
            print("Trust is configured but no NetBIOS domain name found, "
                  "setting it now.")
            reset_netbios_name = True
        else:
            # initial trust configuration
            reset_netbios_name = False
    else:
        # all possible cases should be covered above
        raise Exception('Unexpected state while checking NetBIOS domain name')

    if unattended and netbios_name is None and gen_netbios_name:
        netbios_name = gen_netbios_name

    if not adtrustinstance.check_netbios_name(netbios_name):
        if unattended:
            netbios_name_error(netbios_name)
            raise ScriptError("Aborting installation.")
        else:
            if netbios_name:
                netbios_name_error(netbios_name)
                netbios_name = None

    if not unattended and not netbios_name:
        netbios_name = read_netbios_name(gen_netbios_name)

    return (netbios_name, reset_netbios_name)
Пример #59
0
def add_new_adtrust_agents(api, options):
    """
    Find out IPA masters which are not part of the cn=adtrust agents
    and propose them to be added to the list
    :param api: API instance
    :param options: parsed CLI options
    """
    potential_agents_cns = retrieve_potential_adtrust_agents(api)

    if potential_agents_cns:
        print("")
        print("WARNING: %d IPA masters are not yet able to serve "
              "information about users from trusted forests."
              % len(potential_agents_cns))
        print("Installer can add them to the list of IPA masters "
              "allowed to access information about trusts.")
        print("If you choose to do so, you also need to restart "
              "LDAP service on those masters.")
        print("Refer to ipa-adtrust-install(1) man page for details.")
        print("")
        if options.unattended:
            print("Unattended mode was selected, installer will NOT "
                  "add other IPA masters to the list of allowed to")
            print("access information about trusted forests!")
            return

    new_agents = []

    for name in sorted(potential_agents_cns):
        if ipautil.user_input(
                "IPA master [%s]?" % (name),
                default=False,
                allow_empty=False):
            new_agents.append(name)

    if new_agents:
        add_hosts_to_adtrust_agents(api, new_agents)

        # The method trust_enable_agent was added on API version 2.236
        # Specifically request this version in the remote call
        kwargs = {u'version': u'2.236',
                  u'enable_compat': options.enable_compat}
        failed_agents = []
        for agent in new_agents:
            # Try to run the ipa-trust-enable-agent script on the agent
            # If the agent is too old and does not support this,
            # print a msg
            logger.info("Execute trust_enable_agent on remote server %s",
                        agent)
            client = None
            try:
                xmlrpc_uri = 'https://{}/ipa/xml'.format(
                    ipautil.format_netloc(agent))
                remote_api = create_api(mode=None)
                remote_api.bootstrap(context='installer',
                                     confdir=paths.ETC_IPA,
                                     xmlrpc_uri=xmlrpc_uri,
                                     fallback=False)
                client = rpc.jsonclient(remote_api)
                client.finalize()
                client.connect()
                result = client.forward(
                    u'trust_enable_agent',
                    ipautil.fsdecode(agent),
                    **kwargs)
            except errors.CommandError as e:
                logger.debug(
                    "Remote server %s does not support agent enablement "
                    "over RPC: %s", agent, e)
                failed_agents.append(agent)
            except (errors.PublicError, ConnectionRefusedError) as e:
                logger.debug(
                    "Remote call to trust_enable_agent failed on server %s: "
                    "%s", agent, e)
                failed_agents.append(agent)
            else:
                for message in result.get('messages'):
                    logger.debug('%s', message['message'])
                if not int(result['result']):
                    logger.debug(
                        "ipa-trust-enable-agent returned non-zero exit code "
                        " on server %s", agent)
                    failed_agents.append(agent)
            finally:
                if client and client.isconnected():
                    client.disconnect()

        # if enablement failed on some agents, print a WARNING:
        if failed_agents:
            if options.enable_compat:
                print("""
WARNING: you MUST manually enable the Schema compatibility Plugin and """)
            print("""
WARNING: you MUST restart (both "ipactl restart" and "systemctl restart sssd")
the following IPA masters in order to activate them to serve information about
users from trusted forests:
""")

            for x in failed_agents:
                print(x)