Beispiel #1
0
class DNSInstallInterface(hostname.HostNameInstallInterface):
    """
    Interface of the DNS installer

    Knobs defined here will be available in:
    * ipa-server-install
    * ipa-replica-prepare
    * ipa-replica-install
    * ipa-dns-install
    """

    allow_zone_overlap = knob(
        None,
        description="Create DNS zone even if it already exists",
    )
    allow_zone_overlap = prepare_only(allow_zone_overlap)

    reverse_zones = knob(
        # pylint: disable=invalid-sequence-index
        typing.List[str],
        [],
        description=("The reverse DNS zone to use. This option can be used "
                     "multiple times"),
        cli_names='--reverse-zone',
        cli_metavar='REVERSE_ZONE',
    )
    reverse_zones = prepare_only(reverse_zones)

    @reverse_zones.validator
    def reverse_zones(self, values):
        if not self.allow_zone_overlap:
            for zone in values:
                check_zone_overlap(zone)

    no_reverse = knob(
        None,
        description="Do not create new reverse DNS zone",
    )
    no_reverse = prepare_only(no_reverse)

    auto_reverse = knob(
        None,
        description="Create necessary reverse zones",
    )
    auto_reverse = prepare_only(auto_reverse)

    zonemgr = knob(
        str,
        None,
        description=("DNS zone manager e-mail address. Defaults to "
                     "hostmaster@DOMAIN"),
    )
    zonemgr = prepare_only(zonemgr)

    @zonemgr.validator
    def zonemgr(self, value):
        # validate the value first
        try:
            # IDNA support requires unicode
            encoding = getattr(sys.stdin, 'encoding', None)
            if encoding is None:
                encoding = 'utf-8'
            value = value.decode(encoding)
            bindinstance.validate_zonemgr_str(value)
        except ValueError as e:
            # FIXME we can do this in better way
            # https://fedorahosted.org/freeipa/ticket/4804
            # decode to proper stderr encoding
            stderr_encoding = getattr(sys.stderr, 'encoding', None)
            if stderr_encoding is None:
                stderr_encoding = 'utf-8'
            error = unicode(e).encode(stderr_encoding)
            raise ValueError(error)

    forwarders = knob(
        # pylint: disable=invalid-sequence-index
        typing.List[ipautil.CheckedIPAddress],
        None,
        description=("Add a DNS forwarder. This option can be used multiple "
                     "times"),
        cli_names='--forwarder',
    )
    forwarders = enroll_only(forwarders)

    no_forwarders = knob(
        None,
        description="Do not add any DNS forwarders, use root servers instead",
    )
    no_forwarders = enroll_only(no_forwarders)

    auto_forwarders = knob(
        None,
        description="Use DNS forwarders configured in /etc/resolv.conf",
    )
    auto_forwarders = enroll_only(auto_forwarders)

    forward_policy = knob(
        DNSForwardPolicy,
        None,
        description=("DNS forwarding policy for global forwarders"),
    )
    forward_policy = enroll_only(forward_policy)

    no_dnssec_validation = knob(
        None,
        description="Disable DNSSEC validation",
    )
    no_dnssec_validation = enroll_only(no_dnssec_validation)

    dnssec_master = False
    disable_dnssec_master = False
    kasp_db_file = None
    force = False
Beispiel #2
0
class ServerInstallInterface(client.ClientInstallInterface,
                             ca.CAInstallInterface, kra.KRAInstallInterface,
                             dns.DNSInstallInterface,
                             conncheck.ConnCheckInterface):
    """
    Interface of server installers

    Knobs defined here will be available in:
    * ipa-server-install
    * ipa-replica-prepare
    * ipa-replica-install
    """

    force_join = False
    kinit_attempts = 1
    fixed_primary = True
    ntp_servers = None
    force_ntpd = False
    permit = False
    enable_dns_updates = False
    no_krb5_offline_passwords = False
    preserve_sssd = False

    domain_name = knob(
        bases=client.ClientInstallInterface.domain_name,
        # pylint: disable=no-member
        cli_names=(list(client.ClientInstallInterface.domain_name.cli_names) +
                   ['-n']),
    )

    servers = knob(
        bases=client.ClientInstallInterface.servers,
        description="fully qualified name of IPA server to enroll to",
    )
    servers = enroll_only(servers)

    realm_name = knob(
        bases=client.ClientInstallInterface.realm_name,
        cli_names=(list(client.ClientInstallInterface.realm_name.cli_names) +
                   ['-r']),
    )

    host_name = knob(
        bases=client.ClientInstallInterface.host_name,
        description="fully qualified name of this host",
    )

    ca_cert_files = knob(
        bases=client.ClientInstallInterface.ca_cert_files,
        description="File containing CA certificates for the service "
        "certificate files",
        cli_deprecated_names='--root-ca-file',
    )
    ca_cert_files = prepare_only(ca_cert_files)

    dm_password = knob(
        bases=client.ClientInstallInterface.dm_password,
        description="Directory Manager password",
    )

    ip_addresses = knob(
        bases=client.ClientInstallInterface.ip_addresses,
        description="Server IP Address. This option can be used multiple "
        "times",
    )

    principal = knob(
        bases=client.ClientInstallInterface.principal,
        description="User Principal allowed to promote replicas and join IPA "
        "realm",
        cli_names=(list(client.ClientInstallInterface.principal.cli_names) +
                   ['-P']),
    )
    principal = replica_install_only(principal)

    master_password = knob(
        str,
        None,
        sensitive=True,
        deprecated=True,
        description="kerberos master password (normally autogenerated)",
    )
    master_password = master_install_only(master_password)

    domain_level = knob(
        int,
        constants.MAX_DOMAIN_LEVEL,
        description="IPA domain level",
        deprecated=True,
    )
    domain_level = master_install_only(domain_level)

    @domain_level.validator
    def domain_level(self, value):
        # Check that Domain Level is within the allowed range
        if value < constants.MIN_DOMAIN_LEVEL:
            raise ValueError("Domain Level cannot be lower than {0}".format(
                constants.MIN_DOMAIN_LEVEL))
        elif value > constants.MAX_DOMAIN_LEVEL:
            raise ValueError("Domain Level cannot be higher than {0}".format(
                constants.MAX_DOMAIN_LEVEL))

    setup_ca = knob(
        None,
        description="configure a dogtag CA",
    )
    setup_ca = enroll_only(setup_ca)

    setup_kra = knob(
        None,
        description="configure a dogtag KRA",
    )
    setup_kra = enroll_only(setup_kra)

    setup_dns = knob(
        None,
        description="configure bind with our zone",
    )
    setup_dns = enroll_only(setup_dns)

    idstart = knob(
        int,
        random.randint(1, 10000) * 200000,
        description="The starting value for the IDs range (default random)",
    )
    idstart = master_install_only(idstart)

    idmax = knob(
        int,
        description=("The max value for the IDs range (default: "
                     "idstart+199999)"),
    )
    idmax = master_install_only(idmax)

    @idmax.default_getter
    def idmax(self):
        return self.idstart + 200000 - 1

    no_hbac_allow = knob(
        None,
        description="Don't install allow_all HBAC rule",
        cli_deprecated_names='--no_hbac_allow',
    )
    no_hbac_allow = master_install_only(no_hbac_allow)

    ignore_topology_disconnect = knob(
        None,
        description="do not check whether server uninstall disconnects the "
        "topology (domain level 1+)",
    )
    ignore_topology_disconnect = master_install_only(
        ignore_topology_disconnect)

    ignore_last_of_role = knob(
        None,
        description="do not check whether server uninstall removes last "
        "CA/DNS server or DNSSec master (domain level 1+)",
    )
    ignore_last_of_role = master_install_only(ignore_last_of_role)

    no_pkinit = knob(
        None,
        description="disables pkinit setup steps",
    )
    no_pkinit = prepare_only(no_pkinit)

    no_ui_redirect = knob(
        None,
        description="Do not automatically redirect to the Web UI",
    )
    no_ui_redirect = enroll_only(no_ui_redirect)

    ssh_trust_dns = knob(
        None,
        description="configure OpenSSH client to trust DNS SSHFP records",
    )
    ssh_trust_dns = enroll_only(ssh_trust_dns)

    no_ssh = knob(
        None,
        description="do not configure OpenSSH client",
    )
    no_ssh = enroll_only(no_ssh)

    no_sshd = knob(
        None,
        description="do not configure OpenSSH server",
    )
    no_sshd = enroll_only(no_sshd)

    no_dns_sshfp = knob(
        None,
        description="Do not automatically create DNS SSHFP records",
    )
    no_dns_sshfp = enroll_only(no_dns_sshfp)

    dirsrv_config_file = knob(
        str,
        None,
        description="The path to LDIF file that will be used to modify "
        "configuration of dse.ldif during installation of the "
        "directory server instance",
        cli_metavar='FILE',
    )
    dirsrv_config_file = enroll_only(dirsrv_config_file)

    @dirsrv_config_file.validator
    def dirsrv_config_file(self, value):
        if not os.path.exists(value):
            raise ValueError("File %s does not exist." % value)

    dirsrv_cert_files = knob(
        # pylint: disable=invalid-sequence-index
        typing.List[str],
        None,
        description=("File containing the Directory Server SSL certificate "
                     "and private key"),
        cli_names='--dirsrv-cert-file',
        cli_deprecated_names='--dirsrv_pkcs12',
        cli_metavar='FILE',
    )
    dirsrv_cert_files = prepare_only(dirsrv_cert_files)

    http_cert_files = knob(
        # pylint: disable=invalid-sequence-index
        typing.List[str],
        None,
        description=("File containing the Apache Server SSL certificate and "
                     "private key"),
        cli_names='--http-cert-file',
        cli_deprecated_names='--http_pkcs12',
        cli_metavar='FILE',
    )
    http_cert_files = prepare_only(http_cert_files)

    pkinit_cert_files = knob(
        # pylint: disable=invalid-sequence-index
        typing.List[str],
        None,
        description=("File containing the Kerberos KDC SSL certificate and "
                     "private key"),
        cli_names='--pkinit-cert-file',
        cli_deprecated_names='--pkinit_pkcs12',
        cli_metavar='FILE',
    )
    pkinit_cert_files = prepare_only(pkinit_cert_files)

    dirsrv_pin = knob(
        str,
        None,
        sensitive=True,
        description="The password to unlock the Directory Server private key",
        cli_deprecated_names='--dirsrv_pin',
        cli_metavar='PIN',
    )
    dirsrv_pin = prepare_only(dirsrv_pin)

    http_pin = knob(
        str,
        None,
        sensitive=True,
        description="The password to unlock the Apache Server private key",
        cli_deprecated_names='--http_pin',
        cli_metavar='PIN',
    )
    http_pin = prepare_only(http_pin)

    pkinit_pin = knob(
        str,
        None,
        sensitive=True,
        description="The password to unlock the Kerberos KDC private key",
        cli_deprecated_names='--pkinit_pin',
        cli_metavar='PIN',
    )
    pkinit_pin = prepare_only(pkinit_pin)

    dirsrv_cert_name = knob(
        str,
        None,
        description="Name of the Directory Server SSL certificate to install",
        cli_metavar='NAME',
    )
    dirsrv_cert_name = prepare_only(dirsrv_cert_name)

    http_cert_name = knob(
        str,
        None,
        description="Name of the Apache Server SSL certificate to install",
        cli_metavar='NAME',
    )
    http_cert_name = prepare_only(http_cert_name)

    pkinit_cert_name = knob(
        str,
        None,
        description="Name of the Kerberos KDC SSL certificate to install",
        cli_metavar='NAME',
    )
    pkinit_cert_name = prepare_only(pkinit_cert_name)

    def __init__(self, **kwargs):
        super(ServerInstallInterface, self).__init__(**kwargs)

        # If any of the key file options are selected, all are required.
        cert_file_req = (self.dirsrv_cert_files, self.http_cert_files)
        cert_file_opt = (self.pkinit_cert_files, )
        if any(cert_file_req + cert_file_opt) and not all(cert_file_req):
            raise RuntimeError(
                "--dirsrv-cert-file and --http-cert-file are required if any "
                "key file options are used.")

        if not self.interactive:
            if self.dirsrv_cert_files and self.dirsrv_pin is None:
                raise RuntimeError(
                    "You must specify --dirsrv-pin with --dirsrv-cert-file")
            if self.http_cert_files and self.http_pin is None:
                raise RuntimeError(
                    "You must specify --http-pin with --http-cert-file")
            if self.pkinit_cert_files and self.pkinit_pin is None:
                raise RuntimeError(
                    "You must specify --pkinit-pin with --pkinit-cert-file")

        if not self.setup_dns:
            if self.forwarders:
                raise RuntimeError(
                    "You cannot specify a --forwarder option without the "
                    "--setup-dns option")
            if self.auto_forwarders:
                raise RuntimeError(
                    "You cannot specify a --auto-forwarders option without "
                    "the --setup-dns option")
            if self.no_forwarders:
                raise RuntimeError(
                    "You cannot specify a --no-forwarders option without the "
                    "--setup-dns option")
            if self.forward_policy:
                raise RuntimeError(
                    "You cannot specify a --forward-policy option without the "
                    "--setup-dns option")
            if self.reverse_zones:
                raise RuntimeError(
                    "You cannot specify a --reverse-zone option without the "
                    "--setup-dns option")
            if self.auto_reverse:
                raise RuntimeError(
                    "You cannot specify a --auto-reverse option without the "
                    "--setup-dns option")
            if self.no_reverse:
                raise RuntimeError(
                    "You cannot specify a --no-reverse option without the "
                    "--setup-dns option")
            if self.no_dnssec_validation:
                raise RuntimeError(
                    "You cannot specify a --no-dnssec-validation option "
                    "without the --setup-dns option")
        elif self.forwarders and self.no_forwarders:
            raise RuntimeError(
                "You cannot specify a --forwarder option together with "
                "--no-forwarders")
        elif self.auto_forwarders and self.no_forwarders:
            raise RuntimeError(
                "You cannot specify a --auto-forwarders option together with "
                "--no-forwarders")
        elif self.reverse_zones and self.no_reverse:
            raise RuntimeError(
                "You cannot specify a --reverse-zone option together with "
                "--no-reverse")
        elif self.auto_reverse and self.no_reverse:
            raise RuntimeError(
                "You cannot specify a --auto-reverse option together with "
                "--no-reverse")

        if not hasattr(self, 'replica_file'):
            if self.external_cert_files and self.dirsrv_cert_files:
                raise RuntimeError(
                    "Service certificate file options cannot be used with the "
                    "external CA options.")

            if self.external_ca_type and not self.external_ca:
                raise RuntimeError(
                    "You cannot specify --external-ca-type without "
                    "--external-ca")

            if self.uninstalling:
                if (self.realm_name or self.admin_password
                        or self.master_password):
                    raise RuntimeError(
                        "In uninstall mode, -a, -r and -P options are not "
                        "allowed")
            elif not self.interactive:
                if (not self.realm_name or not self.dm_password
                        or not self.admin_password):
                    raise RuntimeError(
                        "In unattended mode you need to provide at least -r, "
                        "-p and -a options")
                if self.setup_dns:
                    if (not self.forwarders and not self.no_forwarders
                            and not self.auto_forwarders):
                        raise RuntimeError(
                            "You must specify at least one of --forwarder, "
                            "--auto-forwarders, or --no-forwarders options")

            any_ignore_option_true = any(
                [self.ignore_topology_disconnect, self.ignore_last_of_role])
            if any_ignore_option_true and not self.uninstalling:
                raise RuntimeError(
                    "'--ignore-topology-disconnect/--ignore-last-of-role' "
                    "options can be used only during uninstallation")

            if self.idmax < self.idstart:
                raise RuntimeError(
                    "idmax (%s) cannot be smaller than idstart (%s)" %
                    (self.idmax, self.idstart))
        else:
            cert_file_req = (self.dirsrv_cert_files, self.http_cert_files)
            cert_file_opt = (self.pkinit_cert_files, )

            if self.replica_file is None:
                # If any of the PKCS#12 options are selected, all are required.
                if any(cert_file_req +
                       cert_file_opt) and not all(cert_file_req):
                    raise RuntimeError(
                        "--dirsrv-cert-file and --http-cert-file are required "
                        "if any PKCS#12 options are used")

                if self.servers and not self.domain_name:
                    raise RuntimeError(
                        "The --server option cannot be used without providing "
                        "domain via the --domain option")

            else:
                if not ipautil.file_exists(self.replica_file):
                    raise RuntimeError("Replica file %s does not exist" %
                                       self.replica_file)

                if any(cert_file_req + cert_file_opt):
                    raise RuntimeError(
                        "You cannot specify any of --dirsrv-cert-file, "
                        "--http-cert-file, or --pkinit-cert-file together "
                        "with replica file")

                CLIKnob = collections.namedtuple('CLIKnob', ('value', 'name'))

                conflicting_knobs = (
                    CLIKnob(self.realm_name, '--realm'),
                    CLIKnob(self.domain_name, '--domain'),
                    CLIKnob(self.host_name, '--hostname'),
                    CLIKnob(self.servers, '--server'),
                    CLIKnob(self.principal, '--principal'),
                )

                if any([k.value is not None for k in conflicting_knobs]):
                    conflicting_knob_names = [
                        knob.name for knob in conflicting_knobs
                        if knob.value is not None
                    ]

                    raise RuntimeError(
                        "You cannot specify '{0}' option(s) with replica file."
                        .format(", ".join(conflicting_knob_names)))

            if self.setup_dns:
                if (not self.forwarders and not self.no_forwarders
                        and not self.auto_forwarders):
                    raise RuntimeError(
                        "You must specify at least one of --forwarder, "
                        "--auto-forwarders, or --no-forwarders options")

        # Automatically enable pkinit w/ dogtag
        self.no_pkinit = not self.setup_ca
Beispiel #3
0
class CAInstallInterface(dogtag.DogtagInstallInterface,
                         conncheck.ConnCheckInterface):
    """
    Interface of the CA installer

    Knobs defined here will be available in:
    * ipa-server-install
    * ipa-replica-prepare
    * ipa-replica-install
    * ipa-ca-install
    """
    description = "Certificate system"

    principal = conncheck.ConnCheckInterface.principal
    principal = extend_knob(
        principal,
        description="User allowed to manage replicas",
        cli_names=list(principal.cli_names) + ['-P'],
    )
    principal = enroll_only(principal)
    principal = replica_install_only(principal)

    admin_password = conncheck.ConnCheckInterface.admin_password
    admin_password = extend_knob(
        admin_password,
        description="Admin user Kerberos password used for connection check",
        cli_names=list(admin_password.cli_names) + ['-w'],
    )
    admin_password = enroll_only(admin_password)

    external_ca = knob(
        None,
        description=("Generate a CSR for the IPA CA certificate to be signed "
                     "by an external CA"),
    )
    external_ca = master_install_only(external_ca)

    external_ca_type = knob(
        cainstance.ExternalCAType,
        None,
        description="Type of the external CA",
    )
    external_ca_type = master_install_only(external_ca_type)

    external_ca_profile = knob(
        type=cainstance.ExternalCAProfile,
        default=None,
        description=("Specify the certificate profile/template to use at the "
                     "external CA"),
    )
    external_ca_profile = master_install_only(external_ca_profile)

    external_cert_files = knob(
        # pylint: disable=invalid-sequence-index
        typing.List[str],
        None,
        description=("File containing the IPA CA certificate and the external "
                     "CA certificate chain"),
        cli_names='--external-cert-file',
        cli_deprecated_names=['--external_cert_file', '--external_ca_file'],
        cli_metavar='FILE',
    )
    external_cert_files = master_install_only(external_cert_files)

    @external_cert_files.validator
    def external_cert_files(self, value):
        if any(not os.path.isabs(path) for path in value):
            raise ValueError("must use an absolute path")

    subject_base = knob(
        str,
        None,
        description=("The certificate subject base (default O=<realm-name>). "
                     "RDNs are in LDAP order (most specific RDN first)."),
        cli_deprecated_names=['--subject'],
    )
    subject_base = master_install_only(subject_base)

    @subject_base.validator
    def subject_base(self, value):
        subject_validator(VALID_SUBJECT_BASE_ATTRS, value)

    ca_subject = knob(
        str,
        None,
        description=("The CA certificate subject DN "
                     "(default CN=Certificate Authority,O=<realm-name>). "
                     "RDNs are in LDAP order (most specific RDN first)."),
    )
    ca_subject = master_install_only(ca_subject)

    @ca_subject.validator
    def ca_subject(self, value):
        subject_validator(VALID_SUBJECT_ATTRS, value)

    ca_signing_algorithm = knob(
        CASigningAlgorithm,
        None,
        description="Signing algorithm of the IPA CA certificate",
    )
    ca_signing_algorithm = master_install_only(ca_signing_algorithm)

    skip_schema_check = knob(
        None,
        description="skip check for updated CA DS schema on the remote master",
    )
    skip_schema_check = enroll_only(skip_schema_check)
    skip_schema_check = replica_install_only(skip_schema_check)
Beispiel #4
0
class ServiceInstallInterface(common.Installable,
                              common.Interactive,
                              core.Composite):
    """
    Interface common to all service installers
    """
    description = "Basic"

    domain_name = knob(
        str, None,
        description="primary DNS domain of the IPA deployment "
                    "(not necessarily related to the current hostname)",
        cli_names='--domain',
    )

    @domain_name.validator
    def domain_name(self, value):
        validate_domain_name(value)

    servers = knob(
        # pylint: disable=invalid-sequence-index
        typing.List[str], None,
        description="FQDN of IPA server",
        cli_names='--server',
        cli_metavar='SERVER',
    )

    realm_name = knob(
        str, None,
        description="Kerberos realm name of the IPA deployment (typically "
                    "an upper-cased name of the primary DNS domain)",
        cli_names='--realm',
    )

    @realm_name.validator
    def realm_name(self, value):
        validate_domain_name(value, entity="realm")

    host_name = knob(
        str, None,
        description="The hostname of this machine (FQDN). If specified, the "
                    "hostname will be set and the system configuration will "
                    "be updated to persist over reboot. By default the result "
                    "of getfqdn() call from Python's socket module is used.",
        cli_names='--hostname',
    )

    ca_cert_files = knob(
        # pylint: disable=invalid-sequence-index
        typing.List[str], None,
        description="load the CA certificate from this file",
        cli_names='--ca-cert-file',
        cli_metavar='FILE',
    )

    replica_file = knob(
        str, None,
        description="a file generated by ipa-replica-prepare",
        deprecated=True
    )
    replica_file = replica_install_only(replica_file)

    dm_password = knob(
        str, None,
        sensitive=True,
        description="Directory Manager password (for the existing master)",
    )
Beispiel #5
0
class ServerCertificateInstallInterface(service.ServiceInstallInterface):
    description = "SSL certificate"

    dirsrv_cert_files = knob(
        # pylint: disable=invalid-sequence-index
        typing.List[str],
        None,
        description=("File containing the Directory Server SSL certificate "
                     "and private key"),
        cli_names='--dirsrv-cert-file',
        cli_deprecated_names='--dirsrv_pkcs12',
        cli_metavar='FILE',
    )
    dirsrv_cert_files = prepare_only(dirsrv_cert_files)

    http_cert_files = knob(
        # pylint: disable=invalid-sequence-index
        typing.List[str],
        None,
        description=("File containing the Apache Server SSL certificate and "
                     "private key"),
        cli_names='--http-cert-file',
        cli_deprecated_names='--http_pkcs12',
        cli_metavar='FILE',
    )
    http_cert_files = prepare_only(http_cert_files)

    pkinit_cert_files = knob(
        # pylint: disable=invalid-sequence-index
        typing.List[str],
        None,
        description=("File containing the Kerberos KDC SSL certificate and "
                     "private key"),
        cli_names='--pkinit-cert-file',
        cli_deprecated_names='--pkinit_pkcs12',
        cli_metavar='FILE',
    )
    pkinit_cert_files = prepare_only(pkinit_cert_files)

    dirsrv_pin = knob(
        str,
        None,
        sensitive=True,
        description="The password to unlock the Directory Server private key",
        cli_deprecated_names='--dirsrv_pin',
        cli_metavar='PIN',
    )
    dirsrv_pin = prepare_only(dirsrv_pin)

    http_pin = knob(
        str,
        None,
        sensitive=True,
        description="The password to unlock the Apache Server private key",
        cli_deprecated_names='--http_pin',
        cli_metavar='PIN',
    )
    http_pin = prepare_only(http_pin)

    pkinit_pin = knob(
        str,
        None,
        sensitive=True,
        description="The password to unlock the Kerberos KDC private key",
        cli_deprecated_names='--pkinit_pin',
        cli_metavar='PIN',
    )
    pkinit_pin = prepare_only(pkinit_pin)

    dirsrv_cert_name = knob(
        str,
        None,
        description="Name of the Directory Server SSL certificate to install",
        cli_metavar='NAME',
    )
    dirsrv_cert_name = prepare_only(dirsrv_cert_name)

    http_cert_name = knob(
        str,
        None,
        description="Name of the Apache Server SSL certificate to install",
        cli_metavar='NAME',
    )
    http_cert_name = prepare_only(http_cert_name)

    pkinit_cert_name = knob(
        str,
        None,
        description="Name of the Kerberos KDC SSL certificate to install",
        cli_metavar='NAME',
    )
    pkinit_cert_name = prepare_only(pkinit_cert_name)
Beispiel #6
0
class ServerInstallInterface(
        ServerCertificateInstallInterface, client.ClientInstallInterface,
        ca.CAInstallInterface, kra.KRAInstallInterface,
        dns.DNSInstallInterface, adtrust.ADTrustInstallInterface,
        conncheck.ConnCheckInterface, ServerUninstallInterface):
    """
    Interface of server installers

    Knobs defined here will be available in:
    * ipa-server-install
    * ipa-replica-prepare
    * ipa-replica-install
    """
    description = "Server"

    kinit_attempts = 1
    fixed_primary = True
    permit = False
    enable_dns_updates = False
    no_krb5_offline_passwords = False
    preserve_sssd = False
    no_sssd = False

    domain_name = client.ClientInstallInterface.domain_name
    domain_name = extend_knob(
        domain_name,
        # pylint: disable=no-member
        cli_names=list(domain_name.cli_names) + ['-n'],
    )

    servers = extend_knob(
        client.ClientInstallInterface.servers,
        description="fully qualified name of IPA server to enroll to",
    )
    servers = enroll_only(servers)

    realm_name = client.ClientInstallInterface.realm_name
    realm_name = extend_knob(
        realm_name,
        cli_names=list(realm_name.cli_names) + ['-r'],
    )

    host_name = extend_knob(
        client.ClientInstallInterface.host_name,
        description="fully qualified name of this host",
    )

    ca_cert_files = extend_knob(
        client.ClientInstallInterface.ca_cert_files,
        description="File containing CA certificates for the service "
        "certificate files",
        cli_deprecated_names='--root-ca-file',
    )
    ca_cert_files = prepare_only(ca_cert_files)

    dm_password = extend_knob(
        client.ClientInstallInterface.dm_password,
        description="Directory Manager password",
    )

    ip_addresses = extend_knob(
        client.ClientInstallInterface.ip_addresses,
        description="Server IP Address. This option can be used multiple "
        "times",
    )

    principal = client.ClientInstallInterface.principal
    principal = extend_knob(
        principal,
        description="User Principal allowed to promote replicas and join IPA "
        "realm",
        cli_names=list(principal.cli_names) + ['-P'],
    )
    principal = replica_install_only(principal)

    admin_password = extend_knob(
        client.ClientInstallInterface.admin_password, )

    master_password = knob(
        str,
        None,
        sensitive=True,
        deprecated=True,
        description="kerberos master password (normally autogenerated)",
    )
    master_password = master_install_only(master_password)

    hidden_replica = knob(
        None,
        cli_names='--hidden-replica',
        description="Install a hidden replica",
    )
    hidden_replica = replica_install_only(hidden_replica)

    domain_level = knob(
        int,
        constants.MAX_DOMAIN_LEVEL,
        description="IPA domain level",
        deprecated=True,
    )
    domain_level = master_install_only(domain_level)

    @domain_level.validator
    def domain_level(self, value):
        # Check that Domain Level is within the allowed range
        if value < constants.MIN_DOMAIN_LEVEL:
            raise ValueError("Domain Level cannot be lower than {0}".format(
                constants.MIN_DOMAIN_LEVEL))
        elif value > constants.MAX_DOMAIN_LEVEL:
            raise ValueError("Domain Level cannot be higher than {0}".format(
                constants.MAX_DOMAIN_LEVEL))

    setup_adtrust = knob(None, description="configure AD trust capability")
    setup_ca = knob(
        None,
        description="configure a dogtag CA",
    )
    setup_ca = enroll_only(setup_ca)

    setup_kra = knob(
        None,
        description="configure a dogtag KRA",
    )
    setup_kra = enroll_only(setup_kra)

    setup_dns = knob(
        None,
        description="configure bind with our zone",
    )
    setup_dns = enroll_only(setup_dns)

    idstart = knob(
        int,
        random.randint(1, 10000) * 200000,
        description="The starting value for the IDs range (default random)",
    )
    idstart = master_install_only(idstart)

    idmax = knob(
        int,
        description=("The max value for the IDs range (default: "
                     "idstart+199999)"),
    )
    idmax = master_install_only(idmax)

    @idmax.default_getter
    def idmax(self):
        return self.idstart + 200000 - 1

    no_hbac_allow = knob(
        None,
        description="Don't install allow_all HBAC rule",
        cli_deprecated_names='--no_hbac_allow',
    )
    no_hbac_allow = master_install_only(no_hbac_allow)

    no_pkinit = knob(
        None,
        description="disables pkinit setup steps",
    )
    no_pkinit = prepare_only(no_pkinit)

    no_ui_redirect = knob(
        None,
        description="Do not automatically redirect to the Web UI",
    )
    no_ui_redirect = enroll_only(no_ui_redirect)

    dirsrv_config_file = knob(
        str,
        None,
        description="The path to LDIF file that will be used to modify "
        "configuration of dse.ldif during installation of the "
        "directory server instance",
        cli_metavar='FILE',
    )
    dirsrv_config_file = enroll_only(dirsrv_config_file)

    @dirsrv_config_file.validator
    def dirsrv_config_file(self, value):
        if not os.path.exists(value):
            raise ValueError("File %s does not exist." % value)

    def __init__(self, **kwargs):
        super(ServerInstallInterface, self).__init__(**kwargs)

        # If any of the key file options are selected, all are required.
        cert_file_req = (self.dirsrv_cert_files, self.http_cert_files)
        cert_file_opt = (self.pkinit_cert_files, )
        if not self.no_pkinit:
            cert_file_req += cert_file_opt
        if self.no_pkinit and self.pkinit_cert_files:
            raise RuntimeError(
                "--no-pkinit and --pkinit-cert-file cannot be specified "
                "together")
        if any(cert_file_req + cert_file_opt) and not all(cert_file_req):
            raise RuntimeError(
                "--dirsrv-cert-file, --http-cert-file, and --pkinit-cert-file "
                "or --no-pkinit are required if any key file options are used."
            )

        if not self.interactive:
            if self.dirsrv_cert_files and self.dirsrv_pin is None:
                raise RuntimeError(
                    "You must specify --dirsrv-pin with --dirsrv-cert-file")
            if self.http_cert_files and self.http_pin is None:
                raise RuntimeError(
                    "You must specify --http-pin with --http-cert-file")
            if self.pkinit_cert_files and self.pkinit_pin is None:
                raise RuntimeError(
                    "You must specify --pkinit-pin with --pkinit-cert-file")

        if not self.setup_dns:
            if self.forwarders:
                raise RuntimeError(
                    "You cannot specify a --forwarder option without the "
                    "--setup-dns option")
            if self.auto_forwarders:
                raise RuntimeError(
                    "You cannot specify a --auto-forwarders option without "
                    "the --setup-dns option")
            if self.no_forwarders:
                raise RuntimeError(
                    "You cannot specify a --no-forwarders option without the "
                    "--setup-dns option")
            if self.forward_policy:
                raise RuntimeError(
                    "You cannot specify a --forward-policy option without the "
                    "--setup-dns option")
            if self.reverse_zones:
                raise RuntimeError(
                    "You cannot specify a --reverse-zone option without the "
                    "--setup-dns option")
            if self.auto_reverse:
                raise RuntimeError(
                    "You cannot specify a --auto-reverse option without the "
                    "--setup-dns option")
            if self.no_reverse:
                raise RuntimeError(
                    "You cannot specify a --no-reverse option without the "
                    "--setup-dns option")
            if self.no_dnssec_validation:
                raise RuntimeError(
                    "You cannot specify a --no-dnssec-validation option "
                    "without the --setup-dns option")
        elif self.forwarders and self.no_forwarders:
            raise RuntimeError(
                "You cannot specify a --forwarder option together with "
                "--no-forwarders")
        elif self.auto_forwarders and self.no_forwarders:
            raise RuntimeError(
                "You cannot specify a --auto-forwarders option together with "
                "--no-forwarders")
        elif self.reverse_zones and self.no_reverse:
            raise RuntimeError(
                "You cannot specify a --reverse-zone option together with "
                "--no-reverse")
        elif self.auto_reverse and self.no_reverse:
            raise RuntimeError(
                "You cannot specify a --auto-reverse option together with "
                "--no-reverse")

        if not self.setup_adtrust:
            if self.add_agents:
                raise RuntimeError(
                    "You cannot specify an --add-agents option without the "
                    "--setup-adtrust option")

            if self.enable_compat:
                raise RuntimeError(
                    "You cannot specify an --enable-compat option without the "
                    "--setup-adtrust option")

            if self.netbios_name:
                raise RuntimeError(
                    "You cannot specify a --netbios-name option without the "
                    "--setup-adtrust option")

            if self.no_msdcs:
                raise RuntimeError(
                    "You cannot specify a --no-msdcs option without the "
                    "--setup-adtrust option")

        if not hasattr(self, 'replica_install'):
            if self.external_cert_files and self.dirsrv_cert_files:
                raise RuntimeError(
                    "Service certificate file options cannot be used with the "
                    "external CA options.")

            if self.external_ca_type and not self.external_ca:
                raise RuntimeError(
                    "You cannot specify --external-ca-type without "
                    "--external-ca")

            if self.external_ca_profile and not self.external_ca:
                raise RuntimeError(
                    "You cannot specify --external-ca-profile without "
                    "--external-ca")

            if self.uninstalling:  # pylint: disable=using-constant-test
                if (self.realm_name or self.admin_password
                        or self.master_password):
                    raise RuntimeError(
                        "In uninstall mode, -a, -r and -P options are not "
                        "allowed")
            elif not self.interactive:
                if (not self.realm_name or not self.dm_password
                        or not self.admin_password):
                    raise RuntimeError(
                        "In unattended mode you need to provide at least -r, "
                        "-p and -a options")
                if self.setup_dns:
                    if (not self.forwarders and not self.no_forwarders
                            and not self.auto_forwarders):
                        raise RuntimeError(
                            "You must specify at least one of --forwarder, "
                            "--auto-forwarders, or --no-forwarders options")

            any_ignore_option_true = any(
                [self.ignore_topology_disconnect, self.ignore_last_of_role])
            if any_ignore_option_true and not self.uninstalling:
                raise RuntimeError(
                    "'--ignore-topology-disconnect/--ignore-last-of-role' "
                    "options can be used only during uninstallation")

            if self.idmax < self.idstart:
                raise RuntimeError(
                    "idmax (%s) cannot be smaller than idstart (%s)" %
                    (self.idmax, self.idstart))
        else:
            # replica installers
            if self.servers and not self.domain_name:
                raise RuntimeError(
                    "The --server option cannot be used without providing "
                    "domain via the --domain option")

            if self.setup_dns:
                if (not self.forwarders and not self.no_forwarders
                        and not self.auto_forwarders):
                    raise RuntimeError(
                        "You must specify at least one of --forwarder, "
                        "--auto-forwarders, or --no-forwarders options")
Beispiel #7
0
class CAInstallInterface(dogtag.DogtagInstallInterface,
                         conncheck.ConnCheckInterface):
    """
    Interface of the CA installer

    Knobs defined here will be available in:
    * ipa-server-install
    * ipa-replica-prepare
    * ipa-replica-install
    * ipa-ca-install
    """

    principal = knob(
        bases=conncheck.ConnCheckInterface.principal,
        description="User allowed to manage replicas",
        cli_names=(list(conncheck.ConnCheckInterface.principal.cli_names) +
                   ['-P']),
    )
    principal = enroll_only(principal)
    principal = replica_install_only(principal)

    admin_password = knob(
        bases=conncheck.ConnCheckInterface.admin_password,
        description="Admin user Kerberos password used for connection check",
        cli_names=(
            list(conncheck.ConnCheckInterface.admin_password.cli_names) +
            ['-w']),
    )
    admin_password = enroll_only(admin_password)

    external_ca = knob(
        None,
        description=("Generate a CSR for the IPA CA certificate to be signed "
                     "by an external CA"),
    )
    external_ca = master_install_only(external_ca)

    external_ca_type = knob(
        ExternalCAType,
        None,
        description="Type of the external CA",
    )
    external_ca_type = master_install_only(external_ca_type)

    external_cert_files = knob(
        # pylint: disable=invalid-sequence-index
        typing.List[str],
        None,
        description=("File containing the IPA CA certificate and the external "
                     "CA certificate chain"),
        cli_names='--external-cert-file',
        cli_deprecated_names=['--external_cert_file', '--external_ca_file'],
        cli_metavar='FILE',
    )
    external_cert_files = master_install_only(external_cert_files)

    @external_cert_files.validator
    def external_cert_files(self, value):
        if any(not os.path.isabs(path) for path in value):
            raise ValueError("must use an absolute path")

    subject = knob(
        str,
        None,
        description="The certificate subject base (default O=<realm-name>)",
    )
    subject = master_install_only(subject)

    @subject.validator
    def subject(self, value):
        v = unicode(value, 'utf-8')
        if any(ord(c) < 0x20 for c in v):
            raise ValueError("must not contain control characters")
        if '&' in v:
            raise ValueError("must not contain an ampersand (\"&\")")
        try:
            dn = DN(v)
            for rdn in dn:
                if rdn.attr.lower() not in VALID_SUBJECT_ATTRS:
                    raise ValueError("invalid attribute: \"%s\"" % rdn.attr)
        except ValueError as e:
            raise ValueError("invalid subject base format: %s" % e)

    ca_signing_algorithm = knob(
        CASigningAlgorithm,
        None,
        description="Signing algorithm of the IPA CA certificate",
    )
    ca_signing_algorithm = master_install_only(ca_signing_algorithm)

    skip_schema_check = knob(
        None,
        description="skip check for updated CA DS schema on the remote master",
    )
    skip_schema_check = enroll_only(skip_schema_check)
    skip_schema_check = replica_install_only(skip_schema_check)
Beispiel #8
0
class CompatServerReplicaInstall(ServerReplicaInstall):
    ca_cert_files = None
    all_ip_addresses = False
    no_wait_for_dns = True
    nisdomain = None
    no_nisdomain = False
    no_sudo = False
    request_cert = False
    ca_file = None
    zonemgr = None
    replica_install = True  # Used in ServerInstallInterface.__init__

    auto_password = knob(
        str,
        None,
        description="Password to join the IPA realm. Assumes bulk password "
        "unless principal is also set. (domain level 1+) "
        "Directory Manager (existing master) password. (domain "
        "level 0)",
        sensitive=True,
        cli_names=['--password', '-p'],
        cli_metavar='PASSWORD',
    )

    @property
    def dm_password(self):
        try:
            return self.__dm_password
        except AttributeError:
            pass

        return super(CompatServerReplicaInstall, self).dm_password

    @dm_password.setter
    def dm_password(self, value):
        self.__dm_password = value

    ip_addresses = extend_knob(
        ServerReplicaInstall.ip_addresses,
        description="Replica server IP Address. This option can be used "
        "multiple times",
    )

    admin_password = ServerReplicaInstall.admin_password
    admin_password = extend_knob(
        admin_password,
        cli_names=list(admin_password.cli_names) + ['-w'],
    )

    @admin_password.default_getter
    def admin_password(self):
        if self.principal:
            return self.auto_password

        return super(CompatServerReplicaInstall, self).admin_password

    @property
    def host_password(self):
        admin_password = (super(CompatServerReplicaInstall,
                                self).admin_password)
        if not self.principal or admin_password:
            return self.auto_password

        return super(CompatServerReplicaInstall, self).host_password