Exemplo n.º 1
0
class ServerMasterInstall(ServerMasterInstallInterface):
    """
    Server master installer
    """

    force_join = False
    servers = None
    no_wait_for_dns = True
    host_password = None
    keytab = None
    setup_ca = True

    domain_name = extend_knob(ServerMasterInstallInterface.domain_name, )

    @domain_name.validator
    def domain_name(self, value):
        # There might be an overlap but at this point we don't have
        # complete installer object to verify that DNS is hosted
        # by the same machine (i.e. we are already installed).
        # Later, DNS.install_check will do its zone overlap check
        # and will make sure to fail if overlap does really exist.
        # At this point we only verify that value is a valid DNS syntax.
        validate_domain_name(value)

    dm_password = extend_knob(ServerMasterInstallInterface.dm_password, )

    @dm_password.validator
    def dm_password(self, value):
        validate_dm_password(value)

    admin_password = extend_knob(
        ServerMasterInstallInterface.admin_password,
        description="admin user kerberos password",
    )

    @admin_password.validator
    def admin_password(self, value):
        validate_admin_password(value)

    # always run sidgen task and do not allow adding agents on first master
    add_sids = True
    add_agents = False

    def __init__(self, **kwargs):
        super(ServerMasterInstall, self).__init__(**kwargs)
        master_init(self)

    @step()
    def main(self):
        master_install_check(self)
        yield
        master_install(self)

    @main.uninstaller
    def main(self):
        uninstall_check(self)
        yield
        uninstall(self)
Exemplo n.º 2
0
class ServerMasterInstall(ServerMasterInstallInterface):
    """
    Server master installer
    """

    force_join = False
    servers = None
    no_wait_for_dns = True
    host_password = None
    keytab = None
    setup_ca = True

    domain_name = extend_knob(ServerMasterInstallInterface.domain_name, )

    @domain_name.validator
    def domain_name(self, value):
        if (self.setup_dns and not self.allow_zone_overlap):
            print("Checking DNS domain %s, please wait ..." % value)
            check_zone_overlap(value, False)

    dm_password = extend_knob(ServerMasterInstallInterface.dm_password, )

    @dm_password.validator
    def dm_password(self, value):
        validate_dm_password(value)

    admin_password = extend_knob(
        ServerMasterInstallInterface.admin_password,
        description="admin user kerberos password",
    )

    @admin_password.validator
    def admin_password(self, value):
        validate_admin_password(value)

    # always run sidgen task and do not allow adding agents on first master
    add_sids = True
    add_agents = False

    def _is_promote(self):
        return self.domain_level > constants.DOMAIN_LEVEL_0

    def __init__(self, **kwargs):
        super(ServerMasterInstall, self).__init__(**kwargs)
        master_init(self)

    @step()
    def main(self):
        master_install_check(self)
        yield
        master_install(self)

    @main.uninstaller
    def main(self):
        uninstall_check(self)
        yield
        uninstall(self)
Exemplo n.º 3
0
class ServerReplicaInstall(ServerReplicaInstallInterface):
    """
    Server replica installer
    """

    subject_base = None
    ca_subject = None

    admin_password = extend_knob(
        ServerReplicaInstallInterface.admin_password,
        description="Kerberos password for the specified admin principal",
    )

    def _is_promote(self):
        return self.replica_file is None

    def __init__(self, **kwargs):
        super(ServerReplicaInstall, self).__init__(**kwargs)
        replica_init(self)

    @step()
    def main(self):
        if self.replica_file is None:
            replica_promote_check(self)
        else:
            replica_install_check(self)
        yield
        replica_install(self)
Exemplo n.º 4
0
class CompatServerMasterInstall(ServerMasterInstall):
    all_ip_addresses = False
    nisdomain = None
    no_nisdomain = False
    no_sudo = False
    request_cert = False

    dm_password = extend_knob(
        ServerMasterInstall.dm_password,
        cli_names=['--ds-password', '-p'],
    )

    admin_password = ServerMasterInstall.admin_password
    admin_password = extend_knob(
        admin_password,
        cli_names=list(admin_password.cli_names) + ['-a'],
    )

    ip_addresses = extend_knob(
        ServerMasterInstall.ip_addresses,
        description="Master Server IP Address. This option can be used "
        "multiple times",
    )
Exemplo n.º 5
0
class StandaloneClientInstall(client.ClientInstall):
    no_host_dns = False
    no_wait_for_dns = False

    principal = client.ClientInstall.principal
    principal = extend_knob(
        principal,
        cli_names=list(principal.cli_names) + ['-p'],
    )

    password = knob(
        str,
        None,
        sensitive=True,
        description="password to join the IPA realm (assumes bulk password "
        "unless principal is also set)",
        cli_names=[None, '-w'],
    )

    @property
    def admin_password(self):
        if self.principal:
            return self.password

        return super(StandaloneClientInstall, self).admin_password

    @property
    def host_password(self):
        if not self.principal:
            return self.password

        return super(StandaloneClientInstall, self).host_password

    prompt_password = knob(
        None,
        description="Prompt for a password to join the IPA realm",
        cli_names='-W',
    )

    on_master = knob(
        None,
        deprecated=True,
    )
Exemplo n.º 6
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,  # pylint: disable=no-member
        description="Replica server IP Address. This option can be used "
        "multiple times",
    )

    admin_password = (
        ServerReplicaInstall.admin_password  # pylint: disable=no-member
    )
    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
Exemplo n.º 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
    """
    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(x509.ExternalCAType,
                            None,
                            description="Type of the external CA")
    external_ca_type = master_install_only(external_ca_type)

    external_ca_profile = knob(
        type=x509.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(
        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)
Exemplo n.º 8
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)

    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 _is_promote(self):
        """
        :returns: True if domain level options correspond to domain level > 0
        """
        raise NotImplementedError()

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

        # pkinit is not supported on DL0, don't allow related options
        if not self._is_promote():
            if (self.no_pkinit or self.pkinit_cert_files is not None
                    or self.pkinit_pin is not None):
                raise RuntimeError(
                    "pkinit on domain level 0 is not supported. Please "
                    "don't use any pkinit-related options.")
            self.no_pkinit = True

        # 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_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.external_ca_profile and not self.external_ca:
                raise RuntimeError(
                    "You cannot specify --external-ca-profile 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:
            # replica installers
            if self.replica_file is None:
                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 os.path.isfile(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")