def execute(self, **options): ldap = self.api.Backend.ldap2 if not dns_container_exists(ldap): return False, [] try: zones = self.api.Command.dnszone_find(all=True)['result'] except errors.NotFound: self.log.info('No DNS zone to update found') return False, [] for zone in zones: update = {} if not zone.get('idnsallowquery'): # allow query from any client by default update['idnsallowquery'] = u'any;' if not zone.get('idnsallowtransfer'): # do not open zone transfers by default update['idnsallowtransfer'] = u'none;' old_policy = util.get_dns_forward_zone_update_policy( self.api.env.realm, ('A', 'AAAA')) if zone.get('idnsupdatepolicy', [''])[0] == old_policy: update['idnsupdatepolicy'] = util.get_dns_forward_zone_update_policy(\ self.api.env.realm) if update: # FIXME: https://fedorahosted.org/freeipa/ticket/4722 self.api.Command.dnszone_mod( zone[u'idnsname'][0].make_absolute(), **update) return False, []
def execute(self, **options): ldap = self.api.Backend.ldap2 if not dns_container_exists(ldap): return False, [] dns_principal = 'DNS/%s@%s' % (self.env.host, self.env.realm) dns_service_dn = DN(('krbprincipalname', dns_principal), self.env.container_service, self.env.basedn) try: entry = ldap.get_entry(dns_service_dn, self.limit_attributes) except errors.NotFound: # this host may not have DNS service set root_logger.debug("DNS: service %s not found, no need to update limits" % dns_service_dn) return False, [] if all(entry.get(limit.lower(), [None])[0] == self.limit_value for limit in self.limit_attributes): root_logger.debug("DNS: limits for service %s already set" % dns_service_dn) # service is already updated return False, [] limit_updates = [] for limit in self.limit_attributes: limit_updates.append(dict(action='only', attr=limit, value=self.limit_value)) dnsupdate = {'dn': dns_service_dn, 'updates': limit_updates} root_logger.debug("DNS: limits for service %s will be updated" % dns_service_dn) return False, [dnsupdate]
def execute(self, **options): ldap = self.api.Backend.ldap2 if not dns_container_exists(ldap): return False, [] try: zones = self.api.Command.dnszone_find(all=True)['result'] except errors.NotFound: self.log.debug('No DNS zone to update found') return False, [] for zone in zones: update = {} if not zone.get('idnsallowquery'): # allow query from any client by default update['idnsallowquery'] = u'any;' if not zone.get('idnsallowtransfer'): # do not open zone transfers by default update['idnsallowtransfer'] = u'none;' old_policy = util.get_dns_forward_zone_update_policy( self.api.env.realm, ('A', 'AAAA')) if zone.get('idnsupdatepolicy', [''])[0] == old_policy: update['idnsupdatepolicy'] = util.get_dns_forward_zone_update_policy(\ self.api.env.realm) if update: # FIXME: https://fedorahosted.org/freeipa/ticket/4722 self.api.Command.dnszone_mod(zone[u'idnsname'][0].make_absolute(), **update) return False, []
def post_callback(self, ldap, dn, entry_attrs, *keys, **options): assert isinstance(dn, DN) exc = None if dns_container_exists(ldap): try: parts = keys[-1].split('.') host = parts[0] domain = unicode('.'.join(parts[1:])) if options.get('ip_address'): add_reverse = not options.get('no_reverse', False) add_records_for_host(DNSName(host), DNSName(domain).make_absolute(), options['ip_address'], add_forward=True, add_reverse=add_reverse) del options['ip_address'] update_sshfp_record(domain, unicode(parts[0]), entry_attrs) except Exception as e: exc = e if options.get('random', False): try: entry_attrs['randompassword'] = unicode(getattr(context, 'randompassword')) except AttributeError: # On the off-chance some other extension deletes this from the # context, don't crash. pass if exc: raise errors.NonFatalError( reason=_('The host was added but the DNS update failed with: %(exc)s') % dict(exc=exc) ) set_certificate_attrs(entry_attrs) set_kerberos_attrs(entry_attrs, options) rename_ipaallowedtoperform_from_ldap(entry_attrs, options) if options.get('all', False): entry_attrs['managing'] = self.obj.get_managed_hosts(dn) self.obj.get_password_attributes(ldap, dn, entry_attrs) if entry_attrs['has_password']: # If an OTP is set there is no keytab, at least not one # fetched anywhere. entry_attrs['has_keytab'] = False convert_sshpubkey_post(ldap, dn, entry_attrs) return dn
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): assert isinstance(dn, DN) if options.get('ip_address') and dns_container_exists(ldap): parts = keys[-1].split('.') host = parts[0] domain = unicode('.'.join(parts[1:])) check_reverse = not options.get('no_reverse', False) add_records_for_host_validation('ip_address', DNSName(host), DNSName(domain).make_absolute(), options['ip_address'], check_forward=True, check_reverse=check_reverse) if not options.get('force', False) and not 'ip_address' in options: util.verify_host_resolvable(keys[-1], self.log) if 'locality' in entry_attrs: entry_attrs['l'] = entry_attrs['locality'] entry_attrs['cn'] = keys[-1] entry_attrs['serverhostname'] = keys[-1].split('.', 1)[0] if not entry_attrs.get('userpassword', False) and not options.get('random', False): entry_attrs['krbprincipalname'] = 'host/%s@%s' % ( keys[-1], self.api.env.realm ) if 'krbprincipalaux' not in entry_attrs['objectclass']: entry_attrs['objectclass'].append('krbprincipalaux') if 'krbprincipal' not in entry_attrs['objectclass']: entry_attrs['objectclass'].append('krbprincipal') else: if 'krbprincipalaux' in entry_attrs['objectclass']: entry_attrs['objectclass'].remove('krbprincipalaux') if 'krbprincipal' in entry_attrs['objectclass']: entry_attrs['objectclass'].remove('krbprincipal') if options.get('random'): entry_attrs['userpassword'] = ipa_generate_password(characters=host_pwd_chars) # save the password so it can be displayed in post_callback setattr(context, 'randompassword', entry_attrs['userpassword']) certs = options.get('usercertificate', []) certs_der = [x509.normalize_certificate(c) for c in certs] for cert in certs_der: x509.verify_cert_subject(ldap, keys[-1], cert) entry_attrs['usercertificate'] = certs_der entry_attrs['managedby'] = dn entry_attrs['objectclass'].append('ieee802device') entry_attrs['objectclass'].append('ipasshhost') update_krbticketflags(ldap, entry_attrs, attrs_list, options, False) if 'krbticketflags' in entry_attrs: entry_attrs['objectclass'].append('krbticketpolicyaux') return dn
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options): assert isinstance(dn, DN) if options.get('ip_address') and dns_container_exists(ldap): parts = keys[-1].split('.') host = parts[0] domain = unicode('.'.join(parts[1:])) check_reverse = not options.get('no_reverse', False) add_records_for_host_validation('ip_address', DNSName(host), DNSName(domain).make_absolute(), options['ip_address'], check_forward=True, check_reverse=check_reverse) if not options.get('force', False) and not 'ip_address' in options: util.validate_host_dns(self.log, keys[-1]) if 'locality' in entry_attrs: entry_attrs['l'] = entry_attrs['locality'] entry_attrs['cn'] = keys[-1] entry_attrs['serverhostname'] = keys[-1].split('.', 1)[0] if not entry_attrs.get('userpassword', False) and not options.get('random', False): entry_attrs['krbprincipalname'] = 'host/%s@%s' % ( keys[-1], self.api.env.realm ) if 'krbprincipalaux' not in entry_attrs['objectclass']: entry_attrs['objectclass'].append('krbprincipalaux') if 'krbprincipal' not in entry_attrs['objectclass']: entry_attrs['objectclass'].append('krbprincipal') else: if 'krbprincipalaux' in entry_attrs['objectclass']: entry_attrs['objectclass'].remove('krbprincipalaux') if 'krbprincipal' in entry_attrs['objectclass']: entry_attrs['objectclass'].remove('krbprincipal') if options.get('random'): entry_attrs['userpassword'] = ipa_generate_password(characters=host_pwd_chars) # save the password so it can be displayed in post_callback setattr(context, 'randompassword', entry_attrs['userpassword']) certs = options.get('usercertificate', []) certs_der = map(x509.normalize_certificate, certs) for cert in certs_der: x509.verify_cert_subject(ldap, keys[-1], cert) entry_attrs['usercertificate'] = certs_der entry_attrs['managedby'] = dn entry_attrs['objectclass'].append('ieee802device') entry_attrs['objectclass'].append('ipasshhost') update_krbticketflags(ldap, entry_attrs, attrs_list, options, False) if 'krbticketflags' in entry_attrs: entry_attrs['objectclass'].append('krbticketpolicyaux') return dn
def execute(self, **options): ldap = self.obj.backend if not dns_container_exists(ldap): return (False, False, []) dnsupdates = {} # add default and updated entries for dn, container, entry in ((self._write_dns_perm_dn, 'default', self._write_dns_perm_entry), (self._read_dns_perm_dn, 'default', self._read_dns_perm_entry), (self._write_dns_aci_dn, 'updates', self._write_dns_aci_entry), (self._read_dns_aci_dn, 'updates', self._read_dns_aci_entry)): dnsupdates[dn] = {'dn': dn, container: entry} return (False, True, [dnsupdates])
def post_callback(self, ldap, dn, entry_attrs, *keys, **options): assert isinstance(dn, DN) exc = None if dns_container_exists(ldap): try: parts = keys[-1].split('.') host = parts[0] domain = unicode('.'.join(parts[1:])) if options.get('ip_address'): add_reverse = not options.get('no_reverse', False) add_records_for_host(host, domain, options['ip_address'], add_forward=True, add_reverse=add_reverse) del options['ip_address'] update_sshfp_record(domain, unicode(parts[0]), entry_attrs) except Exception, e: exc = e
def execute(self, **options): ldap = self.obj.backend if not dns_container_exists(ldap): return (False, False, []) dns_principal = 'DNS/%s@%s' % (self.env.host, self.env.realm) dns_service_dn = DN(('krbprincipalname', dns_principal), self.env.container_service, self.env.basedn) try: (dn, entry) = ldap.get_entry(dns_service_dn, self.limit_attributes) except errors.NotFound: # this host may not have DNS service set root_logger.debug( "DNS: service %s not found, no need to update limits" % dns_service_dn) return (False, False, []) if all( entry.get(limit.lower(), [None])[0] == self.limit_value for limit in self.limit_attributes): root_logger.debug("DNS: limits for service %s already set" % dns_service_dn) # service is already updated return (False, False, []) limit_updates = [] for limit in self.limit_attributes: limit_updates.append('only:%s:%s' % (limit, self.limit_value)) dnsupdates = {} dnsupdates[dns_service_dn] = { 'dn': dns_service_dn, 'updates': limit_updates } root_logger.debug("DNS: limits for service %s will be updated" % dns_service_dn) return (False, True, [dnsupdates])
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 try: (dn, entry_attrs) = ldap.get_entry(dn, ['usercertificate']) except errors.NotFound: self.obj.handle_not_found(*keys) if 'usercertificate' in entry_attrs: cert = x509.normalize_certificate(entry_attrs.get('usercertificate')[0]) try: serial = unicode(x509.get_serial_number(cert, x509.DER)) try: result = api.Command['cert_show'](unicode(serial))['result' ] if 'revocation_reason' not in result: try: api.Command['cert_revoke'](unicode(serial), revocation_reason=4) except errors.NotImplementedError: # some CA's might not implement revoke pass except errors.NotImplementedError: # some CA's might not implement revoke pass except NSPRError, nsprerr: if nsprerr.errno == -8183: # If we can't decode the cert them proceed with # removing the host. self.log.info("Problem decoding certificate %s" % nsprerr.args[1]) else: raise nsprerr
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
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
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
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.env.enable_ra: try: (dn, entry_attrs) = ldap.get_entry(dn, ['usercertificate']) except errors.NotFound: self.obj.handle_not_found(*keys) cert = entry_attrs.single_value.get('usercertificate') if cert: cert = x509.normalize_certificate(cert) try: serial = unicode(x509.get_serial_number(cert, x509.DER)) try: result = api.Command['cert_show'](serial)['result'] if 'revocation_reason' not in result: try: api.Command['cert_revoke'](serial, revocation_reason=4) except errors.NotImplementedError: # some CA's might not implement revoke pass except errors.NotImplementedError: # some CA's might not implement revoke pass except NSPRError, nsprerr: if nsprerr.errno == -8183: # If we can't decode the cert them proceed with # removing the host. self.log.info("Problem decoding certificate %s" % nsprerr.args[1]) else: raise nsprerr
def execute_ad(self, *keys, **options): # Join domain using full credentials and with random trustdom # secret (will be generated by the join method) trustinstance = None if not _bindings_installed: raise errors.NotFound(name=_('AD Trust setup'), reason=_('''Cannot perform join operation without Samba 4 support installed. Make sure you have installed server-trust-ad sub-package of IPA''')) if 'realm_server' not in options: realm_server = None else: realm_server = options['realm_server'] trustinstance = ipaserver.dcerpc.TrustDomainJoins(self.api) if not trustinstance.configured: raise errors.NotFound(name=_('AD Trust setup'), reason=_('''Cannot perform join operation without own domain configured. Make sure you have run ipa-adtrust-install on the IPA server first''')) try: existing_trust = api.Command['trust_show'](keys[-1]) summary = _('Re-established trust to domain "%(value)s"') except errors.NotFound: summary = self.msg_summary # 1. Full access to the remote domain. Use admin credentials and # generate random trustdom password to do work on both sides if 'realm_admin' in options: realm_admin = options['realm_admin'] names = realm_admin.split('@') if len(names) > 1: # realm admin name is in UPN format, user@realm, check that # realm is the same as the one that we are attempting to trust if keys[-1].lower() != names[-1].lower(): raise errors.ValidationError(name=_('AD Trust setup'), error=_('Trusted domain and administrator account use different realms')) realm_admin = names[0] if 'realm_passwd' not in options: raise errors.ValidationError(name=_('AD Trust setup'), error=_('Realm administrator password should be specified')) realm_passwd = options['realm_passwd'] try: result = trustinstance.join_ad_full_credentials(keys[-1], realm_server, realm_admin, realm_passwd) except errors.NotFound, e: error_message=_("Unable to resolve domain controller for '%s' domain. ") % (keys[-1]) instructions=[] if dns_container_exists(self.obj.backend): try: dns_zone = api.Command.dnszone_show(keys[-1])['result'] if ('idnsforwardpolicy' in dns_zone) and dns_zone['idnsforwardpolicy'][0] == u'only': instructions.append(_("Forward policy is defined for it in IPA DNS, " "perhaps forwarder points to incorrect host?")) except (errors.NotFound, KeyError) as e: instructions.append(_("IPA manages DNS, please verify " "your DNS configuration and " "make sure that service records " "of the '%(domain)s' domain can " "be resolved. Examples how to " "configure DNS with CLI commands " "or the Web UI can be found in " "the documentation. " ) % dict(domain=keys[-1])) else: instructions.append(_("Since IPA does not manage DNS records, ensure DNS " "is configured to resolve '%(domain)s' domain from " "IPA hosts and back.") % dict(domain=keys[-1])) raise errors.NotFound(reason=error_message, instructions=instructions) if result is None: raise errors.ValidationError(name=_('AD Trust setup'), error=_('Unable to verify write permissions to the AD')) ret = dict(value=trustinstance.remote_domain.info['dns_domain'], verified=result['verified']) ret['summary'] = summary % ret return ret
def execute_ad(self, *keys, **options): # Join domain using full credentials and with random trustdom # secret (will be generated by the join method) trustinstance = None if not _bindings_installed: raise errors.NotFound( name=_('AD Trust setup'), reason= _('''Cannot perform join operation without Samba 4 support installed. Make sure you have installed server-trust-ad sub-package of IPA''' )) if 'realm_server' not in options: realm_server = None else: realm_server = options['realm_server'] trustinstance = ipaserver.dcerpc.TrustDomainJoins(self.api) if not trustinstance.configured: raise errors.NotFound( name=_('AD Trust setup'), reason= _('''Cannot perform join operation without own domain configured. Make sure you have run ipa-adtrust-install on the IPA server first''' )) try: existing_trust = api.Command['trust_show'](keys[-1]) summary = _('Re-established trust to domain "%(value)s"') except errors.NotFound: summary = self.msg_summary # 1. Full access to the remote domain. Use admin credentials and # generate random trustdom password to do work on both sides if 'realm_admin' in options: realm_admin = options['realm_admin'] names = realm_admin.split('@') if len(names) > 1: # realm admin name is in UPN format, user@realm, check that # realm is the same as the one that we are attempting to trust if keys[-1].lower() != names[-1].lower(): raise errors.ValidationError( name=_('AD Trust setup'), error= _('Trusted domain and administrator account use different realms' )) realm_admin = names[0] if 'realm_passwd' not in options: raise errors.ValidationError( name=_('AD Trust setup'), error=_( 'Realm administrator password should be specified')) realm_passwd = options['realm_passwd'] try: result = trustinstance.join_ad_full_credentials( keys[-1], realm_server, realm_admin, realm_passwd) except errors.NotFound, e: error_message = _( "Unable to resolve domain controller for '%s' domain. " ) % (keys[-1]) instructions = [] if dns_container_exists(self.obj.backend): try: dns_zone = api.Command.dnszone_show(keys[-1])['result'] if ('idnsforwardpolicy' in dns_zone ) and dns_zone['idnsforwardpolicy'][0] == u'only': instructions.append( _("Forward policy is defined for it in IPA DNS, " "perhaps forwarder points to incorrect host?" )) except (errors.NotFound, KeyError) as e: instructions.append( _("IPA manages DNS, please verify " "your DNS configuration and " "make sure that service records " "of the '%(domain)s' domain can " "be resolved. Examples how to " "configure DNS with CLI commands " "or the Web UI can be found in " "the documentation. ") % dict(domain=keys[-1])) else: instructions.append( _("Since IPA does not manage DNS records, ensure DNS " "is configured to resolve '%(domain)s' domain from " "IPA hosts and back.") % dict(domain=keys[-1])) raise errors.NotFound(reason=error_message, instructions=instructions) if result is None: raise errors.ValidationError( name=_('AD Trust setup'), error=_('Unable to verify write permissions to the AD')) ret = dict(value=trustinstance.remote_domain.info['dns_domain'], verified=result['verified']) ret['summary'] = summary % ret return ret
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
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
class host_mod(LDAPUpdate): __doc__ = _('Modify information about a host.') has_output_params = LDAPUpdate.has_output_params + host_output_params msg_summary = _('Modified host "%(value)s"') member_attributes = ['managedby'] takes_options = LDAPUpdate.takes_options + ( Str('krbprincipalname?', cli_name='principalname', label=_('Principal name'), doc=_('Kerberos principal name for this host'), attribute=True, ), Flag('updatedns?', doc=_('Update DNS entries'), default=False, ), ) 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'] del entry_attrs['locality'] if 'krbprincipalname' in entry_attrs: (dn, 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 cert = x509.normalize_certificate(entry_attrs.get('usercertificate')) if cert: x509.verify_cert_subject(ldap, keys[-1], cert) (dn, entry_attrs_old) = ldap.get_entry(dn, ['usercertificate']) if 'usercertificate' in entry_attrs_old: oldcert = x509.normalize_certificate(entry_attrs_old.get('usercertificate')[0]) try: serial = unicode(x509.get_serial_number(oldcert, x509.DER)) try: result = api.Command['cert_show'](unicode(serial))['result'] if 'revocation_reason' not in result: try: api.Command['cert_revoke'](unicode(serial), revocation_reason=4) except errors.NotImplementedError: # some CA's might not implement revoke pass except errors.NotImplementedError: # some CA's might not implement revoke pass except NSPRError, nsprerr: if nsprerr.errno == -8183: # If we can't decode the cert them proceed with # modifying the host. self.log.info("Problem decoding certificate %s" % nsprerr.args[1]) else: raise nsprerr entry_attrs['usercertificate'] = cert 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: (_dn, _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: (_dn, _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') return dn