def _validate_pyparsing_hostname(name, data, text): try: thing = dns.name.from_text(text) except Exception as exc: raise HostnameParseError(name, data, text, str(exc)) if not is_inet_hostname(text): raise HostnameParseError(name, data, text, None) if not text.endswith('.'): raise HostnameParseError(name, data, text, "must end with '.'.")
def validate_initial_name(): if not name: return if isinstance(bind_file, StringIO): input_thing = 'StringIO object' elif file_name: input_thing = file_name else: input_thing = ('FD %s' % str(bind_file.fileno())) try: thing = dns.name.from_text(name) except Exception as exc: raise BadInitialZoneName(input_thing, name, str(exc)) if not is_inet_hostname(name): raise BadInitialZoneName(input_thing, name, None) if not name.endswith('.'): raise BadInitialZoneName(input_thing, name, "must end with '.'.")
def _queue_auto_ptr_data(self, auto_ptr_data): """ Queue auto PTR data as incremental updates against respective reverse zones. """ if not auto_ptr_data: return if not len(auto_ptr_data): return if not settings['auto_reverse']: return db_session = self.db_session # Create new update_group ug_dict = {} auto_ptr_privilege_flag = False for ptr_data in auto_ptr_data: # Ignore addresses we don't have reverse zone for query = db_session.query(ZoneSM)\ .join(ReverseNetwork)\ .filter(":address <<= reverse_networks.network")\ .params(address = ptr_data['address']) query = ZoneSM.query_is_not_deleted(query) query = ZoneSM.query_inc_updates(query) query = query.order_by(ReverseNetwork.network.desc())\ .limit(1) try: zone_sm = query.one() except NoResultFound: continue # Ignore invalid host names if not is_inet_hostname(ptr_data['hostname'], absolute=True, wildcard=False): log_error("Hostname '%s' is not a valid hostname." % ptr_data['hostname']) continue # Determine proposed update operation update_op = RROP_PTR_UPDATE_FORCE if ptr_data['force_reverse'] \ else RROP_PTR_UPDATE # Execute privilege checks ahead of time to save unnecessary churn # Better than needlessly going through whole rigamorole of # incremental update processing later on for no effect #1 See if old PTR exists to retrieve any RR reference # Both following also used lower down when generating RR_PTR label = label_from_address(ptr_data['address']) rr_ref = find_reference(db_session, ptr_data['reference'], raise_exc=False) # query for old record - this generates one select # Optimization - if check has previously suceeded, don't check # again as this is all checked further in if not auto_ptr_privilege_flag: qlabel= label[:label.rfind(zone_sm.name)-1] query = db_session.query(ResourceRecord)\ .filter(ResourceRecord.label == qlabel)\ .filter(ResourceRecord.zi_id == zone_sm.zi_candidate_id)\ .filter(ResourceRecord.disable == False)\ .filter(ResourceRecord.type_ == RRTYPE_PTR) old_rrs = query.all() old_rr = old_rrs[0] if len(old_rrs) else None # Check that we can proceed, only if check has not succeded yet if not check_auto_ptr_privilege(rr_ref, self.sectag, zone_sm, old_rr): if old_rr: log_debug("Zone '%s' - can't replace '%s' PTR" " as neither" " sectags '%s' vs '%s'" " references '%s' vs '%s'/'%s' (old PTR/rev zone)" "match ," " or values not given." % (zone_sm.name, old_rr.label, self.sectag.sectag, settings['admin_sectag'], rr_ref, old_rr.reference, zone_sm.reference)) else: log_debug("Zone '%s' - can't add '%s' PTR as neither" " sectags '%s' vs '%s'" " references '%s' vs '%s' (rev zone) match," " or values not given." % (zone_sm.name, qlabel, self.sectag.sectag, settings['admin_sectag'], rr_ref, zone_sm.reference)) continue auto_ptr_privilege_flag = True # Create a new update group if zone has not been seen before. try: update_group, zone_ttl = ug_dict.get(zone_sm) except (ValueError, TypeError): # Obtain reverse zone_ttl so PTR rrs can be created # Use candidate ZI as it always is available. # zi is published zi zi = self._get_zi(zone_sm.zi_candidate_id) if not zi: log_error("Zone '%s': does not have candidate zi." % zone_sm.name) continue zone_ttl = zi.zone_ttl update_group = new_update_group(db_session, None, zone_sm, None, ptr_only=True, sectag=self.sectag.sectag) ug_dict[zone_sm] = (update_group, zone_ttl) # Allocate RR_PTR update record rr = RR_PTR(label=label, zone_ttl=zone_ttl, rdata=ptr_data['hostname'], disable=ptr_data['disable'], domain=zone_sm.name, update_op=update_op) rr.ref_id = rr_ref.id_ if rr_ref else None rr.reference = rr_ref # Chain on RR_PTR update record update_group.update_ops.append(rr) # Flush everything to disk db_session.flush() # Issue zone refreshes to implement PTR changes for zone_sm in ug_dict: if zone_sm.is_disabled(): continue exec_zonesm(zone_sm, ZoneSMDoRefresh) # Make sure everything is committed db_session.commit()
def _queue_auto_ptr_data(self, auto_ptr_data): """ Queue auto PTR data as incremental updates against respective reverse zones. """ if not auto_ptr_data: return if not len(auto_ptr_data): return if not settings['auto_reverse']: return db_session = self.db_session # Create new update_group ug_dict = {} auto_ptr_privilege_flag = False for ptr_data in auto_ptr_data: # Ignore addresses we don't have reverse zone for query = db_session.query(ZoneSM)\ .join(ReverseNetwork)\ .filter(text(":address <<= reverse_networks.network"))\ .params(address = ptr_data['address']) query = ZoneSM.query_is_not_deleted(query) query = ZoneSM.query_inc_updates(query) query = query.order_by(ReverseNetwork.network.desc())\ .limit(1) try: zone_sm = query.one() except NoResultFound: continue # Ignore invalid host names if not is_inet_hostname( ptr_data['hostname'], absolute=True, wildcard=False): log_error("Hostname '%s' is not a valid hostname." % ptr_data['hostname']) continue # Determine proposed update operation update_op = RROP_PTR_UPDATE_FORCE if ptr_data['force_reverse'] \ else RROP_PTR_UPDATE # Execute privilege checks ahead of time to save unnecessary churn # Better than needlessly going through whole rigamorole of # incremental update processing later on for no effect #1 See if old PTR exists to retrieve any RR reference # Both following also used lower down when generating RR_PTR label = label_from_address(ptr_data['address']) rr_ref = find_reference(db_session, ptr_data['reference'], raise_exc=False) # query for old record - this generates one select # Optimization - if check has previously suceeded, don't check # again as this is all checked further in if not auto_ptr_privilege_flag: qlabel = label[:label.rfind(zone_sm.name) - 1] query = db_session.query(ResourceRecord)\ .filter(ResourceRecord.label == qlabel)\ .filter(ResourceRecord.zi_id == zone_sm.zi_candidate_id)\ .filter(ResourceRecord.disable == False)\ .filter(ResourceRecord.type_ == RRTYPE_PTR) old_rrs = query.all() old_rr = old_rrs[0] if len(old_rrs) else None # Check that we can proceed, only if check has not succeded yet if not check_auto_ptr_privilege(rr_ref, self.sectag, zone_sm, old_rr): if old_rr: log_debug( "Zone '%s' - can't replace '%s' PTR" " as neither" " sectags '%s' vs '%s'" " references '%s' vs '%s'/'%s' (old PTR/rev zone)" "match ," " or values not given." % (zone_sm.name, old_rr.label, self.sectag.sectag, settings['admin_sectag'], rr_ref, old_rr.reference, zone_sm.reference)) else: log_debug("Zone '%s' - can't add '%s' PTR as neither" " sectags '%s' vs '%s'" " references '%s' vs '%s' (rev zone) match," " or values not given." % (zone_sm.name, qlabel, self.sectag.sectag, settings['admin_sectag'], rr_ref, zone_sm.reference)) continue auto_ptr_privilege_flag = True # Create a new update group if zone has not been seen before. try: update_group, zone_ttl = ug_dict.get(zone_sm) except (ValueError, TypeError): # Obtain reverse zone_ttl so PTR rrs can be created # Use candidate ZI as it always is available. # zi is published zi zi = self._get_zi(zone_sm.zi_candidate_id) if not zi: log_error("Zone '%s': does not have candidate zi." % zone_sm.name) continue zone_ttl = zi.zone_ttl update_group = new_update_group(db_session, None, zone_sm, None, ptr_only=True, sectag=self.sectag.sectag) ug_dict[zone_sm] = (update_group, zone_ttl) # Allocate RR_PTR update record rr = RR_PTR(label=label, zone_ttl=zone_ttl, rdata=ptr_data['hostname'], disable=ptr_data['disable'], domain=zone_sm.name, update_op=update_op) rr.ref_id = rr_ref.id_ if rr_ref else None rr.reference = rr_ref # Chain on RR_PTR update record update_group.update_ops.append(rr) # Flush everything to disk db_session.flush() # Issue zone refreshes to implement PTR changes for zone_sm in ug_dict: if zone_sm.is_disabled(): continue exec_zonesm(zone_sm, ZoneSMDoRefresh) # Make sure everything is committed db_session.commit()