Exemple #1
0
    def legal_dns_owner_name(self, name, record_type, allow_underscores=False):
        uber_hyphen = re.compile(r'---+')
        uber_underscore = re.compile(r'__+')
        if record_type == dns.SRV_OWNER or allow_underscores:
            valid_chars = re.compile(r'^[a-zA-Z\-_0-9]*$')
        else:
            valid_chars = re.compile(r'^[a-zA-Z\-0-9]+$')

        if not name.endswith('.'):
            raise DNSError("Name not fully qualified")

        for n in name[:-1].split("."):
            if n.startswith("-") or n.endswith("-"):
                raise DNSError(
                    "Illegal name: '%s'; Cannot start or end with '-'"
                    % (name,))
            if uber_hyphen.search(n):
                raise DNSError(
                    "Illegal name: '%s'; More than two '-' in a row"
                    % (name, ))
            if not valid_chars.search(n):
                raise DNSError(
                    "Illegal name: '%s'; Invalid character(s)" % (name, ))
            if record_type == dns.SRV_OWNER:
                if uber_underscore.search(n):
                    raise DNSError(
                        "Illegal name: '%s'; More than one '_' in a row"
                        % (name, ))
Exemple #2
0
    def dns_reg_owner_ok(self, name, record_type, allow_underscores=False):
        """
        Checks if it is legal to register a record of type
        record_type with given name.  Raises an exception if record_type
        is illegal, or name is illegal.  Returns:
          - dns_owner_ref: reference to dns_owner or None if non-existing
          - same_type: boolean set to true if a record of the same type exists.
        """

        dns_owner = DnsOwner.DnsOwner(self._db)
        self.legal_dns_owner_name(name, record_type, allow_underscores)
        try:
            dns_owner.find_by_name(name)
        except Errors.NotFoundError:
            return None, None

        owner_types = self._find.find_dns_owners(dns_owner.entity_id)

        if dns.CNAME_OWNER in owner_types:
            raise DNSError("%s is already a CNAME" % (name, ))

        if record_type == dns.CNAME_OWNER:
            if owner_types:
                raise DNSError("%s already exists" % (name, ))
        if record_type == dns.HOST_INFO:
            if dns.HOST_INFO in owner_types:
                raise DNSError("%s already exists" % (name, ))
        # TODO: This should probarbly be rewritten, since it is a bit ugly.
        # The difference between A- and AAAA-records is minimal, so this is
        # enough for now.
        if record_type in (dns.A_RECORD, dns.AAAA_RECORD,):
            if dns.A_RECORD in owner_types or dns.AAAA_RECORD in owner_types:
                return dns_owner.entity_id, True

        return dns_owner.entity_id, False
Exemple #3
0
    def remove_arecord(self, a_record_id, try_dns_remove=False):
        """Remove an a-record identified by a_record_id.

        Will also update override_revmap and remove the entry in ip_number if
        it is no longer referred to by other tables.

        :param int a_record_id: The ARecords id.
        :param bool try_dns_remove: Remove the DNSOwner too.
        """
        ip_type = dns.IP_NUMBER
        record_type = dns.A_RECORD
        arecord = ARecord.ARecord(self._db)

        try:
            arecord.find(a_record_id)
            ip_number_id = arecord.ip_number_id
            ipnumber = IPNumber.IPNumber(self._db)
        except Errors.NotFoundError:
            arecord = AAAARecord.AAAARecord(self._db)
            arecord.find(a_record_id)
            ip_type = dns.IPv6_NUMBER
            record_type = dns.AAAA_RECORD
            ip_number_id = arecord.ipv6_number_id
            ipnumber = IPv6Number.IPv6Number(self._db)

        ipnumber.find(ip_number_id)

        dns_owner_id = arecord.dns_owner_id
        arecord._delete()

        refs = self._find.find_referers(ip_number_id=ipnumber.entity_id,
                                        ip_type=ip_type)
        if dns.REV_IP_NUMBER in refs:
            self._update_override(ipnumber.entity_id, dns_owner_id)
            refs = self._find.find_referers(ip_number_id=ipnumber.entity_id,
                                            ip_type=ip_type)

        if not (dns.REV_IP_NUMBER in refs or record_type in refs):
            # IP no longer used
            ipnumber.delete()

        # Assert that any cname/srv targets still point to atleast one
        # a-record.  Assert that host_info has atleast one associated
        # a_record.
        # TODO: This check should be somewhere that makes it is easier
        # to always enforce this constraint.
        refs = set(self._find.find_referers(dns_owner_id=dns_owner_id,
                                            ip_type=dns.IP_NUMBER))
        refs.update(self._find.find_referers(dns_owner_id=dns_owner_id,
                                             ip_type=dns.IPv6_NUMBER))
        if not any(r_type in refs
                   for r_type in (dns.A_RECORD, dns.AAAA_RECORD)):
            if dns.SRV_TARGET in refs or dns.CNAME_TARGET in refs:
                raise DNSError("Host is used as target for CNAME or SRV")

        if try_dns_remove:
            self.remove_dns_owner(dns_owner_id)
Exemple #4
0
    def _verify_mac_format(self, mac_adr):
        """Checks that the given MAC-address is written with an
        acceptable format. If so, it returns the MAC address on the
        standardized format.

        Acceptable formats:
        * Valid seperators are ':', '-', '.' and ' '
        * Numbers are hexa-decimal. Capitalization doesn't matter
        * Seperators between every 2 or 4 numbers

        Standardized format:
        * Only ':' used as seperator, between every two numbers
        * Only lowercase hexa-decimal numbers.
        
        @type mac_adr: string
        @param mac_adr: The MAC address that is to be verified

        @rtype: string
        @return: The MAC-address as formatted to the standard format

        @raise DNSError: If mac_adr isn't formatted in any valid way

        """
        # Prepare error message for possible later use
        error_msg = ("Invalid MAC-address: '%s'. " % mac_adr +
                     "Try something like '01:23:45:67:89:ab' instead")

        # Standardize case
        mac_adr = mac_adr.lower()
        # Standardize seperator character
        for char in ('-', '.', ' '):
            mac_adr = mac_adr.replace(char, ":")
        # Standardize if using Cisco format or no seperators at all
        for index in (2, 5, 8, 11, 14):
            try:
                if not mac_adr[index] == ':':
                    mac_adr = mac_adr[0:index] + ':' + mac_adr[index:]
            except IndexError:
                raise DNSError(error_msg)

        if not re.search("^([a-f0-9]{2}:){5}[a-f0-9]{2}$", mac_adr):
            raise DNSError(error_msg)

        return mac_adr
Exemple #5
0
    def remove_dns_owner(self, dns_owner_id):
        refs = self._find.find_referers(dns_owner_id=dns_owner_id)
        if refs:
            raise DNSError("dns_owner still refered in %s" % str(refs))

        dns_owner = DnsOwner.DnsOwner(self._db)
        dns_owner.find(dns_owner_id)

        if not self._find.find_overrides(dns_owner_id=dns_owner_id):
            dns_owner.delete()
        else:
            for t in dns_owner.get_traits().keys():
                try:
                    dns_owner.delete_trait(t)
                except errors.NotFoundError:
                    pass
            dns_owner.mx_set_id = None
            dns_owner.write_db()
Exemple #6
0
 def alter_entity_note(self, owner_id, trait, dta):
     dta = dta.strip()
     if trait == self.const.trait_dns_contact:
         mail_ok_re = re.compile(cereconf.DNS_EMAIL_REGEXP)
         if dta and not mail_ok_re.match(dta):
             raise DNSError("'%s' does not look like an e-mail address" %
                            dta)
     self._dns_owner.clear()
     self._dns_owner.find(owner_id)
     if not dta:
         try:
             self._dns_owner.delete_trait(trait)
         except Errors.NotFoundError:  # Already deleted, noop
             pass
         return "removed"
     if self._dns_owner.populate_trait(trait, strval=dta) == 'INSERT':
         action = "added"
     else:
         action = 'updated'
     self._dns_owner.write_db()
     return action
Exemple #7
0
 def ip_to_long(ip):
     try:
         return struct.unpack('!L', socket.inet_aton(ip))[0]
     except socket.error, msg:
         raise DNSError("Bad IP: %s" % msg)
Exemple #8
0
 def ip_to_long(ip):
     """Convert an IPv6 IP address to long format."""
     try:
         hi, lo = struct.unpack('!QQ', socket.inet_pton(socket.AF_INET6, ip))
     except socket.error, msg:
         raise DNSError("Bad IP: %s" % msg)