예제 #1
0
    def execute(self, *keys, **options):
        dn = self.obj.get_dn(*keys, **options)
        ldap = self.obj.backend

        domains_old = set(ldap.get_entry(dn)['associateddomain'])
        result = super(realmdomains_mod, self).execute(*keys, **options)
        domains_new = set(ldap.get_entry(dn)['associateddomain'])

        domains_added = domains_new - domains_old
        domains_deleted = domains_old - domains_new

        # Add a _kerberos TXT record for zones that correspond with
        # domains which were added
        for domain in domains_added:

            # Skip our own domain
            if domain == api.env.domain:
                continue

            try:
                self.api.Command['dnsrecord_add'](unicode(domain),
                                                  u'_kerberos',
                                                  txtrecord=api.env.realm)
            except (errors.EmptyModlist, errors.NotFound,
                    errors.ValidationError) as error:

                # If creation of the _kerberos TXT record failed, prompt
                # for manual intervention
                messages.add_message(
                    options['version'], result,
                    messages.KerberosTXTRecordCreationFailure(
                        domain=domain,
                        error=unicode(error),
                        realm=self.api.env.realm))

        # Delete _kerberos TXT record from zones that correspond with
        # domains which were deleted
        for domain in domains_deleted:

            # Skip our own domain
            if domain == api.env.domain:
                continue

            try:
                self.api.Command['dnsrecord_del'](unicode(domain),
                                                  u'_kerberos',
                                                  txtrecord=api.env.realm)
            except (errors.AttrValueNotFound, errors.NotFound,
                    errors.ValidationError) as error:
                # If deletion of the _kerberos TXT record failed, prompt
                # for manual intervention
                messages.add_message(
                    options['version'], result,
                    messages.KerberosTXTRecordDeletionFailure(
                        domain=domain, error=unicode(error)))

        return result
예제 #2
0
파일: server.py 프로젝트: zhoubh/freeipa
    def execute(self, *keys, **options):
        # the server must be the local host
        if keys[-2] != api.env.host:
            raise errors.ValidationError(name='cn',
                                         error=_("must be \"%s\"") %
                                         api.env.host)

        # the server entry must exist
        try:
            self.obj.get_dn_if_exists(*keys[:-1])
        except errors.NotFound:
            raise self.obj.handle_not_found(keys[-2])

        # the user must have the Replication Administrators privilege
        privilege = u'Replication Administrators'
        privilege_dn = self.api.Object.privilege.get_dn(privilege)
        ldap = self.obj.backend
        filter = ldap.make_filter(
            {
                'krbprincipalname': context.principal,  # pylint: disable=no-member
                'memberof': privilege_dn
            },
            rules=ldap.MATCH_ALL)
        try:
            ldap.find_entries(base_dn=self.api.env.basedn, filter=filter)
        except errors.NotFound:
            raise errors.ACIError(
                info=_("not allowed to perform server connection check"))

        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

        bus = dbus.SystemBus()
        obj = bus.get_object('org.freeipa.server',
                             '/',
                             follow_name_owner_changes=True)
        server = dbus.Interface(obj, 'org.freeipa.server')

        ret, stdout, _stderr = server.conncheck(keys[-1])

        result = dict(
            result=(ret == 0),
            value=keys[-2],
        )

        for line in stdout.splitlines():
            messages.add_message(options['version'], result,
                                 messages.ExternalCommandOutput(line=line))

        return result
예제 #3
0
파일: server.py 프로젝트: LiptonB/freeipa
    def execute(self, *keys, **options):
        # the server must be the local host
        if keys[-2] != api.env.host:
            raise errors.ValidationError(
                name='cn', error=_("must be \"%s\"") % api.env.host)

        # the server entry must exist
        try:
            self.obj.get_dn_if_exists(*keys[:-1])
        except errors.NotFound:
            self.obj.handle_not_found(keys[-2])

        # the user must have the Replication Administrators privilege
        privilege = u'Replication Administrators'
        privilege_dn = self.api.Object.privilege.get_dn(privilege)
        ldap = self.obj.backend
        filter = ldap.make_filter({
            'krbprincipalname': context.principal,  # pylint: disable=no-member
            'memberof': privilege_dn},
            rules=ldap.MATCH_ALL)
        try:
            ldap.find_entries(base_dn=self.api.env.basedn, filter=filter)
        except errors.NotFound:
            raise errors.ACIError(
                info=_("not allowed to perform server connection check"))

        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

        bus = dbus.SystemBus()
        obj = bus.get_object('org.freeipa.server', '/',
                             follow_name_owner_changes=True)
        server = dbus.Interface(obj, 'org.freeipa.server')

        ret, stdout, _stderr = server.conncheck(keys[-1])

        result = dict(
            result=(ret == 0),
            value=keys[-2],
        )

        for line in stdout.splitlines():
            messages.add_message(options['version'],
                                 result,
                                 messages.ExternalCommandOutput(line=line))

        return result
예제 #4
0
    def __call__(self, *args, **options):
        """
        Perform validation and then execute the command.

        If not in a server context, the call will be forwarded over
        XML-RPC and the executed an the nearest IPA server.
        """
        self.ensure_finalized()
        version_provided = 'version' in options
        if version_provided:
            self.verify_client_version(unicode(options['version']))
        elif self.api.env.skip_version_check and not self.api.env.in_server:
            options['version'] = u'2.0'
        else:
            options['version'] = API_VERSION
        params = self.args_options_2_params(*args, **options)
        self.debug(
            'raw: %s(%s)', self.name, ', '.join(self._repr_iter(**params))
        )
        params.update(self.get_default(**params))
        params = self.normalize(**params)
        params = self.convert(**params)
        self.debug(
            '%s(%s)', self.name, ', '.join(self._repr_iter(**params))
        )
        self.validate(**params)
        (args, options) = self.params_2_args_options(**params)
        ret = self.run(*args, **options)
        if (not version_provided and isinstance(ret, dict) and
                self.api.env.in_server):
            # add message only on server side
            messages.add_message(
                API_VERSION, ret,
                messages.VersionMissing(server_version=API_VERSION))
        if (
            isinstance(ret, dict)
            and 'summary' in self.output
            and 'summary' not in ret
        ):
            ret['summary'] = self.get_summary_default(ret)
        if self.use_output_validation and (self.output or ret is not None):
            self.validate_output(ret, options['version'])
        return ret
예제 #5
0
파일: frontend.py 프로젝트: msrb/freeipa
    def __call__(self, *args, **options):
        """
        Perform validation and then execute the command.

        If not in a server context, the call will be forwarded over
        XML-RPC and the executed an the nearest IPA server.
        """
        self.ensure_finalized()
        version_provided = 'version' in options
        if version_provided:
            self.verify_client_version(unicode(options['version']))
        elif self.api.env.skip_version_check and not self.api.env.in_server:
            options['version'] = VERSION_WITHOUT_CAPABILITIES
        else:
            options['version'] = API_VERSION
        params = self.args_options_2_params(*args, **options)
        self.debug(
            'raw: %s(%s)', self.name, ', '.join(self._repr_iter(**params))
        )
        params.update(self.get_default(**params))
        params = self.normalize(**params)
        params = self.convert(**params)
        self.debug(
            '%s(%s)', self.name, ', '.join(self._repr_iter(**params))
        )
        self.validate(**params)
        (args, options) = self.params_2_args_options(**params)
        ret = self.run(*args, **options)
        if (not version_provided and isinstance(ret, dict) and
                self.api.env.in_server):
            # add message only on server side
            messages.add_message(
                API_VERSION, ret,
                messages.VersionMissing(server_version=API_VERSION))
        if (
            isinstance(ret, dict)
            and 'summary' in self.output
            and 'summary' not in ret
        ):
            ret['summary'] = self.get_summary_default(ret)
        if self.use_output_validation and (self.output or ret is not None):
            self.validate_output(ret, options['version'])
        return ret
예제 #6
0
파일: otptoken.py 프로젝트: guanwei/freeipa
    def _get_qrcode(self, output, uri, version):
        # Print QR code to terminal if specified
        qr_output = StringIO()
        qr = qrcode.QRCode()
        qr.add_data(uri)
        qr.make()
        qr.print_ascii(out=qr_output, tty=False)

        encoding = getattr(sys.stdout, 'encoding', None)
        if encoding is None:
            encoding = locale.getpreferredencoding(False)

        try:
            qr_code = qr_output.getvalue().encode(encoding)
        except UnicodeError:
            add_message(
                version,
                output,
                message=ResultFormattingError(
                    message=_("Unable to display QR code using the configured "
                              "output encoding. Please use the token URI to "
                              "configure your OTP device")
                )
            )
            return None

        if sys.stdout.isatty():
            output_width = self.api.Backend.textui.get_tty_width()
            qr_code_width = len(qr_code.splitlines()[0])
            if qr_code_width > output_width:
                add_message(
                    version,
                    output,
                    message=ResultFormattingError(
                        message=_(
                            "QR code width is greater than that of the output "
                            "tty. Please resize your terminal.")
                    )
                )

        return qr
예제 #7
0
    def _get_qrcode(self, output, uri, version):
        # Print QR code to terminal if specified
        qr_output = StringIO()
        qr = qrcode.QRCode()
        qr.add_data(uri)
        qr.make()
        qr.print_ascii(out=qr_output, tty=False)

        encoding = getattr(sys.stdout, 'encoding', None)
        if encoding is None:
            encoding = locale.getpreferredencoding(False)

        try:
            qr_code = qr_output.getvalue().encode(encoding)
        except UnicodeError:
            add_message(
                version,
                output,
                message=ResultFormattingError(
                    message=_("Unable to display QR code using the configured "
                              "output encoding. Please use the token URI to "
                              "configure your OTP device")
                )
            )
            return None

        if sys.stdout.isatty():
            output_width = self.api.Backend.textui.get_tty_width()
            qr_code_width = len(qr_code.splitlines()[0])
            if qr_code_width > output_width:
                add_message(
                    version,
                    output,
                    message=ResultFormattingError(
                        message=_(
                            "QR code width is greater than that of the output "
                            "tty. Please resize your terminal.")
                    )
                )

        return qr
예제 #8
0
def test_add_message():
    result = {}

    assert capabilities['messages'] == u'2.52'

    messages.add_message(u'2.52', result,
                         HelloMessage(greeting='Hello', object='world'))
    messages.add_message(u'2.1', result,
                         HelloMessage(greeting="'Lo", object='version'))
    messages.add_message(u'2.60', result,
                         HelloMessage(greeting='Hi', object='version'))

    assert result == {'messages': [
        dict(
            name=u'HelloMessage',
            type=u'info',
            message=u'Hello, world!',
            code=1234,
            data={'greeting': 'Hello', 'object': 'world'},
        ),
        dict(
            name=u'HelloMessage',
            type=u'info',
            message=u'Hi, version!',
            code=1234,
            data={'greeting': 'Hi', 'object': 'version'},
        )
    ]}
예제 #9
0
def test_add_message():
    result = {}

    assert capabilities['messages'] == u'2.52'

    messages.add_message(u'2.52', result,
                         HelloMessage(greeting='Hello', object='world'))
    messages.add_message(u'2.1', result,
                         HelloMessage(greeting="'Lo", object='version'))
    messages.add_message(u'2.60', result,
                         HelloMessage(greeting='Hi', object='version'))

    assert result == {'messages': [
        dict(
            name='HelloMessage',
            type='info',
            message='Hello, world!',
            code=1234,
        ),
        dict(
            name='HelloMessage',
            type='info',
            message='Hi, version!',
            code=1234,
        )
    ]}
예제 #10
0
파일: server.py 프로젝트: zpytela/freeipa
    def execute(self, *keys, **options):
        # the server must be the local host
        if keys[-2] != api.env.host:
            raise errors.ValidationError(name='cn',
                                         error=_("must be \"%s\"") %
                                         api.env.host)

        # the server entry must exist
        try:
            self.obj.get_dn_if_exists(*keys[:-1])
        except errors.NotFound:
            raise self.obj.handle_not_found(keys[-2])

        # the user must have the Replication Administrators privilege
        privilege = u'Replication Administrators'
        if not principal_has_privilege(self.api, context.principal, privilege):
            raise errors.ACIError(
                info=_("not allowed to perform server connection check"))

        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

        bus = dbus.SystemBus()
        obj = bus.get_object('org.freeipa.server',
                             '/',
                             follow_name_owner_changes=True)
        server = dbus.Interface(obj, 'org.freeipa.server')

        ret, stdout, _stderr = server.conncheck(keys[-1])

        result = dict(
            result=(ret == 0),
            value=keys[-2],
        )

        for line in stdout.splitlines():
            messages.add_message(options['version'], result,
                                 messages.ExternalCommandOutput(line=line))

        return result
예제 #11
0
 def forward(self, *args, **kw):
     result = {'name': 'forward'}
     messages.add_message(kw['version'], result, TestMessage())
     return result
예제 #12
0
 def execute(self, *args, **kw):
     result = {'name': 'execute'}
     messages.add_message(kw['version'], result, TestMessage())
     return result
예제 #13
0
 def forward(self, *args, **kw):
     result = {'name': 'forward'}
     messages.add_message(kw['version'], result, TestMessage())
     return result
예제 #14
0
 def execute(self, *args, **kw):
     result = {'name': 'execute'}
     messages.add_message(kw['version'], result, TestMessage())
     return result
예제 #15
0
    def execute(self, *keys, **options):
        dn = self.obj.get_dn(*keys, **options)
        ldap = self.obj.backend

        domains_old = set(ldap.get_entry(dn)['associateddomain'])
        result = super(realmdomains_mod, self).execute(*keys, **options)
        domains_new = set(ldap.get_entry(dn)['associateddomain'])

        domains_added = domains_new - domains_old
        domains_deleted = domains_old - domains_new

        # Add a _kerberos TXT record for zones that correspond with
        # domains which were added
        for domain in domains_added:

            # Skip our own domain
            if domain == api.env.domain:
                continue

            try:
                self.api.Command['dnsrecord_add'](
                    unicode(domain),
                    u'_kerberos',
                    txtrecord=api.env.realm
                )
            except (errors.EmptyModlist, errors.NotFound,
                    errors.ValidationError) as error:

                # If creation of the _kerberos TXT record failed, prompt
                # for manual intervention
                messages.add_message(
                    options['version'],
                    result,
                    messages.KerberosTXTRecordCreationFailure(
                        domain=domain,
                        error=unicode(error),
                        realm=self.api.env.realm
                    )
                )

        # Delete _kerberos TXT record from zones that correspond with
        # domains which were deleted
        for domain in domains_deleted:

            # Skip our own domain
            if domain == api.env.domain:
                continue

            try:
                self.api.Command['dnsrecord_del'](
                    unicode(domain),
                    u'_kerberos',
                    txtrecord=api.env.realm
                )
            except (errors.AttrValueNotFound, errors.NotFound,
                    errors.ValidationError) as error:
                # If deletion of the _kerberos TXT record failed, prompt
                # for manual intervention
                messages.add_message(
                    options['version'],
                    result,
                    messages.KerberosTXTRecordDeletionFailure(
                        domain=domain, error=unicode(error)
                    )
                )

        return result