Пример #1
0
    def _fetch(self, client, ignore_cache=False):
        if not client.isconnected():
            client.connect(verbose=False)

        fps = []
        if not ignore_cache:
            try:
                fps = [fsdecode(f) for f in os.listdir(self._DIR)]
            except EnvironmentError:
                pass

        kwargs = {u'version': u'2.170'}
        if fps:
            kwargs[u'known_fingerprints'] = fps
        try:
            schema = client.forward(u'schema', **kwargs)['result']
        except errors.CommandError:
            raise NotAvailable()

        try:
            fp = schema['fingerprint']
            ttl = schema.pop('ttl')
            schema.pop('version')

            for key, value in schema.items():
                if key in self.namespaces:
                    value = {m['full_name']: m for m in value}
                self._dict[key] = value
        except KeyError as e:
            logger.warning("Failed to fetch schema: %s", e)
            raise NotAvailable()

        return (fp, ttl,)
Пример #2
0
    def _fetch(self, client, ignore_cache=False):
        if not client.isconnected():
            client.connect(verbose=False)

        fps = []
        if not ignore_cache:
            try:
                fps = [fsdecode(f) for f in os.listdir(self._DIR)]
            except EnvironmentError:
                pass

        kwargs = {u'version': u'2.170'}
        if fps:
            kwargs[u'known_fingerprints'] = fps
        try:
            schema = client.forward(u'schema', **kwargs)['result']
        except errors.CommandError:
            raise NotAvailable()

        try:
            fp = schema['fingerprint']
            ttl = schema.pop('ttl')
            schema.pop('version')

            for key, value in schema.items():
                if key in self.namespaces:
                    value = {m['full_name']: m for m in value}
                self._dict[key] = value
        except KeyError as e:
            logger.warning("Failed to fetch schema: %s", e)
            raise NotAvailable()

        return (fp, ttl,)
Пример #3
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
Пример #4
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)