mirror of
https://github.com/samba-team/samba.git
synced 2025-12-16 00:23:52 +03:00
py/dnsserver: add .from_string() methods
The logic to parse DNS value strings (e.g. "example.com 10" for an MX, which needs to be split on the space) is repeated at least in samba-tool dns and tests/dcerpc/dnsserver.py. Here we bring it together so we can do it once. The sep= keyword allows callers to separate on all runs of whitespace (the default, as samba-tool dns does) or, using sep='', to separate on true spaces only. Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
committed by
Douglas Bagnall
parent
bddce1f7e6
commit
d84d10bb0e
@@ -16,6 +16,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import shlex
|
||||
from samba.dcerpc import dnsserver, dnsp
|
||||
|
||||
# Note: these are not quite the same as similar looking classes in
|
||||
@@ -39,6 +40,9 @@ from samba.dcerpc import dnsserver, dnsp
|
||||
# them can represent any type of record.
|
||||
|
||||
|
||||
class DNSParseError(ValueError):
|
||||
pass
|
||||
|
||||
|
||||
class ARecord(dnsserver.DNS_RPC_RECORD):
|
||||
def __init__(self, ip_addr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
|
||||
@@ -50,6 +54,10 @@ class ARecord(dnsserver.DNS_RPC_RECORD):
|
||||
self.dwTtlSeconds = ttl
|
||||
self.data = ip_addr
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, data, sep=None, **kwargs):
|
||||
return cls(data, **kwargs)
|
||||
|
||||
|
||||
class AAAARecord(dnsserver.DNS_RPC_RECORD):
|
||||
|
||||
@@ -62,6 +70,10 @@ class AAAARecord(dnsserver.DNS_RPC_RECORD):
|
||||
self.dwTtlSeconds = ttl
|
||||
self.data = ip6_addr
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, data, sep=None, **kwargs):
|
||||
return cls(data, **kwargs)
|
||||
|
||||
|
||||
class PTRRecord(dnsserver.DNS_RPC_RECORD):
|
||||
|
||||
@@ -77,6 +89,10 @@ class PTRRecord(dnsserver.DNS_RPC_RECORD):
|
||||
ptr_name.len = len(ptr)
|
||||
self.data = ptr_name
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, data, sep=None, **kwargs):
|
||||
return cls(data, **kwargs)
|
||||
|
||||
|
||||
class CNAMERecord(dnsserver.DNS_RPC_RECORD):
|
||||
|
||||
@@ -92,6 +108,10 @@ class CNAMERecord(dnsserver.DNS_RPC_RECORD):
|
||||
cname_name.len = len(cname)
|
||||
self.data = cname_name
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, data, sep=None, **kwargs):
|
||||
return cls(data, **kwargs)
|
||||
|
||||
|
||||
class NSRecord(dnsserver.DNS_RPC_RECORD):
|
||||
|
||||
@@ -107,6 +127,10 @@ class NSRecord(dnsserver.DNS_RPC_RECORD):
|
||||
ns.len = len(dns_server)
|
||||
self.data = ns
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, data, sep=None, **kwargs):
|
||||
return cls(data, **kwargs)
|
||||
|
||||
|
||||
class MXRecord(dnsserver.DNS_RPC_RECORD):
|
||||
|
||||
@@ -123,6 +147,16 @@ class MXRecord(dnsserver.DNS_RPC_RECORD):
|
||||
mx.nameExchange.len = len(mail_server)
|
||||
self.data = mx
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, data, sep=None, **kwargs):
|
||||
try:
|
||||
server, priority = data.split(sep)
|
||||
priority = int(priority)
|
||||
except ValueError as e:
|
||||
raise DNSParseError("MX data must have server and priority "
|
||||
"(space separated), not %r" % data) from e
|
||||
return cls(server, priority, **kwargs)
|
||||
|
||||
|
||||
class SOARecord(dnsserver.DNS_RPC_RECORD):
|
||||
|
||||
@@ -146,6 +180,21 @@ class SOARecord(dnsserver.DNS_RPC_RECORD):
|
||||
soa.ZoneAdministratorEmail.len = len(rname)
|
||||
self.data = soa
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, data, sep=None, **kwargs):
|
||||
args = data.split(sep)
|
||||
if len(args) != 7:
|
||||
raise DNSParseError('Data requires 7 space separated elements - '
|
||||
'nameserver, email, serial, '
|
||||
'refresh, retry, expire, minimumttl')
|
||||
try:
|
||||
for i in range(2, 7):
|
||||
args[i] = int(args[i])
|
||||
except ValueError as e:
|
||||
raise DNSParseError("SOA serial, refresh, retry, expire, minimumttl' "
|
||||
"should be integers") from e
|
||||
return cls(*args, **kwargs)
|
||||
|
||||
|
||||
class SRVRecord(dnsserver.DNS_RPC_RECORD):
|
||||
|
||||
@@ -164,6 +213,23 @@ class SRVRecord(dnsserver.DNS_RPC_RECORD):
|
||||
srv.nameTarget.len = len(target)
|
||||
self.data = srv
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, data, sep=None, **kwargs):
|
||||
try:
|
||||
target, port, priority, weight = data.split(sep)
|
||||
except ValueError as e:
|
||||
raise DNSParseError("SRV data must have four space "
|
||||
"separated elements: "
|
||||
"server, port, priority, weight; "
|
||||
"not %r" % data) from e
|
||||
try:
|
||||
args = (target, int(port), int(priority), int(weight))
|
||||
except ValueError as e:
|
||||
raise DNSParseError("SRV port, priority, and weight "
|
||||
"must be integers") from e
|
||||
|
||||
return cls(*args, **kwargs)
|
||||
|
||||
|
||||
class TXTRecord(dnsserver.DNS_RPC_RECORD):
|
||||
|
||||
@@ -184,3 +250,8 @@ class TXTRecord(dnsserver.DNS_RPC_RECORD):
|
||||
txt.count = len(slist)
|
||||
txt.str = names
|
||||
self.data = txt
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, data, sep=None, **kwargs):
|
||||
slist = shlex.split(data)
|
||||
return cls(slist, **kwargs)
|
||||
|
||||
Reference in New Issue
Block a user