Ejemplo n.º 1
0
    def __get_connection(self):
        """Make a connection to IPA or raise an error."""
        tries = 0

        while (tries <= self.ntries) or (self.backoff > 0):
            if self.backoff == 0:
                LOG.debug("Attempt %d of %d", tries, self.ntries)
            if api.Backend.rpcclient.isconnected():
                api.Backend.rpcclient.disconnect()
            try:
                api.Backend.rpcclient.connect()
                # ping to force an actual connection in case there is only one
                # IPA master
                api.Command[u'ping']()
            except (errors.CCacheError,
                    errors.TicketExpired,
                    errors.KerberosError) as e:
                LOG.debug("kinit again: %s", e)
                # pylint: disable=no-member
                try:
                    kinit_keytab(str('nova/%s@%s' %
                                 (api.env.host, api.env.realm)),
                                 self.keytab,
                                 self.ccache)
                except GSSError as e:
                    LOG.debug("kinit failed: %s", e)
                if tries > 0 and self.backoff:
                    self.__backoff()
                tries += 1
            except errors.NetworkError:
                tries += 1
                if self.backoff:
                    self.__backoff()
            else:
                return
Ejemplo n.º 2
0
    def kinit(self, user, realm, password, ccache_name):
        # get http service ccache as an armor for FAST to enable OTP authentication
        armor_principal = str(krb5_format_service_principal_name(
            'HTTP', self.api.env.host, realm))
        keytab = paths.IPA_KEYTAB
        armor_name = "%sA_%s" % (krbccache_prefix, user)
        armor_path = os.path.join(krbccache_dir, armor_name)

        self.debug('Obtaining armor ccache: principal=%s keytab=%s ccache=%s',
                   armor_principal, keytab, armor_path)

        try:
            ipautil.kinit_keytab(armor_principal, paths.IPA_KEYTAB, armor_path)
        except gssapi.exceptions.GSSError as e:
            raise CCacheError(str(e))

        # Format the user as a kerberos principal
        principal = krb5_format_principal_name(user, realm)

        try:
            ipautil.kinit_password(principal, password, ccache_name,
                                   armor_ccache_name=armor_path)

            self.debug('Cleanup the armor ccache')
            ipautil.run(
                [paths.KDESTROY, '-A', '-c', armor_path],
                env={'KRB5CCNAME': armor_path},
                raiseonerr=False)
        except RuntimeError as e:
            if ('kinit: Cannot read password while '
                    'getting initial credentials') in str(e):
                raise PasswordExpired(principal=principal, message=unicode(e))
            raise InvalidSessionPassword(principal=principal,
                                         message=unicode(e))
Ejemplo n.º 3
0
    def run(self):
        fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
        if (not fstore.has_files() and
            not os.path.exists(paths.IPA_DEFAULT_CONF)):
            raise admintool.ScriptError(
                "IPA client is not configured on this system.")

        api.bootstrap(context='cli_installer')
        api.finalize()

        server = urlsplit(api.env.jsonrpc_uri).hostname
        ldap = ipaldap.IPAdmin(server)

        tmpdir = tempfile.mkdtemp(prefix="tmp-")
        ccache_name = os.path.join(tmpdir, 'ccache')
        try:
            principal = str('host/%s@%s' % (api.env.host, api.env.realm))
            ipautil.kinit_keytab(principal, paths.KRB5_KEYTAB, ccache_name)
            os.environ['KRB5CCNAME'] = ccache_name

            api.Backend.rpcclient.connect()
            try:
                result = api.Backend.rpcclient.forward(
                    'ca_is_enabled',
                    version=u'2.107',
                )
                ca_enabled = result['result']
            except (errors.CommandError, errors.NetworkError):
                result = api.Backend.rpcclient.forward(
                    'env',
                    server=True,
                    version=u'2.0',
                )
                ca_enabled = result['result']['enable_ra']

            ldap.do_sasl_gssapi_bind()

            certs = certstore.get_ca_certs(ldap, api.env.basedn,
                                           api.env.realm, ca_enabled)

            # find lightweight CAs (on renewal master only)
            lwcas = []
            for ca_obj in api.Command.ca_find()['result']:
                if IPA_CA_CN not in ca_obj['cn']:
                    lwcas.append(ca_obj)

            api.Backend.rpcclient.disconnect()
        finally:
            shutil.rmtree(tmpdir)

        server_fstore = sysrestore.FileStore(paths.SYSRESTORE)
        if server_fstore.has_files():
            self.update_server(certs)
            for entry in lwcas:
                self.server_track_lightweight_ca(entry)

        self.update_client(certs)
Ejemplo n.º 4
0
def change_principal(principal,
                     password=None,
                     client=None,
                     path=None,
                     canonicalize=False,
                     enterprise=False,
                     keytab=None):
    """Temporarily change the kerberos principal

    Most of the test cases run with the admin ipa user which is granted
    all access and exceptions from rules on some occasions.

    When the test needs to test for an application of some kind
    of a restriction it needs to authenticate as a different principal
    with required set of rights to the operation.

    The context manager changes the principal identity in two ways:

    * using password
    * using keytab

    If the context manager is to be used with a keytab, the keytab
    option must be its absolute path.

    The context manager can be used to authenticate with enterprise
    principals and aliases when given respective options.
    """

    if path:
        ccache_name = path
    else:
        ccache_name = os.path.join('/tmp', str(uuid.uuid4()))

    if client is None:
        client = api

    client.Backend.rpcclient.disconnect()

    try:
        with private_ccache(ccache_name):
            if keytab:
                kinit_keytab(principal, keytab, ccache_name)
            else:
                kinit_password(principal,
                               password,
                               ccache_name,
                               canonicalize=canonicalize,
                               enterprise=enterprise)
            client.Backend.rpcclient.connect()

            try:
                yield
            finally:
                client.Backend.rpcclient.disconnect()
    finally:
        client.Backend.rpcclient.connect()
Ejemplo n.º 5
0
def change_principal(principal, password=None, client=None, path=None,
                     canonicalize=False, enterprise=False, keytab=None):
    """Temporarily change the kerberos principal

    Most of the test cases run with the admin ipa user which is granted
    all access and exceptions from rules on some occasions.

    When the test needs to test for an application of some kind
    of a restriction it needs to authenticate as a different principal
    with required set of rights to the operation.

    The context manager changes the principal identity in two ways:

    * using password
    * using keytab

    If the context manager is to be used with a keytab, the keytab
    option must be its absolute path.

    The context manager can be used to authenticate with enterprise
    principals and aliases when given respective options.
    """

    if path:
        ccache_name = path
    else:
        ccache_name = os.path.join('/tmp', str(uuid.uuid4()))

    if client is None:
        client = api


    client.Backend.rpcclient.disconnect()

    try:
        with private_ccache(ccache_name):
            if keytab:
                kinit_keytab(principal, keytab, ccache_name)
            else:
                kinit_password(principal, password, ccache_name,
                               canonicalize=canonicalize,
                               enterprise=enterprise)
            client.Backend.rpcclient.connect()

            try:
                yield
            finally:
                client.Backend.rpcclient.disconnect()
    finally:
        client.Backend.rpcclient.connect()
Ejemplo n.º 6
0
    def run(self):
        fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
        if (not fstore.has_files() and
            not os.path.exists(paths.IPA_DEFAULT_CONF)):
            raise admintool.ScriptError(
                "IPA client is not configured on this system.")

        api.bootstrap(context='cli_installer')
        api.finalize()

        server = urlparse.urlsplit(api.env.jsonrpc_uri).hostname
        ldap = ipaldap.IPAdmin(server)

        tmpdir = tempfile.mkdtemp(prefix="tmp-")
        ccache_name = os.path.join(tmpdir, 'ccache')
        try:
            principal = str('host/%s@%s' % (api.env.host, api.env.realm))
            ipautil.kinit_keytab(principal, paths.KRB5_KEYTAB, ccache_name)
            os.environ['KRB5CCNAME'] = ccache_name

            api.Backend.rpcclient.connect()
            try:
                result = api.Backend.rpcclient.forward(
                    'ca_is_enabled',
                    version=u'2.107',
                )
                ca_enabled = result['result']
            except (errors.CommandError, errors.NetworkError):
                result = api.Backend.rpcclient.forward(
                    'env',
                    server=True,
                    version=u'2.0',
                )
                ca_enabled = result['result']['enable_ra']
            api.Backend.rpcclient.disconnect()

            ldap.do_sasl_gssapi_bind()

            certs = certstore.get_ca_certs(ldap, api.env.basedn,
                                           api.env.realm, ca_enabled)
        finally:
            shutil.rmtree(tmpdir)

        server_fstore = sysrestore.FileStore(paths.SYSRESTORE)
        if server_fstore.has_files():
            self.update_server(certs)

        self.update_client(certs)
Ejemplo n.º 7
0
    def __get_connection(self):
        """Make a connection to IPA or raise an error."""
        tries = 0

        while tries <= self.ntries:
            try:
                api.Backend.rpcclient.connect()
            except (errors.CCacheError, errors.TicketExpired) as e:
                LOG.debug("kinit again: %s", e)
                # pylint: disable=no-member
                kinit_keytab(str('nova/%s@%s' %
                             (api.env.host, api.env.realm)),
                             CONF.keytab,
                             self.ccache)
                tries += 1
            else:
                return
Ejemplo n.º 8
0
    def kinit(self, user, realm, password, ccache_name):
        # get http service ccache as an armor for FAST to enable OTP authentication
        armor_principal = str(
            krb5_format_service_principal_name('HTTP', self.api.env.host,
                                               realm))
        keytab = paths.IPA_KEYTAB
        armor_name = "%sA_%s" % (krbccache_prefix, user)
        armor_path = os.path.join(krbccache_dir, armor_name)

        self.debug('Obtaining armor ccache: principal=%s keytab=%s ccache=%s',
                   armor_principal, keytab, armor_path)

        try:
            ipautil.kinit_keytab(armor_principal, paths.IPA_KEYTAB, armor_path)
        except gssapi.exceptions.GSSError as e:
            raise CCacheError(message=unicode(e))

        # Format the user as a kerberos principal
        principal = krb5_format_principal_name(user, realm)

        try:
            ipautil.kinit_password(principal,
                                   password,
                                   ccache_name,
                                   armor_ccache_name=armor_path)

            self.debug('Cleanup the armor ccache')
            ipautil.run([paths.KDESTROY, '-A', '-c', armor_path],
                        env={'KRB5CCNAME': armor_path},
                        raiseonerr=False)
        except RuntimeError as e:
            if ('kinit: Cannot read password while '
                    'getting initial credentials') in str(e):
                raise PasswordExpired(principal=principal, message=unicode(e))
            elif ('kinit: Client\'s entry in database'
                  ' has expired while getting initial credentials') in str(e):
                raise KrbPrincipalExpired(principal=principal,
                                          message=unicode(e))
            elif ('kinit: Clients credentials have been revoked '
                  'while getting initial credentials') in str(e):
                raise UserLocked(principal=principal, message=unicode(e))
            raise InvalidSessionPassword(principal=principal,
                                         message=unicode(e))
Ejemplo n.º 9
0
    def run(self):
        fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
        if (not fstore.has_files() and
            not os.path.exists(paths.IPA_DEFAULT_CONF)):
            raise admintool.ScriptError(
                "IPA client is not configured on this system.")

        api.bootstrap(context='cli_installer')
        api.finalize()

        server = urlsplit(api.env.jsonrpc_uri).hostname
        ldap_uri = ipaldap.get_ldap_uri(server)
        ldap = ipaldap.LDAPClient(ldap_uri)

        tmpdir = tempfile.mkdtemp(prefix="tmp-")
        ccache_name = os.path.join(tmpdir, 'ccache')
        try:
            principal = str('host/%s@%s' % (api.env.host, api.env.realm))
            ipautil.kinit_keytab(principal, paths.KRB5_KEYTAB, ccache_name)
            os.environ['KRB5CCNAME'] = ccache_name

            api.Backend.rpcclient.connect()
            try:
                result = api.Backend.rpcclient.forward(
                    'ca_is_enabled',
                    version=u'2.107',
                )
                ca_enabled = result['result']
            except (errors.CommandError, errors.NetworkError):
                result = api.Backend.rpcclient.forward(
                    'env',
                    server=True,
                    version=u'2.0',
                )
                ca_enabled = result['result']['enable_ra']

            ldap.gssapi_bind()

            certs = certstore.get_ca_certs(ldap, api.env.basedn,
                                           api.env.realm, ca_enabled)

            if ca_enabled:
                lwcas = api.Command.ca_find()['result']
            else:
                lwcas = []

            api.Backend.rpcclient.disconnect()
        finally:
            shutil.rmtree(tmpdir)

        server_fstore = sysrestore.FileStore(paths.SYSRESTORE)
        if server_fstore.has_files():
            self.update_server(certs)
            try:
                from ipaserver.install import cainstance
                cainstance.add_lightweight_ca_tracking_requests(
                    self.log, lwcas)
            except Exception:
                self.log.exception(
                    "Failed to add lightweight CA tracking requests")

        self.update_client(certs)