Example #1
0
    def get_keytab(self, principal, retrieve):
        action = ('creating', 'retrieving')[retrieve]
        logger.debug(u'%s keytab for principal "%s"', action, principal)

        try:
            # NOTE: This is run from httpd with PrivateTmp=yes so the
            # temporary files are not accessible to other services running on
            # the same VM. This is in addition to the security of the
            # discretionary access controls being locked down (using
            # NamedTemporaryFile creates files that are only accessible by the
            # user).
            with tempfile.NamedTemporaryFile(suffix='.keytab') as temp_keytab:

                # Since this uses a temporary file and ipa-getkkeytab tool can
                # either create a new keytab file or add to an existing keytab
                # file. A valid keytab file needs to be constructed.
                temp_keytab.write(self.__empty_keytab)
                temp_keytab.flush()

                args = ['ipa-getkeytab',
                        '-p', principal,
                        '-k', temp_keytab.name]
                if retrieve:
                    args.append('-r')

                # The ipa-getkeytab utility enforces the authorization policy
                # for retrieving the keytab.
                p = subprocess.Popen(args,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE,
                                     close_fds=True,
                                     shell=False)
                # There is no stdout output from ipa-getkeytab
                (_, err) = p.communicate()
                p_status = p.wait()

                if p_status != 0:
                    logger.error(
                        u'ipa-getkeytab failed %s keytab for principal "%s" with error code %d and standard error '
                        u'message "%s"',
                        action, principal, p_status, err)
                    raise errors.InternalError()

                temp_keytab.seek(0)
                keytab = temp_keytab.read()

        except errors.InternalError:
            # The details were already logged
            raise
        except Exception as e:
            logger.error(u'failed %s keytab for principal "%s" with error "%s"', action, principal, e)
            raise

        logger.debug(u'%s keytab for principal "%s" succeeded', action, principal)

        return keytab
Example #2
0
    def execute(self, *args, **options):
        results = []
        for arg in args[0]:
            params = dict()
            name = None
            try:
                if 'method' not in arg:
                    raise errors.RequirementError(name='method')
                if 'params' not in arg:
                    raise errors.RequirementError(name='params')
                name = arg['method']
                if name not in self.Command:
                    raise errors.CommandError(name=name)
                a, kw = arg['params']
                newkw = dict((str(k), v) for k, v in kw.items())
                params = api.Command[name].args_options_2_params(*a, **newkw)
                newkw.setdefault('version', options['version'])

                result = api.Command[name](*a, **newkw)
                self.info(
                    '%s: batch: %s(%s): SUCCESS', context.principal, name, ', '.join(api.Command[name]._repr_iter(**params))
                )
                result['error']=None
            except Exception as e:
                if isinstance(e, errors.RequirementError) or \
                    isinstance(e, errors.CommandError):
                    self.info(
                        '%s: batch: %s',
                        context.principal,  # pylint: disable=no-member
                        e.__class__.__name__
                    )
                else:
                    self.info(
                        '%s: batch: %s(%s): %s',
                        context.principal, name,  # pylint: disable=no-member
                        ', '.join(api.Command[name]._repr_iter(**params)),
                        e.__class__.__name__
                    )
                if isinstance(e, errors.PublicError):
                    reported_error = e
                else:
                    reported_error = errors.InternalError()
                result = dict(
                    error=reported_error.strerror,
                    error_code=reported_error.errno,
                    error_name=unicode(type(reported_error).__name__),
                )
            results.append(result)
        return dict(count=len(results) , results=results)
Example #3
0
    def execute(self, methods=None, **options):
        results = []
        for arg in (methods or []):
            params = dict()
            name = None
            try:
                self._validate_request(arg)
                name = arg['method']
                a, kw = arg['params']
                newkw = dict((str(k), v) for k, v in kw.items())
                params = api.Command[name].args_options_2_params(*a, **newkw)
                newkw.setdefault('version', options['version'])

                result = api.Command[name](*a, **newkw)
                logger.info('%s: batch: %s(%s): SUCCESS',
                            getattr(context, 'principal', 'UNKNOWN'), name,
                            ', '.join(api.Command[name]._repr_iter(**params)))
                result['error'] = None
            except Exception as e:
                if (isinstance(e, errors.RequirementError)
                        or isinstance(e, errors.CommandError)
                        or isinstance(e, errors.ConversionError)):
                    logger.info(
                        '%s: batch: %s',
                        context.principal,  # pylint: disable=no-member
                        e.__class__.__name__)
                else:
                    logger.info(
                        '%s: batch: %s(%s): %s',
                        context.principal,
                        name,  # pylint: disable=no-member
                        ', '.join(api.Command[name]._repr_iter(**params)),
                        e.__class__.__name__)
                if isinstance(e, errors.PublicError):
                    reported_error = e
                else:
                    reported_error = errors.InternalError()
                result = dict(
                    error=reported_error.strerror,
                    error_code=reported_error.errno,
                    error_name=unicode(type(reported_error).__name__),
                    error_kw=reported_error.kw,
                )
            results.append(result)
        return dict(count=len(results), results=results)
Example #4
0
    def execute(self, methods=None, **options):
        results = []
        for arg in (methods or []):
            params = dict()
            name = None
            try:
                if 'method' not in arg:
                    raise errors.RequirementError(name='method')
                if 'params' not in arg:
                    raise errors.RequirementError(name='params')
                name = arg['method']
                if (name not in self.api.Command
                        or isinstance(self.api.Command[name], Local)):
                    raise errors.CommandError(name=name)

                # If params are not formated as a tuple(list, dict)
                # the following lines will raise an exception
                # that triggers an internal server error
                # Raise a ConversionError instead to report the issue
                # to the client
                try:
                    a, kw = arg['params']
                    newkw = dict((str(k), v) for k, v in kw.items())
                    params = api.Command[name].args_options_2_params(
                        *a, **newkw)
                except (AttributeError, ValueError, TypeError):
                    raise errors.ConversionError(
                        name='params',
                        error=_(u'must contain a tuple (list, dict)'))
                newkw.setdefault('version', options['version'])

                result = api.Command[name](*a, **newkw)
                self.info('%s: batch: %s(%s): SUCCESS',
                          getattr(context, 'principal', 'UNKNOWN'), name,
                          ', '.join(api.Command[name]._repr_iter(**params)))
                result['error'] = None
            except Exception as e:
                if isinstance(e, errors.RequirementError) or \
                    isinstance(e, errors.CommandError):
                    self.info(
                        '%s: batch: %s',
                        context.principal,  # pylint: disable=no-member
                        e.__class__.__name__)
                else:
                    self.info(
                        '%s: batch: %s(%s): %s',
                        context.principal,
                        name,  # pylint: disable=no-member
                        ', '.join(api.Command[name]._repr_iter(**params)),
                        e.__class__.__name__)
                if isinstance(e, errors.PublicError):
                    reported_error = e
                else:
                    reported_error = errors.InternalError()
                result = dict(
                    error=reported_error.strerror,
                    error_code=reported_error.errno,
                    error_name=unicode(type(reported_error).__name__),
                    error_kw=reported_error.kw,
                )
            results.append(result)
        return dict(count=len(results), results=results)