--- samba.orig/python/samba/netcmd/dns.py 2013-07-02 00:04:06.028174000 +0200 +++ samba/python/samba/netcmd/dns.py 2013-07-02 04:00:09.060174000 +0200 @@ -20,6 +20,7 @@ import samba.getopt as options from struct import pack from socket import inet_ntoa import shlex +from collections import OrderedDict from samba.netcmd import ( Command, @@ -386,6 +387,33 @@ def print_dnsrecords(outf, records): print_dns_record(outf, dns_rec) +def print_dns_record_bindlike(name, outf, rec, maxlen): + if rec.wType == dnsp.DNS_TYPE_A: + mesg = 'A\t%s' % (rec.data) + elif rec.wType == dnsp.DNS_TYPE_AAAA: + mesg = 'AAAA\t%s' % (rec.data) + elif rec.wType == dnsp.DNS_TYPE_PTR: + mesg = 'PTR\t%s' % (rec.data.str) + elif rec.wType == dnsp.DNS_TYPE_NS: + mesg = 'NS\t%s' % (rec.data.str) + elif rec.wType == dnsp.DNS_TYPE_CNAME: + mesg = 'CNAME\t%s' % (rec.data.str) + elif rec.wType == dnsp.DNS_TYPE_SOA: + mesg = 'SOA\t%s %s %d %d %d %d %d' % (rec.data.NamePrimaryServer.str, rec.data.ZoneAdministratorEmail.str, rec.data.dwSerialNo, rec.data.dwRefresh, rec.data.dwRetry, rec.data.dwExpire, rec.dwTtlSeconds) + elif rec.wType == dnsp.DNS_TYPE_MX: + mesg = 'MX\t%d %s' % (rec.data.wPreference, rec.data.nameExchange.str) + elif rec.wType == dnsp.DNS_TYPE_SRV: + mesg = 'SRV\t%d %d %d %s' % (rec.data.wPriority, rec.data.wWeight, rec.data.wPort, rec.data.nameTarget.str) + elif rec.wType == dnsp.DNS_TYPE_TXT: + slist = ['"%s"' % name.str for name in rec.data.str] + mesg = 'TXT\t%s' % ','.join(slist) + else: + mesg = '' + if mesg != '': + tabs = (maxlen / 8) - (len(name) / 8); + outf.write('%s\t%d\tIN\t%s\n' % (name + ('\t' * tabs), rec.dwTtlSeconds, mesg)) + + # # Always create a copy of strings when creating DNS_RPC_RECORDs # to overcome the bug in pidl generated python bindings. @@ -905,6 +933,47 @@ class cmd_zonedelete(Command): self.outf.write('Zone %s delete successfully\n' % zone) +class cmd_zonedump(Command): + """Dump a zone""" + + synopsis = '%prog [options]' + takes_args = [ 'server', 'zone' ] + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "versionopts": options.VersionOptions, + "credopts": options.CredentialsOptions, + } + takes_options = [ + ] + records = OrderedDict({}) + + def run(self, server, zone, name='@', sambaopts=None, credopts=None, versionopts=None): + record_type = dns_type_flag('ALL') + select_flags = dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA + self.lp = sambaopts.get_loadparm() + self.creds = credopts.get_credentials(self.lp) + dns_conn = dns_connect(server, self.lp, self.creds) + buflen, res = dns_conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN, 0, server, zone, name, None, record_type, select_flags, None, None) + for rec in res.rec: + recname = zone + '.' + if name != '@': + recname = name + '.' + recname + if rec.dnsNodeName.str: + recname = rec.dnsNodeName.str + '.' + recname + if rec.records: + self.records[recname] = rec.records + if rec.dwChildCount: + subname = rec.dnsNodeName.str + if name != '@': + subname += '.' + name + self.run(server, zone, subname, sambaopts, credopts, versionopts) + if name == '@': + maxlen = len(max(self.records.keys(), key = len)) + for rname in self.records.keys(): + for dns_rec in self.records[rname]: + print_dns_record_bindlike(rname, self.outf, dns_rec, maxlen) + + class cmd_query(Command): """Query a name.""" @@ -1179,6 +1248,7 @@ class cmd_dns(SuperCommand): subcommands['zonelist'] = cmd_zonelist() subcommands['zonecreate'] = cmd_zonecreate() subcommands['zonedelete'] = cmd_zonedelete() + subcommands['zonedump'] = cmd_zonedump() subcommands['query'] = cmd_query() subcommands['roothints'] = cmd_roothints() subcommands['add'] = cmd_add_record()