samba-tool: dns: Convert dns data into a dns record for comparison
[Samba/bjacke.git] / source4 / scripting / python / samba / netcmd / dns.py
blobf1adc06faa6eaa43067a7260dbb5797d39f3e348
1 #!/usr/bin/env python
3 # DNS management tool
5 # Copyright (C) Amitay Isaacs 2011
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21 import samba.getopt as options
22 from struct import pack
23 from socket import inet_ntoa
25 from samba.netcmd import (
26 Command,
27 CommandError,
28 Option,
29 SuperCommand,
31 from samba.dcerpc import dnsp, dnsserver
34 def dns_connect(server, lp, creds):
35 binding_str = "ncacn_ip_tcp:%s[sign]" % server
36 dns_conn = dnsserver.dnsserver(binding_str, lp, creds)
37 return dns_conn
39 def bool_string(flag):
40 if flag == 0:
41 ret = 'FALSE'
42 elif flag == 1:
43 ret = 'TRUE'
44 else:
45 ret = 'UNKNOWN (0x%x)' % flag
46 return ret
48 def enum_string(module, enum_defs, value):
49 ret = None
50 for e in enum_defs:
51 if value == getattr(module, e):
52 ret = e
53 break
54 if not ret:
55 ret = 'UNKNOWN (0x%x)' % value
56 return ret
58 def bitmap_string(module, bitmap_defs, value):
59 ret = ''
60 for b in bitmap_defs:
61 if value & getattr(module, b):
62 ret += '%s ' % b
63 if not ret:
64 ret = 'NONE'
65 return ret
67 def boot_method_string(boot_method):
68 enum_defs = [ 'DNS_BOOT_METHOD_UNINITIALIZED', 'DNS_BOOT_METHOD_FILE',
69 'DNS_BOOT_METHOD_REGISTRY', 'DNS_BOOT_METHOD_DIRECTORY' ]
70 return enum_string(dnsserver, enum_defs, boot_method)
72 def name_check_flag_string(check_flag):
73 enum_defs = [ 'DNS_ALLOW_RFC_NAMES_ONLY', 'DNS_ALLOW_NONRFC_NAMES',
74 'DNS_ALLOW_MULTIBYTE_NAMES', 'DNS_ALLOW_ALL_NAMES' ]
75 return enum_string(dnsserver, enum_defs, check_flag)
77 def zone_type_string(zone_type):
78 enum_defs = [ 'DNS_ZONE_TYPE_CACHE', 'DNS_ZONE_TYPE_PRIMARY',
79 'DNS_ZONE_TYPE_SECONDARY', 'DNS_ZONE_TYPE_STUB',
80 'DNS_ZONE_TYPE_FORWARDER', 'DNS_ZONE_TYPE_SECONDARY_CACHE' ]
81 return enum_string(dnsp, enum_defs, zone_type)
83 def zone_update_string(zone_update):
84 enum_defs = [ 'DNS_ZONE_UPDATE_OFF', 'DNS_ZONE_UPDATE_SECURE',
85 'DNS_ZONE_UPDATE_SECURE' ]
86 return enum_string(dnsp, enum_defs, zone_update)
88 def zone_secondary_security_string(security):
89 enum_defs = [ 'DNS_ZONE_SECSECURE_NO_SECURITY', 'DNS_ZONE_SECSECURE_NS_ONLY',
90 'DNS_ZONE_SECSECURE_LIST_ONLY', 'DNS_ZONE_SECSECURE_NO_XFER' ]
91 return enum_string(dnsserver, enum_defs, security)
93 def zone_notify_level_string(notify_level):
94 enum_defs = [ 'DNS_ZONE_NOTIFY_OFF', 'DNS_ZONE_NOTIFY_ALL_SECONDARIES',
95 'DNS_ZONE_NOTIFY_LIST_ONLY' ]
96 return enum_string(dnsserver, enum_defs, notify_level)
98 def dp_flags_string(dp_flags):
99 bitmap_defs = [ 'DNS_DP_AUTOCREATED', 'DNS_DP_LEGACY', 'DNS_DP_DOMAIN_DEFAULT',
100 'DNS_DP_FOREST_DEFAULT', 'DNS_DP_ENLISTED', 'DNS_DP_DELETED' ]
101 return bitmap_string(dnsserver, bitmap_defs, dp_flags)
103 def zone_flags_string(flags):
104 bitmap_defs = [ 'DNS_RPC_ZONE_PAUSED', 'DNS_RPC_ZONE_SHUTDOWN',
105 'DNS_RPC_ZONE_REVERSE', 'DNS_RPC_ZONE_AUTOCREATED',
106 'DNS_RPC_ZONE_DSINTEGRATED', 'DNS_RPC_ZONE_AGING',
107 'DNS_RPC_ZONE_UPDATE_UNSECURE', 'DNS_RPC_ZONE_UPDATE_SECURE',
108 'DNS_RPC_ZONE_READONLY']
109 return bitmap_string(dnsserver, bitmap_defs, flags)
111 def ip4_array_string(array):
112 ret = []
113 if not array:
114 return ret
115 for i in xrange(array.AddrCount):
116 addr = '%s' % inet_ntoa(pack('i', array.AddrArray[i]))
117 ret.append(addr)
118 return ret
120 def dns_addr_array_string(array):
121 ret = []
122 if not array:
123 return ret
124 for i in xrange(array.AddrCount):
125 if array.AddrArray[i].MaxSa[0] == 0x02:
126 addr = '%d.%d.%d.%d (%d)' % \
127 tuple(array.AddrArray[i].MaxSa[4:8] + [array.AddrArray[i].MaxSa[3]])
128 elif array.AddrArray[i].MaxSa[0] == 0x17:
129 addr = '%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x (%d)' % \
130 tuple(array.AddrArray[i].MaxSa[4:20] + [array.AddrArray[i].MaxSa[3]])
131 else:
132 addr = 'UNKNOWN'
133 ret.append(addr)
134 return ret
136 def dns_type_flag(rec_type):
137 rtype = rec_type.upper()
138 if rtype == 'A':
139 record_type = dnsp.DNS_TYPE_A
140 elif rtype == 'AAAA':
141 record_type = dnsp.DNS_TYPE_AAAA
142 elif rtype == 'PTR':
143 record_type = dnsp.DNS_TYPE_PTR
144 elif rtype == 'NS':
145 record_type = dnsp.DNS_TYPE_NS
146 elif rtype == 'CNAME':
147 record_type = dnsp.DNS_TYPE_CNAME
148 elif rtype == 'SOA':
149 record_type = dnsp.DNS_TYPE_SOA
150 elif rtype == 'MX':
151 record_type = dnsp.DNS_TYPE_MX
152 elif rtype == 'SRV':
153 record_type = dnsp.DNS_TYPE_SRV
154 elif rtype == 'ALL':
155 record_type = dnsp.DNS_TYPE_ALL
156 else:
157 raise CommandError('Unknown type of DNS record %s' % rec_type)
158 return record_type
160 def dns_client_version(cli_version):
161 version = cli_version.upper()
162 if version == 'W2K':
163 client_version = dnsserver.DNS_CLIENT_VERSION_W2K
164 elif version == 'DOTNET':
165 client_version = dnsserver.DNS_CLIENT_VERSION_DOTNET
166 elif version == 'LONGHORN':
167 client_version = dnsserver.DNS_CLIENT_VERSION_LONGHORN
168 else:
169 raise CommandError('Unknown client version %s' % cli_version)
170 return client_version
172 def print_serverinfo(outf, typeid, serverinfo):
173 outf.write(' dwVersion : 0x%x\n' % serverinfo.dwVersion)
174 outf.write(' fBootMethod : %s\n' % boot_method_string(serverinfo.fBootMethod))
175 outf.write(' fAdminConfigured : %s\n' % bool_string(serverinfo.fAdminConfigured))
176 outf.write(' fAllowUpdate : %s\n' % bool_string(serverinfo.fAllowUpdate))
177 outf.write(' fDsAvailable : %s\n' % bool_string(serverinfo.fDsAvailable))
178 outf.write(' pszServerName : %s\n' % serverinfo.pszServerName)
179 outf.write(' pszDsContainer : %s\n' % serverinfo.pszDsContainer)
181 if typeid != dnsserver.DNSSRV_TYPEID_SERVER_INFO:
182 outf.write(' aipServerAddrs : %s\n' %
183 ip4_array_string(serverinfo.aipServerAddrs))
184 outf.write(' aipListenAddrs : %s\n' %
185 ip4_array_string(serverinfo.aipListenAddrs))
186 outf.write(' aipForwarders : %s\n' %
187 ip4_array_string(serverinfo.aipForwarders))
188 else:
189 outf.write(' aipServerAddrs : %s\n' %
190 dns_addr_array_string(serverinfo.aipServerAddrs))
191 outf.write(' aipListenAddrs : %s\n' %
192 dns_addr_array_string(serverinfo.aipListenAddrs))
193 outf.write(' aipForwarders : %s\n' %
194 dns_addr_array_string(serverinfo.aipForwarders))
196 outf.write(' dwLogLevel : %d\n' % serverinfo.dwLogLevel)
197 outf.write(' dwDebugLevel : %d\n' % serverinfo.dwDebugLevel)
198 outf.write(' dwForwardTimeout : %d\n' % serverinfo.dwForwardTimeout)
199 outf.write(' dwRpcPrototol : 0x%x\n' % serverinfo.dwRpcProtocol)
200 outf.write(' dwNameCheckFlag : %s\n' % name_check_flag_string(serverinfo.dwNameCheckFlag))
201 outf.write(' cAddressAnswerLimit : %d\n' % serverinfo.cAddressAnswerLimit)
202 outf.write(' dwRecursionRetry : %d\n' % serverinfo.dwRecursionRetry)
203 outf.write(' dwRecursionTimeout : %d\n' % serverinfo.dwRecursionTimeout)
204 outf.write(' dwMaxCacheTtl : %d\n' % serverinfo.dwMaxCacheTtl)
205 outf.write(' dwDsPollingInterval : %d\n' % serverinfo.dwDsPollingInterval)
206 outf.write(' dwScavengingInterval : %d\n' % serverinfo.dwScavengingInterval)
207 outf.write(' dwDefaultRefreshInterval : %d\n' % serverinfo.dwDefaultRefreshInterval)
208 outf.write(' dwDefaultNoRefreshInterval : %d\n' % serverinfo.dwDefaultNoRefreshInterval)
209 outf.write(' fAutoReverseZones : %s\n' % bool_string(serverinfo.fAutoReverseZones))
210 outf.write(' fAutoCacheUpdate : %s\n' % bool_string(serverinfo.fAutoCacheUpdate))
211 outf.write(' fRecurseAfterForwarding : %s\n' % bool_string(serverinfo.fRecurseAfterForwarding))
212 outf.write(' fForwardDelegations : %s\n' % bool_string(serverinfo.fForwardDelegations))
213 outf.write(' fNoRecursion : %s\n' % bool_string(serverinfo.fNoRecursion))
214 outf.write(' fSecureResponses : %s\n' % bool_string(serverinfo.fSecureResponses))
215 outf.write(' fRoundRobin : %s\n' % bool_string(serverinfo.fRoundRobin))
216 outf.write(' fLocalNetPriority : %s\n' % bool_string(serverinfo.fLocalNetPriority))
217 outf.write(' fBindSecondaries : %s\n' % bool_string(serverinfo.fBindSecondaries))
218 outf.write(' fWriteAuthorityNs : %s\n' % bool_string(serverinfo.fWriteAuthorityNs))
219 outf.write(' fStrictFileParsing : %s\n' % bool_string(serverinfo.fStrictFileParsing))
220 outf.write(' fLooseWildcarding : %s\n' % bool_string(serverinfo.fLooseWildcarding))
221 outf.write(' fDefaultAgingState : %s\n' % bool_string(serverinfo.fDefaultAgingState))
223 if typeid != dnsserver.DNSSRV_TYPEID_SERVER_INFO_W2K:
224 outf.write(' dwRpcStructureVersion : 0x%x\n' % serverinfo.dwRpcStructureVersion)
225 outf.write(' aipLogFilter : %s\n' % dns_addr_array_string(serverinfo.aipLogFilter))
226 outf.write(' pwszLogFilePath : %s\n' % serverinfo.pwszLogFilePath)
227 outf.write(' pszDomainName : %s\n' % serverinfo.pszDomainName)
228 outf.write(' pszForestName : %s\n' % serverinfo.pszForestName)
229 outf.write(' pszDomainDirectoryPartition : %s\n' % serverinfo.pszDomainDirectoryPartition)
230 outf.write(' pszForestDirectoryPartition : %s\n' % serverinfo.pszForestDirectoryPartition)
232 outf.write(' dwLocalNetPriorityNetMask : 0x%x\n' % serverinfo.dwLocalNetPriorityNetMask)
233 outf.write(' dwLastScavengeTime : %d\n' % serverinfo.dwLastScavengeTime)
234 outf.write(' dwEventLogLevel : %d\n' % serverinfo.dwEventLogLevel)
235 outf.write(' dwLogFileMaxSize : %d\n' % serverinfo.dwLogFileMaxSize)
236 outf.write(' dwDsForestVersion : %d\n' % serverinfo.dwDsForestVersion)
237 outf.write(' dwDsDomainVersion : %d\n' % serverinfo.dwDsDomainVersion)
238 outf.write(' dwDsDsaVersion : %d\n' % serverinfo.dwDsDsaVersion)
240 if typeid == dnsserver.DNSSRV_TYPEID_SERVER_INFO:
241 outf.write(' fReadOnlyDC : %s\n' % bool_string(serverinfo.fReadOnlyDC))
244 def print_zoneinfo(outf, typeid, zoneinfo):
245 outf.write(' pszZoneName : %s\n' % zoneinfo.pszZoneName)
246 outf.write(' dwZoneType : %s\n' % zone_type_string(zoneinfo.dwZoneType))
247 outf.write(' fReverse : %s\n' % bool_string(zoneinfo.fReverse))
248 outf.write(' fAllowUpdate : %s\n' % zone_update_string(zoneinfo.fAllowUpdate))
249 outf.write(' fPaused : %s\n' % bool_string(zoneinfo.fPaused))
250 outf.write(' fShutdown : %s\n' % bool_string(zoneinfo.fShutdown))
251 outf.write(' fAutoCreated : %s\n' % bool_string(zoneinfo.fAutoCreated))
252 outf.write(' fUseDatabase : %s\n' % bool_string(zoneinfo.fUseDatabase))
253 outf.write(' pszDataFile : %s\n' % zoneinfo.pszDataFile)
254 if typeid != dnsserver.DNSSRV_TYPEID_ZONE_INFO:
255 outf.write(' aipMasters : %s\n' %
256 ip4_array_string(zoneinfo.aipMasters))
257 else:
258 outf.write(' aipMasters : %s\n' %
259 dns_addr_array_string(zoneinfo.aipMasters))
260 outf.write(' fSecureSecondaries : %s\n' % zone_secondary_security_string(zoneinfo.fSecureSecondaries))
261 outf.write(' fNotifyLevel : %s\n' % zone_notify_level_string(zoneinfo.fNotifyLevel))
262 if typeid != dnsserver.DNSSRV_TYPEID_ZONE_INFO:
263 outf.write(' aipSecondaries : %s\n' %
264 ip4_array_string(zoneinfo.aipSecondaries))
265 outf.write(' aipNotify : %s\n' %
266 ip4_array_string(zoneinfo.aipNotify))
267 else:
268 outf.write(' aipSecondaries : %s\n' %
269 dns_addr_array_string(zoneinfo.aipSecondaries))
270 outf.write(' aipNotify : %s\n' %
271 dns_addr_array_string(zoneinfo.aipNotify))
272 outf.write(' fUseWins : %s\n' % bool_string(zoneinfo.fUseWins))
273 outf.write(' fUseNbstat : %s\n' % bool_string(zoneinfo.fUseNbstat))
274 outf.write(' fAging : %s\n' % bool_string(zoneinfo.fAging))
275 outf.write(' dwNoRefreshInterval : %d\n' % zoneinfo.dwNoRefreshInterval)
276 outf.write(' dwRefreshInterval : %d\n' % zoneinfo.dwRefreshInterval)
277 outf.write(' dwAvailForScavengeTime : %d\n' % zoneinfo.dwAvailForScavengeTime)
278 if typeid != dnsserver.DNSSRV_TYPEID_ZONE_INFO:
279 outf.write(' aipScavengeServers : %s\n' %
280 ip4_array_string(zoneinfo.aipScavengeServers))
281 else:
282 outf.write(' aipScavengeServers : %s\n' %
283 dns_addr_array_string(zoneinfo.aipScavengeServers))
285 if typeid != dnsserver.DNSSRV_TYPEID_ZONE_INFO_W2K:
286 outf.write(' dwRpcStructureVersion : 0x%x\n' % zoneinfo.dwRpcStructureVersion)
287 outf.write(' dwForwarderTimeout : %d\n' % zoneinfo.dwForwarderTimeout)
288 outf.write(' fForwarderSlave : %d\n' % zoneinfo.fForwarderSlave)
289 if typeid != dnsserver.DNSSRV_TYPEID_ZONE_INFO:
290 outf.write(' aipLocalMasters : %s\n' %
291 ip4_array_string(zoneinfo.aipLocalMasters))
292 else:
293 outf.write(' aipLocalMasters : %s\n' %
294 dns_addr_array_string(zoneinfo.aipLocalMasters))
295 outf.write(' dwDpFlags : %s\n' % dp_flags_string(zoneinfo.dwDpFlags))
296 outf.write(' pszDpFqdn : %s\n' % zoneinfo.pszDpFqdn)
297 outf.write(' pwszZoneDn : %s\n' % zoneinfo.pwszZoneDn)
298 outf.write(' dwLastSuccessfulSoaCheck : %d\n' % zoneinfo.dwLastSuccessfulSoaCheck)
299 outf.write(' dwLastSuccessfulXfr : %d\n' % zoneinfo.dwLastSuccessfulXfr)
301 if typeid == dnsserver.DNSSRV_TYPEID_ZONE_INFO:
302 outf.write(' fQueuedForBackgroundLoad : %s\n' % bool_string(zoneinfo.fQueuedForBackgroundLoad))
303 outf.write(' fBackgroundLoadInProgress : %s\n' % bool_string(zoneinfo.fBackgroundLoadInProgress))
304 outf.write(' fReadOnlyZone : %s\n' % bool_string(zoneinfo.fReadOnlyZone))
305 outf.write(' dwLastXfrAttempt : %d\n' % zoneinfo.dwLastXfrAttempt)
306 outf.write(' dwLastXfrResult : %d\n' % zoneinfo.dwLastXfrResult)
309 def print_zone(outf, typeid, zone):
310 outf.write(' pszZoneName : %s\n' % zone.pszZoneName)
311 outf.write(' Flags : %s\n' % zone_flags_string(zone.Flags))
312 outf.write(' ZoneType : %s\n' % zone_type_string(zone.ZoneType))
313 outf.write(' Version : %s\n' % zone.Version)
315 if typeid != dnsserver.DNSSRV_TYPEID_ZONE_W2K:
316 outf.write(' dwDpFlags : %s\n' % dp_flags_string(zone.dwDpFlags))
317 outf.write(' pszDpFqdn : %s\n' % zone.pszDpFqdn)
320 def print_enumzones(outf, typeid, zones):
321 outf.write(' %d zone(s) found\n' % zones.dwZoneCount)
322 for zone in zones.ZoneArray:
323 outf.write('\n')
324 print_zone(outf, typeid, zone)
327 def print_dns_record(outf, rec):
328 mesg = 'Unknown: '
329 if rec.wType == dnsp.DNS_TYPE_A:
330 mesg = 'A: %s' % (rec.data)
331 elif rec.wType == dnsp.DNS_TYPE_AAAA:
332 mesg = 'AAAA: %s' % (rec.data)
333 elif rec.wType == dnsp.DNS_TYPE_PTR:
334 mesg = 'PTR: %s' % (rec.data.str)
335 elif rec.wType == dnsp.DNS_TYPE_NS:
336 mesg = 'NS: %s' % (rec.data.str)
337 elif rec.wType == dnsp.DNS_TYPE_CNAME:
338 mesg = 'CNAME: %s' % (rec.data.str)
339 elif rec.wType == dnsp.DNS_TYPE_SOA:
340 mesg = 'SOA: serial=%d, refresh=%d, retry=%d, expire=%d, ns=%s, email=%s' % (
341 rec.data.dwSerialNo,
342 rec.data.dwRefresh,
343 rec.data.dwRetry,
344 rec.data.dwExpire,
345 rec.data.NamePrimaryServer.str,
346 rec.data.ZoneAdministratorEmail.str)
347 elif rec.wType == dnsp.DNS_TYPE_MX:
348 mesg = 'MX: %s' % (rec.data.str)
349 elif rec.wType == dnsp.DNS_TYPE_SRV:
350 mesg = 'SRV: %s (%d)' % (rec.data.nameTarget.str, rec.data.wPort)
351 outf.write(' %s (flags=%x, serial=%d, ttl=%d)\n' % (
352 mesg, rec.dwFlags, rec.dwSerial, rec.dwTtlSeconds))
355 def print_dnsrecords(outf, records):
356 for rec in records.rec:
357 outf.write(' Name=%s, Records=%d, Children=%d\n' % (
358 rec.dnsNodeName.str,
359 rec.wRecordCount,
360 rec.dwChildCount))
361 for dns_rec in rec.records:
362 print_dns_record(outf, dns_rec)
365 class ARecord(dnsserver.DNS_RPC_RECORD):
366 def __init__(self, ip_addr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
367 node_flag=0):
368 super(ARecord, self).__init__()
369 self.wType = dnsp.DNS_TYPE_A
370 self.dwFlags = rank | node_flag
371 self.dwSerial = serial
372 self.dwTtlSeconds = ttl
373 self.data = ip_addr
375 class AAAARecord(dnsserver.DNS_RPC_RECORD):
376 def __init__(self, ip6_addr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
377 node_flag=0):
378 super(AAAARecord, self).__init__()
379 self.wType = dnsp.DNS_TYPE_AAAA
380 self.dwFlags = rank | node_flag
381 self.dwSerial = serial
382 self.dwTtlSeconds = ttl
383 self.data = ip6_addr
385 class PTRRecord(dnsserver.DNS_RPC_RECORD):
386 def __init__(self, ptr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
387 node_flag=0):
388 super(PTRRecord, self).__init__()
389 self.wType = dnsp.DNS_TYPE_PTR
390 self.dwFlags = rank | node_flag
391 self.dwSerial = serial
392 self.dwTtleSeconds = ttl
393 ptr_name = dnsserver.DNS_RPC_NAME()
394 ptr_name.str = ptr
395 ptr_name.len = len(ptr)
396 self.data = ptr_name
398 class CNameRecord(dnsserver.DNS_RPC_RECORD):
399 def __init__(self, cname, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
400 node_flag=0):
401 super(CNameRecord, self).__init__()
402 self.wType = dnsp.DNS_TYPE_CNAME
403 self.dwFlags = rank | node_flag
404 self.dwSerial = serial
405 self.dwTtlSeconds = ttl
406 cname_name = dnsserver.DNS_RPC_NAME()
407 cname_name.str = cname
408 cname_name.len = len(cname)
409 self.data = cname_name
411 class NSRecord(dnsserver.DNS_RPC_RECORD):
412 def __init__(self, dns_server, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
413 node_flag=0):
414 super(NSRecord, self).__init__()
415 self.wType = dnsp.DNS_TYPE_NS
416 self.dwFlags = rank | node_flag
417 self.dwSerial = serial
418 self.dwTtlSeconds = ttl
419 ns = dnsserver.DNS_RPC_NAME()
420 ns.str = dns_server
421 ns.len = len(dns_server)
422 self.data = ns
424 class MXRecord(dnsserver.DNS_RPC_RECORD):
425 def __init__(self, mail_server, preference, serial=1, ttl=900,
426 rank=dnsp.DNS_RANK_ZONE, node_flag=0):
427 super(MXRecord, self).__init__()
428 self.wType = dnsp.DNS_TYPE_MX
429 self.dwFlags = rank | node_flag
430 self.dwSerial = serial
431 self.dwTtlSeconds = ttl
432 mx = dnsserver.DNS_RPC_RECORD_NAME_PREFERENCE()
433 mx.wPreference = preference
434 mx.nameExchange.str = mail_server
435 mx.nameExchange.len = len(mail_server)
436 self.data = mx
438 class SOARecord(dnsserver.DNS_RPC_RECORD):
439 def __init__(self, mname, rname, serial=1, refresh=900, retry=600,
440 expire=86400, minimum=3600, ttl=3600, rank=dnsp.DNS_RANK_ZONE,
441 node_flag=dnsp.DNS_RPC_FLAG_AUTH_ZONE_ROOT):
442 super(SOARecord, self).__init__()
443 self.wType = dnsp.DNS_TYPE_SOA
444 self.dwFlags = rank | node_flag
445 self.dwSerial = serial
446 self.dwTtlSeconds = ttl
447 soa = dnsserver.DNS_RPC_RECORD_SOA()
448 soa.dwSerialNo = serial
449 soa.dwRefresh = refresh
450 soa.dwRetry = retry
451 soa.dwExpire = expire
452 soa.NamePrimaryServer.str = mname
453 soa.NamePrimaryServer.len = len(mname)
454 soa.ZoneAdministratorEmail.str = rname
455 soa.ZoneAdministratorEmail.len = len(rname)
456 self.data = soa
458 class SRVRecord(dnsserver.DNS_RPC_RECORD):
459 def __init__(self, target, port, priority=0, weight=100, serial=1, ttl=900,
460 rank=dnsp.DNS_RANK_ZONE, node_flag=0):
461 super(SRVRecord, self).__init__()
462 self.wType = dnsp.DNS_TYPE_SRV
463 self.dwFlags = rank | node_flag
464 self.dwSerial = serial
465 self.dwTtlSeconds = ttl
466 srv = dnsserver.DNS_RPC_RECORD_SRV()
467 srv.wPriority = priority
468 srv.wWeight = weight
469 srv.wPort = port
470 srv.nameTarget.str = target
471 srv.nameTarget.len = len(target)
472 self.data = srv
475 # Convert data into a dns record
476 def data_to_dns_record(record_type, data):
477 if record_type == dnsp.DNS_TYPE_A:
478 rec = ARecord(data)
479 elif record_type == dnsp.DNS_TYPE_AAAA:
480 rec = AAAARecord(data)
481 elif record_type == dnsp.DNS_TYPE_PTR:
482 rec = PTRRecord(data)
483 elif record_type == dnsp.DNS_TYPE_CNAME:
484 rec = CNameRecord(data)
485 elif record_type == dnsp.DNS_TYPE_NS:
486 rec = NSRecord(data)
487 elif record_type == dnsp.DNS_TYPE_MX:
488 tmp = data.split(' ')
489 if len(tmp) != 2:
490 raise CommandError('Data requires 2 elements - mail_server, preference')
491 mail_server = tmp[0]
492 preference = int(tmp[1])
493 rec = MXRecord(mail_server, preference)
494 elif record_type == dnsp.DNS_TYPE_SRV:
495 tmp = data.split(' ')
496 if len(tmp) != 4:
497 raise CommandError('Data requires 4 elements - server, port, priority, weight')
498 server = tmp[0]
499 port = int(tmp[1])
500 priority = int(tmp[2])
501 weight = int(tmp[3])
502 rec = SRVRecord(server, port, priority=priority, weight=weight)
503 elif record_type == dnsp.DNS_TYPE_SOA:
504 tmp = data.split(' ')
505 if len(tmp) != 7:
506 raise CommandError('Data requires 7 elements - nameserver, email, serial, '
507 'refresh, retry, expire, minimumttl')
508 nameserver = tmp[0]
509 email = tmp[1]
510 serial = int(tmp[2])
511 refresh = int(tmp[3])
512 retry = int(tmp[4])
513 expire = int(tmp[5])
514 minimum = int(tmp[6])
515 rec = SOARecord(nameserver, email, serial=serial, refresh=refresh,
516 retry=retry, expire=expire, minimum=minimum)
517 else:
518 raise CommandError('Unsupported record type')
519 return rec
522 # Match dns name (of type DNS_RPC_NAME)
523 def dns_name_equal(n1, n2):
524 return n1.str.rstrip('.').lower() == n2.str.rstrip('.').lower()
527 # Match a dns record with specified data
528 def dns_record_match(dns_conn, server, zone, name, record_type, data):
529 urec = data_to_dns_record(record_type, data)
531 select_flags = dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA
533 try:
534 buflen, res = dns_conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
536 server,
537 zone,
538 name,
539 None,
540 record_type,
541 select_flags,
542 None,
543 None)
544 except RuntimeError, e:
545 return None
547 if not res or res.count == 0:
548 return None
550 rec_match = None
551 for rec in res.rec[0].records:
552 if rec.wType != record_type:
553 continue
555 found = False
556 if record_type == dnsp.DNS_TYPE_A:
557 if rec.data == urec.data:
558 found = True
559 elif record_type == dnsp.DNS_TYPE_AAAA:
560 if rec.data == urec.data:
561 found = True
562 elif record_type == dnsp.DNS_TYPE_PTR:
563 if dns_name_equal(rec.data, urec.data):
564 found = True
565 elif record_type == dnsp.DNS_TYPE_CNAME:
566 if dns_name_equal(rec.data, urec.data):
567 found = True
568 elif record_type == dnsp.DNS_TYPE_NS:
569 if dns_name_equal(rec.data, urec.data):
570 found = True
571 elif record_type == dnsp.DNS_TYPE_MX:
572 if dns_name_equal(rec.data.nameExchange, urec.data.nameExchange) and \
573 rec.data.wPreference == urec.data.wPreference:
574 found = True
575 elif record_type == dnsp.DNS_TYPE_SRV:
576 if rec.data.wPriority == urec.data.wPriority and \
577 rec.data.wWeight == urec.data.wWeight and \
578 rec.data.wPort == urec.data.wPort and \
579 dns_name_equal(rec.data.nameTarget, urec.data.nameTarget):
580 found = True
581 elif record_type == dnsp.DNS_TYPE_SOA:
582 if rec.data.dwSerialNo == urec.data.dwSerialNo and \
583 rec.data.dwRefresh == urec.data.dwRefresh and \
584 rec.data.dwRetry == urec.data.dwRetry and \
585 rec.data.dwExpire == urec.data.dwExpire and \
586 rec.data.dwMinimumTtl == urec.data.dwMinimumTtl and \
587 dns_name_equal(rec.data.NamePrimaryServer,
588 urec.data.NamePrimaryServer) and \
589 dns_name_equal(rec.data.ZoneAdministratorEmail,
590 urec.data.ZoneAdministratorEmail):
591 found = True
592 if found:
593 rec_match = rec
594 break
596 return rec_match
599 class cmd_serverinfo(Command):
600 """Query for Server information"""
602 synopsis = '%prog <server> [options]'
604 takes_args = [ 'server' ]
606 takes_optiongroups = {
607 "sambaopts": options.SambaOptions,
608 "versionopts": options.VersionOptions,
609 "credopts": options.CredentialsOptions,
612 takes_options = [
613 Option('--client-version', help='Client Version',
614 default='longhorn', metavar='w2k|dotnet|longhorn',
615 choices=['w2k','dotnet','longhorn'], dest='cli_ver'),
618 def run(self, server, cli_ver, sambaopts=None, credopts=None, versionopts=None):
619 self.lp = sambaopts.get_loadparm()
620 self.creds = credopts.get_credentials(self.lp)
621 dns_conn = dns_connect(server, self.lp, self.creds)
623 client_version = dns_client_version(cli_ver)
625 typeid, res = dns_conn.DnssrvQuery2(client_version,
627 server,
628 None,
629 'ServerInfo')
630 print_serverinfo(self.outf, typeid, res)
633 class cmd_zoneinfo(Command):
634 """Query for zone information"""
636 synopsis = '%prog <server> <zone> [options]'
638 takes_args = [ 'server', 'zone' ]
640 takes_optiongroups = {
641 "sambaopts": options.SambaOptions,
642 "versionopts": options.VersionOptions,
643 "credopts": options.CredentialsOptions,
646 takes_options = [
647 Option('--client-version', help='Client Version',
648 default='longhorn', metavar='w2k|dotnet|longhorn',
649 choices=['w2k','dotnet','longhorn'], dest='cli_ver'),
652 def run(self, server, zone, cli_ver, sambaopts=None, credopts=None, versionopts=None):
653 self.lp = sambaopts.get_loadparm()
654 self.creds = credopts.get_credentials(self.lp)
655 dns_conn = dns_connect(server, self.lp, self.creds)
657 client_version = dns_client_version(cli_ver)
659 typeid, res = dns_conn.DnssrvQuery2(client_version,
661 server,
662 zone,
663 'ZoneInfo')
664 print_zoneinfo(self.outf, typeid, res)
667 class cmd_zonelist(Command):
668 """Query for zones"""
670 synopsis = '%prog <server> [options]'
672 takes_args = [ 'server' ]
674 takes_optiongroups = {
675 "sambaopts": options.SambaOptions,
676 "versionopts": options.VersionOptions,
677 "credopts": options.CredentialsOptions,
680 takes_options = [
681 Option('--client-version', help='Client Version',
682 default='longhorn', metavar='w2k|dotnet|longhorn',
683 choices=['w2k','dotnet','longhorn'], dest='cli_ver'),
684 Option('--primary', help='List primary zones (default)',
685 action='store_true', dest='primary'),
686 Option('--secondary', help='List secondary zones',
687 action='store_true', dest='secondary'),
688 Option('--cache', help='List cached zones',
689 action='store_true', dest='cache'),
690 Option('--auto', help='List automatically created zones',
691 action='store_true', dest='auto'),
692 Option('--forward', help='List forward zones',
693 action='store_true', dest='forward'),
694 Option('--reverse', help='List reverse zones',
695 action='store_true', dest='reverse'),
696 Option('--ds', help='List directory integrated zones',
697 action='store_true', dest='ds'),
698 Option('--non-ds', help='List non-directory zones',
699 action='store_true', dest='nonds')
702 def run(self, server, cli_ver, primary=False, secondary=False, cache=False,
703 auto=False, forward=False, reverse=False, ds=False, nonds=False,
704 sambaopts=None, credopts=None, versionopts=None):
705 request_filter = 0
707 if primary:
708 request_filter |= dnsserver.DNS_ZONE_REQUEST_PRIMARY
709 if secondary:
710 request_filter |= dnsserver.DNS_ZONE_REQUEST_SECONDARY
711 if cache:
712 request_filter |= dnsserver.DNS_ZONE_REQUEST_CACHE
713 if auto:
714 request_filter |= dnsserver.DNS_ZONE_REQUEST_AUTO
715 if forward:
716 request_filter |= dnsserver.DNS_ZONE_REQUEST_FORWARD
717 if reverse:
718 request_filter |= dnsserver.DNS_ZONE_REQUEST_REVERSE
719 if ds:
720 request_filter |= dnsserver.DNS_ZONE_REQUEST_DS
721 if nonds:
722 request_filter |= dnsserver.DNS_ZONE_REQUEST_NON_DS
724 if request_filter == 0:
725 request_filter = dnsserver.DNS_ZONE_REQUEST_PRIMARY
727 self.lp = sambaopts.get_loadparm()
728 self.creds = credopts.get_credentials(self.lp)
729 dns_conn = dns_connect(server, self.lp, self.creds)
731 client_version = dns_client_version(cli_ver)
733 typeid, res = dns_conn.DnssrvComplexOperation2(client_version,
735 server,
736 None,
737 'EnumZones',
738 dnsserver.DNSSRV_TYPEID_DWORD,
739 request_filter)
741 if client_version == dnsserver.DNS_CLIENT_VERSION_W2K:
742 typeid = dnsserver.DNSSRV_TYPEID_ZONE_W2K
743 else:
744 typeid = dnsserver.DNSSRV_TYPEID_ZONE
745 print_enumzones(self.outf, typeid, res)
748 class cmd_zonecreate(Command):
749 """Create a zone"""
751 synopsis = '%prog <server> <zone> [options]'
753 takes_args = [ 'server', 'zone' ]
755 takes_optiongroups = {
756 "sambaopts": options.SambaOptions,
757 "versionopts": options.VersionOptions,
758 "credopts": options.CredentialsOptions,
761 takes_options = [
762 Option('--client-version', help='Client Version',
763 default='longhorn', metavar='w2k|dotnet|longhorn',
764 choices=['w2k','dotnet','longhorn'], dest='cli_ver')
767 def run(self, server, zone, cli_ver, sambaopts=None, credopts=None,
768 versionopts=None):
770 self.lp = sambaopts.get_loadparm()
771 self.creds = credopts.get_credentials(self.lp)
772 dns_conn = dns_connect(server, self.lp, self.creds)
774 zone = zone.lower()
776 client_version = dns_client_version(cli_ver)
777 if client_version == dnsserver.DNS_CLIENT_VERSION_W2K:
778 typeid = dnsserver.DNSSRV_TYPEID_ZONE_CREATE_W2K
779 zone_create_info = dnsserver.DNS_RPC_ZONE_CREATE_INFO_W2K()
780 zone_create_info.pszZoneName = zone
781 zone_create_info.dwZoneType = dnsp.DNS_ZONE_TYPE_PRIMARY
782 zone_create_info.fAllowUpdate = dnsp.DNS_ZONE_UPDATE_SECURE
783 zone_create_info.fAging = 0
784 elif client_version == dnsserver.DNS_CLIENT_VERSION_DOTNET:
785 typeid = dnsserver.DNSSRV_TYPEID_ZONE_CREATE_DOTNET
786 zone_create_info = dnsserver.DNS_RPC_ZONE_CREATE_INFO_DOTNET()
787 zone_create_info.pszZoneName = zone
788 zone_create_info.dwZoneType = dnsp.DNS_ZONE_TYPE_PRIMARY
789 zone_create_info.fAllowUpdate = dnsp.DNS_ZONE_UPDATE_SECURE
790 zone_create_info.fAging = 0
791 zone_create_info.dwDpFlags = dnsserver.DNS_DP_DOMAIN_DEFAULT
792 else:
793 typeid = dnsserver.DNSSRV_TYPEID_ZONE_CREATE
794 zone_create_info = dnsserver.DNS_RPC_ZONE_CREATE_INFO_LONGHORN()
795 zone_create_info.pszZoneName = zone
796 zone_create_info.dwZoneType = dnsp.DNS_ZONE_TYPE_PRIMARY
797 zone_create_info.fAllowUpdate = dnsp.DNS_ZONE_UPDATE_SECURE
798 zone_create_info.fAging = 0
799 zone_create_info.dwDpFlags = dnsserver.DNS_DP_DOMAIN_DEFAULT
801 res = dns_conn.DnssrvOperation2(client_version,
803 server,
804 None,
806 'ZoneCreate',
807 typeid,
808 zone_create_info)
809 self.outf.write('Zone %s created successfully\n' % zone)
812 class cmd_zonedelete(Command):
813 """Delete a zone"""
815 synopsis = '%prog <server> <zone> [options]'
817 takes_args = [ 'server', 'zone' ]
819 takes_optiongroups = {
820 "sambaopts": options.SambaOptions,
821 "versionopts": options.VersionOptions,
822 "credopts": options.CredentialsOptions,
825 def run(self, server, zone, sambaopts=None, credopts=None, versionopts=None):
827 self.lp = sambaopts.get_loadparm()
828 self.creds = credopts.get_credentials(self.lp)
829 dns_conn = dns_connect(server, self.lp, self.creds)
831 zone = zone.lower()
832 res = dns_conn.DnssrvOperation2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
834 server,
835 zone,
837 'DeleteZoneFromDs',
838 dnsserver.DNSSRV_TYPEID_NULL,
839 None)
840 self.outf.write('Zone %s delete successfully\n' % zone)
843 class cmd_query(Command):
844 """Query a name."""
846 synopsis = '%prog <server> <zone> <name> <A|AAAA|CNAME|MX|NS|SOA|SRV|ALL> [options]'
848 takes_args = [ 'server', 'zone', 'name', 'rtype' ]
850 takes_optiongroups = {
851 "sambaopts": options.SambaOptions,
852 "versionopts": options.VersionOptions,
853 "credopts": options.CredentialsOptions,
856 takes_options = [
857 Option('--authority', help='Search authoritative records (default)',
858 action='store_true', dest='authority'),
859 Option('--cache', help='Search cached records',
860 action='store_true', dest='cache'),
861 Option('--glue', help='Search glue records',
862 action='store_true', dest='glue'),
863 Option('--root', help='Search root hints',
864 action='store_true', dest='root'),
865 Option('--additional', help='List additional records',
866 action='store_true', dest='additional'),
867 Option('--no-children', help='Do not list children',
868 action='store_true', dest='no_children'),
869 Option('--only-children', help='List only children',
870 action='store_true', dest='only_children')
873 def run(self, server, zone, name, rtype, authority=False, cache=False, glue=False,
874 root=False, additional=False, no_children=False, only_children=False,
875 sambaopts=None, credopts=None, versionopts=None):
876 record_type = dns_type_flag(rtype)
878 select_flags = 0
879 if authority:
880 select_flags |= dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA
881 if cache:
882 select_flags |= dnsserver.DNS_RPC_VIEW_CACHE_DATA
883 if glue:
884 select_flags |= dnsserver.DNS_RPC_VIEW_GLUE_DATA
885 if root:
886 select_flags |= dnsserver.DNS_RPC_VIEW_ROOT_HINT_DATA
887 if additional:
888 select_flags |= dnsserver.DNS_RPC_VIEW_ADDITIONAL_DATA
889 if no_children:
890 select_flags |= dnsserver.DNS_RPC_VIEW_NO_CHILDREN
891 if only_children:
892 select_flags |= dnsserver.DNS_RPC_VIEW_ONLY_CHILDREN
894 if select_flags == 0:
895 select_flags = dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA
897 if select_flags == dnsserver.DNS_RPC_VIEW_ADDITIONAL_DATA:
898 self.outf.write('Specify either --authority or --root along with --additional.\n')
899 self.outf.write('Assuming --authority.\n')
900 select_flags |= dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA
902 self.lp = sambaopts.get_loadparm()
903 self.creds = credopts.get_credentials(self.lp)
904 dns_conn = dns_connect(server, self.lp, self.creds)
906 buflen, res = dns_conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
908 server,
909 zone,
910 name,
911 None,
912 record_type,
913 select_flags,
914 None,
915 None)
916 print_dnsrecords(self.outf, res)
919 class cmd_roothints(Command):
920 """Query root hints"""
922 synopsis = '%prog <server> [<name>] [options]'
924 takes_args = [ 'server', 'name?' ]
926 takes_optiongroups = {
927 "sambaopts": options.SambaOptions,
928 "versionopts": options.VersionOptions,
929 "credopts": options.CredentialsOptions,
932 def run(self, server, name='.', sambaopts=None, credopts=None, versionopts=None):
933 record_type = dnsp.DNS_TYPE_NS
934 select_flags = (dnsserver.DNS_RPC_VIEW_ROOT_HINT_DATA |
935 dnsserver.DNS_RPC_VIEW_ADDITIONAL_DATA)
937 self.lp = sambaopts.get_loadparm()
938 self.creds = credopts.get_credentials(self.lp)
939 dns_conn = dns_connect(server, self.lp, self.creds)
941 buflen, res = dns_conn.DnssrvEnumRecords2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
943 server,
944 '..RootHints',
945 name,
946 None,
947 record_type,
948 select_flags,
949 None,
950 None)
951 print_dnsrecords(self.outf, res)
954 class cmd_add_record(Command):
955 """Add a DNS record"""
957 synopsis = '%prog <server> <zone> <name> <A|AAAA|PTR|CNAME|NS> <data>'
959 takes_args = [ 'server', 'zone', 'name', 'rtype', 'data' ]
961 takes_optiongroups = {
962 "sambaopts": options.SambaOptions,
963 "versionopts": options.VersionOptions,
964 "credopts": options.CredentialsOptions,
967 def run(self, server, zone, name, rtype, data, sambaopts=None, credopts=None, versionopts=None):
969 record_type = dns_type_flag(rtype)
971 if record_type == dnsp.DNS_TYPE_A:
972 rec = ARecord(data)
973 elif record_type == dnsp.DNS_TYPE_AAAA:
974 rec = AAAARecord(data)
975 elif record_type == dnsp.DNS_TYPE_PTR:
976 rec = PTRRecord(data)
977 elif record_type == dnsp.DNS_TYPE_CNAME:
978 rec = CNameRecord(data)
979 elif record_type == dnsp.DNS_TYPE_NS:
980 rec = NSRecord(data)
981 else:
982 raise CommandError('Adding record of type %s is not supported' % rtype)
984 self.lp = sambaopts.get_loadparm()
985 self.creds = credopts.get_credentials(self.lp)
986 dns_conn = dns_connect(server, self.lp, self.creds)
988 rec_match = dns_record_match(dns_conn, server, zone, name, record_type, data)
989 if rec_match is not None:
990 raise CommandError('Record already exists')
992 add_rec_buf = dnsserver.DNS_RPC_RECORD_BUF()
993 add_rec_buf.rec = rec
995 dns_conn.DnssrvUpdateRecord2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
997 server,
998 zone,
999 name,
1000 add_rec_buf,
1001 None)
1002 self.outf.write('Record added successfully\n')
1005 class cmd_update_record(Command):
1006 """Update a DNS record"""
1008 synopsis = '%prog <server> <zone> <name> <A|AAAA|PTR|CNAME|NS> <olddata> <newdata>'
1010 takes_args = [ 'server', 'zone', 'name', 'rtype', 'olddata', 'newdata' ]
1012 takes_optiongroups = {
1013 "sambaopts": options.SambaOptions,
1014 "versionopts": options.VersionOptions,
1015 "credopts": options.CredentialsOptions,
1018 def run(self, server, zone, name, rtype, olddata, newdata,
1019 sambaopts=None, credopts=None, versionopts=None):
1021 record_type = dns_type_flag(rtype)
1022 if record_type == dnsp.DNS_TYPE_A:
1023 rec = ARecord(newdata)
1024 elif record_type == dnsp.DNS_TYPE_AAAA:
1025 rec = AAAARecord(newdata)
1026 elif record_type == dnsp.DNS_TYPE_PTR:
1027 rec = PTRRecord(newdata)
1028 elif record_type == dnsp.DNS_TYPE_CNAME:
1029 rec = CNameRecord(newdata)
1030 elif record_type == dnsp.DNS_TYPE_NS:
1031 rec = NSRecord(newdata)
1032 else:
1033 raise CommandError('Updating record of type %s is not supported' % rtype)
1035 self.lp = sambaopts.get_loadparm()
1036 self.creds = credopts.get_credentials(self.lp)
1037 dns_conn = dns_connect(server, self.lp, self.creds)
1039 rec_match = dns_record_match(dns_conn, server, zone, name, record_type, olddata)
1040 if not rec_match:
1041 raise CommandError('Record does not exist')
1043 # Copy properties from existing record to new record
1044 rec.dwFlags = rec_match.dwFlags
1045 rec.dwSerial = rec_match.dwSerial
1046 rec.dwTtlSeconds = rec_match.dwTtlSeconds
1047 rec.dwTimeStamp = rec_match.dwTimeStamp
1049 add_rec_buf = dnsserver.DNS_RPC_RECORD_BUF()
1050 add_rec_buf.rec = rec
1052 del_rec_buf = dnsserver.DNS_RPC_RECORD_BUF()
1053 del_rec_buf.rec = rec_match
1055 dns_conn.DnssrvUpdateRecord2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
1057 server,
1058 zone,
1059 name,
1060 add_rec_buf,
1061 del_rec_buf)
1062 self.outf.write('Record updated succefully\n')
1065 class cmd_delete_record(Command):
1066 """Delete a DNS record"""
1068 synopsis = '%prog <server> <zone> <name> <A|AAAA|PTR|CNAME|NS> <data>'
1070 takes_args = [ 'server', 'zone', 'name', 'rtype', 'data' ]
1072 takes_optiongroups = {
1073 "sambaopts": options.SambaOptions,
1074 "versionopts": options.VersionOptions,
1075 "credopts": options.CredentialsOptions,
1078 def run(self, server, zone, name, rtype, data, sambaopts=None, credopts=None, versionopts=None):
1080 record_type = dns_type_flag(rtype)
1082 if record_type == dnsp.DNS_TYPE_A:
1083 rec = ARecord(data)
1084 elif record_type == dnsp.DNS_TYPE_AAAA:
1085 rec = AAAARecord(data)
1086 elif record_type == dnsp.DNS_TYPE_PTR:
1087 rec = PTRRecord(data)
1088 elif record_type == dnsp.DNS_TYPE_CNAME:
1089 rec = CNameRecord(data)
1090 elif record_type == dnsp.DNS_TYPE_NS:
1091 rec = NSRecord(data)
1092 else:
1093 raise CommandError('Deleting record of type %s is not supported' % rtype)
1095 self.lp = sambaopts.get_loadparm()
1096 self.creds = credopts.get_credentials(self.lp)
1097 dns_conn = dns_connect(server, self.lp, self.creds)
1099 rec_match = dns_record_match(dns_conn, server, zone, name, record_type, data)
1100 if not rec_match:
1101 raise CommandError('Record does not exist')
1103 del_rec_buf = dnsserver.DNS_RPC_RECORD_BUF()
1104 del_rec_buf.rec = rec_match
1106 dns_conn.DnssrvUpdateRecord2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
1108 server,
1109 zone,
1110 name,
1111 None,
1112 del_rec_buf)
1113 self.outf.write('Record deleted succefully\n')
1116 class cmd_dns(SuperCommand):
1117 """Domain Name Service (DNS) management"""
1119 subcommands = {}
1120 subcommands['serverinfo'] = cmd_serverinfo()
1121 subcommands['zoneinfo'] = cmd_zoneinfo()
1122 subcommands['zonelist'] = cmd_zonelist()
1123 subcommands['zonecreate'] = cmd_zonecreate()
1124 subcommands['zonedelete'] = cmd_zonedelete()
1125 subcommands['query'] = cmd_query()
1126 subcommands['roothints'] = cmd_roothints()
1127 subcommands['add'] = cmd_add_record()
1128 subcommands['update'] = cmd_update_record()
1129 subcommands['delete'] = cmd_delete_record()