Beispiel #1
0
    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
        assert isinstance(dn, DN)

        if 'usercertificate' in options:
            revoke_certs(options['usercertificate'], self.log)

        return dn
Beispiel #2
0
    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
        assert isinstance(dn, DN)

        if 'usercertificate' in options:
            revoke_certs(options['usercertificate'], self.log)

        return dn
Beispiel #3
0
    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
        assert isinstance(dn, DN)
        # Allow an existing OTP to be reset but don't allow a OTP to be
        # added to an enrolled host.
        if options.get('userpassword') or options.get('random'):
            entry = {}
            self.obj.get_password_attributes(ldap, dn, entry)
            if not entry['has_password'] and entry['has_keytab']:
                raise errors.ValidationError(
                    name='password',
                    error=_('Password cannot be set on enrolled host.'))

        # Once a principal name is set it cannot be changed
        if 'cn' in entry_attrs:
            raise errors.ACIError(info=_('cn is immutable'))
        if 'locality' in entry_attrs:
            entry_attrs['l'] = entry_attrs['locality']
        if 'krbprincipalname' in entry_attrs:
            entry_attrs_old = ldap.get_entry(
                dn, ['objectclass', 'krbprincipalname']
            )
            if 'krbprincipalname' in entry_attrs_old:
                msg = 'Principal name already set, it is unchangeable.'
                raise errors.ACIError(info=msg)
            obj_classes = entry_attrs_old['objectclass']
            if 'krbprincipalaux' not in obj_classes:
                obj_classes.append('krbprincipalaux')
                entry_attrs['objectclass'] = obj_classes

        # verify certificates
        certs = entry_attrs.get('usercertificate') or []
        certs_der = map(x509.normalize_certificate, certs)
        for cert in certs_der:
            x509.verify_cert_subject(ldap, keys[-1], cert)

        # revoke removed certificates
        if certs and self.api.Command.ca_is_enabled()['result']:
            try:
                entry_attrs_old = ldap.get_entry(dn, ['usercertificate'])
            except errors.NotFound:
                self.obj.handle_not_found(*keys)
            old_certs = entry_attrs_old.get('usercertificate', [])
            old_certs_der = map(x509.normalize_certificate, old_certs)
            removed_certs_der = set(old_certs_der) - set(certs_der)
            revoke_certs(removed_certs_der, self.log)

        if certs:
            entry_attrs['usercertificate'] = certs_der

        if options.get('random'):
            entry_attrs['userpassword'] = ipa_generate_password(characters=host_pwd_chars)
            setattr(context, 'randompassword', entry_attrs['userpassword'])

        if 'macaddress' in entry_attrs:
            if 'objectclass' in entry_attrs:
                obj_classes = entry_attrs['objectclass']
            else:
                _entry_attrs = ldap.get_entry(dn, ['objectclass'])
                obj_classes = _entry_attrs['objectclass']
            if 'ieee802device' not in obj_classes:
                obj_classes.append('ieee802device')
                entry_attrs['objectclass'] = obj_classes

        if options.get('updatedns', False) and dns_container_exists(ldap):
            parts = keys[-1].split('.')
            domain = unicode('.'.join(parts[1:]))
            try:
                result = api.Command['dnszone_show'](domain)['result']
                domain = result['idnsname'][0]
            except errors.NotFound:
                self.obj.handle_not_found(*keys)
            update_sshfp_record(domain, unicode(parts[0]), entry_attrs)

        if 'ipasshpubkey' in entry_attrs:
            if 'objectclass' in entry_attrs:
                obj_classes = entry_attrs['objectclass']
            else:
                _entry_attrs = ldap.get_entry(dn, ['objectclass'])
                obj_classes = entry_attrs['objectclass'] = _entry_attrs['objectclass']
            if 'ipasshhost' not in obj_classes:
                obj_classes.append('ipasshhost')

        update_krbticketflags(ldap, entry_attrs, attrs_list, options, True)

        if 'krbticketflags' in entry_attrs:
            if 'objectclass' not in entry_attrs:
                entry_attrs_old = ldap.get_entry(dn, ['objectclass'])
                entry_attrs['objectclass'] = entry_attrs_old['objectclass']
            if 'krbticketpolicyaux' not in entry_attrs['objectclass']:
                entry_attrs['objectclass'].append('krbticketpolicyaux')

        return dn
Beispiel #4
0
    def pre_callback(self, ldap, dn, *keys, **options):
        assert isinstance(dn, DN)
        # If we aren't given a fqdn, find it
        if _hostname_validator(None, keys[-1]) is not None:
            hostentry = api.Command['host_show'](keys[-1])['result']
            fqdn = hostentry['fqdn'][0]
        else:
            fqdn = keys[-1]
        host_is_master(ldap, fqdn)
        # Remove all service records for this host
        truncated = True
        while truncated:
            try:
                ret = api.Command['service_find'](fqdn)
                truncated = ret['truncated']
                services = ret['result']
            except errors.NotFound:
                break
            else:
                for entry_attrs in services:
                    principal = entry_attrs['krbprincipalname'][0]
                    (service, hostname, realm) = split_principal(principal)
                    if hostname.lower() == fqdn:
                        api.Command['service_del'](principal)
        updatedns = options.get('updatedns', False)
        if updatedns:
            try:
                updatedns = dns_container_exists(ldap)
            except errors.NotFound:
                updatedns = False

        if updatedns:
            # Remove DNS entries
            parts = fqdn.split('.')
            domain = unicode('.'.join(parts[1:]))
            try:
                result = api.Command['dnszone_show'](domain)['result']
                domain = result['idnsname'][0]
            except errors.NotFound:
                self.obj.handle_not_found(*keys)
            # Get all forward resources for this host
            records = api.Command['dnsrecord_find'](domain, idnsname=parts[0])['result']
            for record in records:
                if 'arecord' in record:
                    remove_fwd_ptr(record['arecord'][0], parts[0],
                                   domain, 'arecord')
                if 'aaaarecord' in record:
                    remove_fwd_ptr(record['aaaarecord'][0], parts[0],
                                   domain, 'aaaarecord')
                else:
                    # Try to delete all other record types too
                    _attribute_types = [str('%srecord' % t.lower())
                                        for t in _record_types]
                    for attr in _attribute_types:
                        if attr not in ['arecord', 'aaaarecord'] and attr in record:
                            for i in xrange(len(record[attr])):
                                if (record[attr][i].endswith(parts[0]) or
                                    record[attr][i].endswith(fqdn+'.')):
                                    delkw = { unicode(attr) : record[attr][i] }
                                    api.Command['dnsrecord_del'](domain,
                                            record['idnsname'][0],
                                            **delkw)
                            break

        if self.api.Command.ca_is_enabled()['result']:
            try:
                entry_attrs = ldap.get_entry(dn, ['usercertificate'])
            except errors.NotFound:
                self.obj.handle_not_found(*keys)

            revoke_certs(entry_attrs.get('usercertificate', []), self.log)

        return dn
Beispiel #5
0
    def execute(self, *keys, **options):
        ldap = self.obj.backend

        # If we aren't given a fqdn, find it
        if _hostname_validator(None, keys[-1]) is not None:
            hostentry = api.Command['host_show'](keys[-1])['result']
            fqdn = hostentry['fqdn'][0]
        else:
            fqdn = keys[-1]

        host_is_master(ldap, fqdn)

        # See if we actually do anthing here, and if not raise an exception
        done_work = False

        truncated = True
        while truncated:
            try:
                ret = api.Command['service_find'](fqdn)
                truncated = ret['truncated']
                services = ret['result']
            except errors.NotFound:
                break
            else:
                for entry_attrs in services:
                    principal = entry_attrs['krbprincipalname'][0]
                    (service, hostname, realm) = split_principal(principal)
                    if hostname.lower() == fqdn:
                        try:
                            api.Command['service_disable'](principal)
                            done_work = True
                        except errors.AlreadyInactive:
                            pass

        dn = self.obj.get_dn(*keys, **options)
        try:
            entry_attrs = ldap.get_entry(dn, ['usercertificate'])
        except errors.NotFound:
            self.obj.handle_not_found(*keys)
        if self.api.Command.ca_is_enabled()['result']:
            certs = entry_attrs.get('usercertificate', [])

            if certs:
                revoke_certs(certs, self.log)
                # Remove the usercertificate altogether
                entry_attrs['usercertificate'] = None
                ldap.update_entry(entry_attrs)
                done_work = True

        self.obj.get_password_attributes(ldap, dn, entry_attrs)
        if entry_attrs['has_keytab']:
            ldap.remove_principal_key(dn)
            done_work = True

        if not done_work:
            raise errors.AlreadyInactive()

        return dict(
            result=True,
            value=pkey_to_value(keys[0], options),
        )
Beispiel #6
0
    def pre_callback(self, ldap, dn, *keys, **options):
        assert isinstance(dn, DN)
        # If we aren't given a fqdn, find it
        if _hostname_validator(None, keys[-1]) is not None:
            hostentry = api.Command['host_show'](keys[-1])['result']
            fqdn = hostentry['fqdn'][0]
        else:
            fqdn = keys[-1]
        host_is_master(ldap, fqdn)
        # Remove all service records for this host
        truncated = True
        while truncated:
            try:
                ret = api.Command['service_find'](fqdn)
                truncated = ret['truncated']
                services = ret['result']
            except errors.NotFound:
                break
            else:
                for entry_attrs in services:
                    principal = entry_attrs['krbprincipalname'][0]
                    (service, hostname, realm) = split_principal(principal)
                    if hostname.lower() == fqdn:
                        api.Command['service_del'](principal)
        updatedns = options.get('updatedns', False)
        if updatedns:
            try:
                updatedns = dns_container_exists(ldap)
            except errors.NotFound:
                updatedns = False

        if updatedns:
            # Remove A, AAAA, SSHFP and PTR records of the host
            parts = fqdn.split('.')
            domain = unicode('.'.join(parts[1:]))
            # Get all resources for this host
            rec_removed = False
            try:
                record = api.Command['dnsrecord_show'](
                    domain, parts[0])['result']
            except errors.NotFound:
                pass
            else:
                # remove PTR records first
                for attr in ('arecord', 'aaaarecord'):
                    for val in record.get(attr, []):
                        rec_removed = (
                            remove_ptr_rec(val, parts[0], domain) or
                            rec_removed
                        )
                try:
                    # remove all A, AAAA, SSHFP records of the host
                    api.Command['dnsrecord_mod'](
                        domain,
                        record['idnsname'][0],
                        arecord=[],
                        aaaarecord=[],
                        sshfprecord=[]
                        )
                except errors.EmptyModlist:
                    pass
                else:
                    rec_removed = True

            if not rec_removed:
                self.add_message(
                    messages.FailedToRemoveHostDNSRecords(
                        host=fqdn,
                        reason=_("No A, AAAA, SSHFP or PTR records found.")
                    )
                )

        if self.api.Command.ca_is_enabled()['result']:
            try:
                entry_attrs = ldap.get_entry(dn, ['usercertificate'])
            except errors.NotFound:
                self.obj.handle_not_found(*keys)

            revoke_certs(entry_attrs.get('usercertificate', []), self.log)

        return dn
Beispiel #7
0
    def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
        assert isinstance(dn, DN)
        # Allow an existing OTP to be reset but don't allow a OTP to be
        # added to an enrolled host.
        if options.get('userpassword') or options.get('random'):
            entry = {}
            self.obj.get_password_attributes(ldap, dn, entry)
            if not entry['has_password'] and entry['has_keytab']:
                raise errors.ValidationError(
                    name='password',
                    error=_('Password cannot be set on enrolled host.'))

        # Once a principal name is set it cannot be changed
        if 'cn' in entry_attrs:
            raise errors.ACIError(info=_('cn is immutable'))
        if 'locality' in entry_attrs:
            entry_attrs['l'] = entry_attrs['locality']
        if 'krbprincipalname' in entry_attrs:
            entry_attrs_old = ldap.get_entry(
                dn, ['objectclass', 'krbprincipalname']
            )
            if 'krbprincipalname' in entry_attrs_old:
                msg = 'Principal name already set, it is unchangeable.'
                raise errors.ACIError(info=msg)
            obj_classes = entry_attrs_old['objectclass']
            if 'krbprincipalaux' not in obj_classes:
                obj_classes.append('krbprincipalaux')
                entry_attrs['objectclass'] = obj_classes

        # verify certificates
        certs = entry_attrs.get('usercertificate') or []
        certs_der = [x509.normalize_certificate(c) for c in certs]
        for cert in certs_der:
            x509.verify_cert_subject(ldap, keys[-1], cert)

        # revoke removed certificates
        if certs and self.api.Command.ca_is_enabled()['result']:
            try:
                entry_attrs_old = ldap.get_entry(dn, ['usercertificate'])
            except errors.NotFound:
                self.obj.handle_not_found(*keys)
            old_certs = entry_attrs_old.get('usercertificate', [])
            old_certs_der = [x509.normalize_certificate(c) for c in old_certs]
            removed_certs_der = set(old_certs_der) - set(certs_der)
            revoke_certs(removed_certs_der, self.log)

        if certs:
            entry_attrs['usercertificate'] = certs_der

        if options.get('random'):
            entry_attrs['userpassword'] = ipa_generate_password(characters=host_pwd_chars)
            setattr(context, 'randompassword', entry_attrs['userpassword'])

        if 'macaddress' in entry_attrs:
            if 'objectclass' in entry_attrs:
                obj_classes = entry_attrs['objectclass']
            else:
                _entry_attrs = ldap.get_entry(dn, ['objectclass'])
                obj_classes = _entry_attrs['objectclass']
            if 'ieee802device' not in obj_classes:
                obj_classes.append('ieee802device')
                entry_attrs['objectclass'] = obj_classes

        if options.get('updatedns', False) and dns_container_exists(ldap):
            parts = keys[-1].split('.')
            domain = unicode('.'.join(parts[1:]))
            try:
                result = api.Command['dnszone_show'](domain)['result']
                domain = result['idnsname'][0]
            except errors.NotFound:
                self.obj.handle_not_found(*keys)
            update_sshfp_record(domain, unicode(parts[0]), entry_attrs)

        if 'ipasshpubkey' in entry_attrs:
            if 'objectclass' in entry_attrs:
                obj_classes = entry_attrs['objectclass']
            else:
                _entry_attrs = ldap.get_entry(dn, ['objectclass'])
                obj_classes = entry_attrs['objectclass'] = _entry_attrs['objectclass']
            if 'ipasshhost' not in obj_classes:
                obj_classes.append('ipasshhost')

        update_krbticketflags(ldap, entry_attrs, attrs_list, options, True)

        if 'krbticketflags' in entry_attrs:
            if 'objectclass' not in entry_attrs:
                entry_attrs_old = ldap.get_entry(dn, ['objectclass'])
                entry_attrs['objectclass'] = entry_attrs_old['objectclass']
            if 'krbticketpolicyaux' not in entry_attrs['objectclass']:
                entry_attrs['objectclass'].append('krbticketpolicyaux')

        return dn
Beispiel #8
0
    def pre_callback(self, ldap, dn, *keys, **options):
        assert isinstance(dn, DN)
        # If we aren't given a fqdn, find it
        if _hostname_validator(None, keys[-1]) is not None:
            hostentry = api.Command['host_show'](keys[-1])['result']
            fqdn = hostentry['fqdn'][0]
        else:
            fqdn = keys[-1]
        host_is_master(ldap, fqdn)
        # Remove all service records for this host
        truncated = True
        while truncated:
            try:
                ret = api.Command['service_find'](fqdn)
                truncated = ret['truncated']
                services = ret['result']
            except errors.NotFound:
                break
            else:
                for entry_attrs in services:
                    principal = entry_attrs['krbprincipalname'][0]
                    (service, hostname, realm) = split_principal(principal)
                    if hostname.lower() == fqdn:
                        api.Command['service_del'](principal)
        updatedns = options.get('updatedns', False)
        if updatedns:
            try:
                updatedns = dns_container_exists(ldap)
            except errors.NotFound:
                updatedns = False

        if updatedns:
            # Remove DNS entries
            parts = fqdn.split('.')
            domain = unicode('.'.join(parts[1:]))
            try:
                result = api.Command['dnszone_show'](domain)['result']
                domain = result['idnsname'][0]
            except errors.NotFound:
                self.obj.handle_not_found(*keys)
            # Get all forward resources for this host
            records = api.Command['dnsrecord_find'](domain, idnsname=parts[0])['result']
            for record in records:
                if 'arecord' in record:
                    remove_fwd_ptr(record['arecord'][0], parts[0],
                                   domain, 'arecord')
                if 'aaaarecord' in record:
                    remove_fwd_ptr(record['aaaarecord'][0], parts[0],
                                   domain, 'aaaarecord')
                else:
                    # Try to delete all other record types too
                    _attribute_types = [str('%srecord' % t.lower())
                                        for t in _record_types]
                    for attr in _attribute_types:
                        if attr not in ['arecord', 'aaaarecord'] and attr in record:
                            for val in record[attr]:
                                if (val.endswith(parts[0]) or
                                        val.endswith(fqdn + '.')):
                                    delkw = {unicode(attr): val}
                                    api.Command['dnsrecord_del'](domain,
                                            record['idnsname'][0],
                                            **delkw)
                            break

        if self.api.Command.ca_is_enabled()['result']:
            try:
                entry_attrs = ldap.get_entry(dn, ['usercertificate'])
            except errors.NotFound:
                self.obj.handle_not_found(*keys)

            revoke_certs(entry_attrs.get('usercertificate', []), self.log)

        return dn
Beispiel #9
0
    def execute(self, *keys, **options):
        ldap = self.obj.backend

        # If we aren't given a fqdn, find it
        if _hostname_validator(None, keys[-1]) is not None:
            hostentry = api.Command['host_show'](keys[-1])['result']
            fqdn = hostentry['fqdn'][0]
        else:
            fqdn = keys[-1]

        host_is_master(ldap, fqdn)

        # See if we actually do anthing here, and if not raise an exception
        done_work = False

        truncated = True
        while truncated:
            try:
                ret = api.Command['service_find'](fqdn)
                truncated = ret['truncated']
                services = ret['result']
            except errors.NotFound:
                break
            else:
                for entry_attrs in services:
                    principal = entry_attrs['krbprincipalname'][0]
                    (service, hostname, realm) = split_principal(principal)
                    if hostname.lower() == fqdn:
                        try:
                            api.Command['service_disable'](principal)
                            done_work = True
                        except errors.AlreadyInactive:
                            pass

        dn = self.obj.get_dn(*keys, **options)
        try:
            entry_attrs = ldap.get_entry(dn, ['usercertificate'])
        except errors.NotFound:
            self.obj.handle_not_found(*keys)
        if self.api.Command.ca_is_enabled()['result']:
            certs = entry_attrs.get('usercertificate', [])

            if certs:
                revoke_certs(certs, self.log)
                # Remove the usercertificate altogether
                entry_attrs['usercertificate'] = None
                ldap.update_entry(entry_attrs)
                done_work = True

        self.obj.get_password_attributes(ldap, dn, entry_attrs)
        if entry_attrs['has_keytab']:
            ldap.remove_principal_key(dn)
            done_work = True

        if not done_work:
            raise errors.AlreadyInactive()

        return dict(
            result=True,
            value=pkey_to_value(keys[0], options),
        )