samba-tool: Unify usage messages.
[Samba/gebeck_regimport.git] / source4 / scripting / python / samba / netcmd / dns.py
blob8bd3249ae231a175949f7ba5cf777bfe33f1ff33
1 # DNS management tool
3 # Copyright (C) Amitay Isaacs 2011-2012
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 import samba.getopt as options
20 from struct import pack
21 from socket import inet_ntoa
22 import shlex
24 from samba.netcmd import (
25 Command,
26 CommandError,
27 Option,
28 SuperCommand,
30 from samba.dcerpc import dnsp, dnsserver
33 def dns_connect(server, lp, creds):
34 binding_str = "ncacn_ip_tcp:%s[sign]" % server
35 dns_conn = dnsserver.dnsserver(binding_str, lp, creds)
36 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
49 def enum_string(module, enum_defs, value):
50 ret = None
51 for e in enum_defs:
52 if value == getattr(module, e):
53 ret = e
54 break
55 if not ret:
56 ret = 'UNKNOWN (0x%x)' % value
57 return ret
60 def bitmap_string(module, bitmap_defs, value):
61 ret = ''
62 for b in bitmap_defs:
63 if value & getattr(module, b):
64 ret += '%s ' % b
65 if not ret:
66 ret = 'NONE'
67 return ret
70 def boot_method_string(boot_method):
71 enum_defs = [ 'DNS_BOOT_METHOD_UNINITIALIZED', 'DNS_BOOT_METHOD_FILE',
72 'DNS_BOOT_METHOD_REGISTRY', 'DNS_BOOT_METHOD_DIRECTORY' ]
73 return enum_string(dnsserver, enum_defs, boot_method)
76 def name_check_flag_string(check_flag):
77 enum_defs = [ 'DNS_ALLOW_RFC_NAMES_ONLY', 'DNS_ALLOW_NONRFC_NAMES',
78 'DNS_ALLOW_MULTIBYTE_NAMES', 'DNS_ALLOW_ALL_NAMES' ]
79 return enum_string(dnsserver, enum_defs, check_flag)
82 def zone_type_string(zone_type):
83 enum_defs = [ 'DNS_ZONE_TYPE_CACHE', 'DNS_ZONE_TYPE_PRIMARY',
84 'DNS_ZONE_TYPE_SECONDARY', 'DNS_ZONE_TYPE_STUB',
85 'DNS_ZONE_TYPE_FORWARDER', 'DNS_ZONE_TYPE_SECONDARY_CACHE' ]
86 return enum_string(dnsp, enum_defs, zone_type)
89 def zone_update_string(zone_update):
90 enum_defs = [ 'DNS_ZONE_UPDATE_OFF', 'DNS_ZONE_UPDATE_SECURE',
91 'DNS_ZONE_UPDATE_SECURE' ]
92 return enum_string(dnsp, enum_defs, zone_update)
95 def zone_secondary_security_string(security):
96 enum_defs = [ 'DNS_ZONE_SECSECURE_NO_SECURITY', 'DNS_ZONE_SECSECURE_NS_ONLY',
97 'DNS_ZONE_SECSECURE_LIST_ONLY', 'DNS_ZONE_SECSECURE_NO_XFER' ]
98 return enum_string(dnsserver, enum_defs, security)
101 def zone_notify_level_string(notify_level):
102 enum_defs = [ 'DNS_ZONE_NOTIFY_OFF', 'DNS_ZONE_NOTIFY_ALL_SECONDARIES',
103 'DNS_ZONE_NOTIFY_LIST_ONLY' ]
104 return enum_string(dnsserver, enum_defs, notify_level)
107 def dp_flags_string(dp_flags):
108 bitmap_defs = [ 'DNS_DP_AUTOCREATED', 'DNS_DP_LEGACY', 'DNS_DP_DOMAIN_DEFAULT',
109 'DNS_DP_FOREST_DEFAULT', 'DNS_DP_ENLISTED', 'DNS_DP_DELETED' ]
110 return bitmap_string(dnsserver, bitmap_defs, dp_flags)
113 def zone_flags_string(flags):
114 bitmap_defs = [ 'DNS_RPC_ZONE_PAUSED', 'DNS_RPC_ZONE_SHUTDOWN',
115 'DNS_RPC_ZONE_REVERSE', 'DNS_RPC_ZONE_AUTOCREATED',
116 'DNS_RPC_ZONE_DSINTEGRATED', 'DNS_RPC_ZONE_AGING',
117 'DNS_RPC_ZONE_UPDATE_UNSECURE', 'DNS_RPC_ZONE_UPDATE_SECURE',
118 'DNS_RPC_ZONE_READONLY']
119 return bitmap_string(dnsserver, bitmap_defs, flags)
122 def ip4_array_string(array):
123 ret = []
124 if not array:
125 return ret
126 for i in xrange(array.AddrCount):
127 addr = '%s' % inet_ntoa(pack('i', array.AddrArray[i]))
128 ret.append(addr)
129 return ret
132 def dns_addr_array_string(array):
133 ret = []
134 if not array:
135 return ret
136 for i in xrange(array.AddrCount):
137 if array.AddrArray[i].MaxSa[0] == 0x02:
138 addr = '%d.%d.%d.%d (%d)' % \
139 tuple(array.AddrArray[i].MaxSa[4:8] + [array.AddrArray[i].MaxSa[3]])
140 elif array.AddrArray[i].MaxSa[0] == 0x17:
141 addr = '%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x (%d)' % \
142 tuple(array.AddrArray[i].MaxSa[4:20] + [array.AddrArray[i].MaxSa[3]])
143 else:
144 addr = 'UNKNOWN'
145 ret.append(addr)
146 return ret
149 def dns_type_flag(rec_type):
150 rtype = rec_type.upper()
151 if rtype == 'A':
152 record_type = dnsp.DNS_TYPE_A
153 elif rtype == 'AAAA':
154 record_type = dnsp.DNS_TYPE_AAAA
155 elif rtype == 'PTR':
156 record_type = dnsp.DNS_TYPE_PTR
157 elif rtype == 'NS':
158 record_type = dnsp.DNS_TYPE_NS
159 elif rtype == 'CNAME':
160 record_type = dnsp.DNS_TYPE_CNAME
161 elif rtype == 'SOA':
162 record_type = dnsp.DNS_TYPE_SOA
163 elif rtype == 'MX':
164 record_type = dnsp.DNS_TYPE_MX
165 elif rtype == 'SRV':
166 record_type = dnsp.DNS_TYPE_SRV
167 elif rtype == 'TXT':
168 record_type = dnsp.DNS_TYPE_TXT
169 elif rtype == 'ALL':
170 record_type = dnsp.DNS_TYPE_ALL
171 else:
172 raise CommandError('Unknown type of DNS record %s' % rec_type)
173 return record_type
176 def dns_client_version(cli_version):
177 version = cli_version.upper()
178 if version == 'W2K':
179 client_version = dnsserver.DNS_CLIENT_VERSION_W2K
180 elif version == 'DOTNET':
181 client_version = dnsserver.DNS_CLIENT_VERSION_DOTNET
182 elif version == 'LONGHORN':
183 client_version = dnsserver.DNS_CLIENT_VERSION_LONGHORN
184 else:
185 raise CommandError('Unknown client version %s' % cli_version)
186 return client_version
189 def print_serverinfo(outf, typeid, serverinfo):
190 outf.write(' dwVersion : 0x%x\n' % serverinfo.dwVersion)
191 outf.write(' fBootMethod : %s\n' % boot_method_string(serverinfo.fBootMethod))
192 outf.write(' fAdminConfigured : %s\n' % bool_string(serverinfo.fAdminConfigured))
193 outf.write(' fAllowUpdate : %s\n' % bool_string(serverinfo.fAllowUpdate))
194 outf.write(' fDsAvailable : %s\n' % bool_string(serverinfo.fDsAvailable))
195 outf.write(' pszServerName : %s\n' % serverinfo.pszServerName)
196 outf.write(' pszDsContainer : %s\n' % serverinfo.pszDsContainer)
198 if typeid != dnsserver.DNSSRV_TYPEID_SERVER_INFO:
199 outf.write(' aipServerAddrs : %s\n' %
200 ip4_array_string(serverinfo.aipServerAddrs))
201 outf.write(' aipListenAddrs : %s\n' %
202 ip4_array_string(serverinfo.aipListenAddrs))
203 outf.write(' aipForwarders : %s\n' %
204 ip4_array_string(serverinfo.aipForwarders))
205 else:
206 outf.write(' aipServerAddrs : %s\n' %
207 dns_addr_array_string(serverinfo.aipServerAddrs))
208 outf.write(' aipListenAddrs : %s\n' %
209 dns_addr_array_string(serverinfo.aipListenAddrs))
210 outf.write(' aipForwarders : %s\n' %
211 dns_addr_array_string(serverinfo.aipForwarders))
213 outf.write(' dwLogLevel : %d\n' % serverinfo.dwLogLevel)
214 outf.write(' dwDebugLevel : %d\n' % serverinfo.dwDebugLevel)
215 outf.write(' dwForwardTimeout : %d\n' % serverinfo.dwForwardTimeout)
216 outf.write(' dwRpcPrototol : 0x%x\n' % serverinfo.dwRpcProtocol)
217 outf.write(' dwNameCheckFlag : %s\n' % name_check_flag_string(serverinfo.dwNameCheckFlag))
218 outf.write(' cAddressAnswerLimit : %d\n' % serverinfo.cAddressAnswerLimit)
219 outf.write(' dwRecursionRetry : %d\n' % serverinfo.dwRecursionRetry)
220 outf.write(' dwRecursionTimeout : %d\n' % serverinfo.dwRecursionTimeout)
221 outf.write(' dwMaxCacheTtl : %d\n' % serverinfo.dwMaxCacheTtl)
222 outf.write(' dwDsPollingInterval : %d\n' % serverinfo.dwDsPollingInterval)
223 outf.write(' dwScavengingInterval : %d\n' % serverinfo.dwScavengingInterval)
224 outf.write(' dwDefaultRefreshInterval : %d\n' % serverinfo.dwDefaultRefreshInterval)
225 outf.write(' dwDefaultNoRefreshInterval : %d\n' % serverinfo.dwDefaultNoRefreshInterval)
226 outf.write(' fAutoReverseZones : %s\n' % bool_string(serverinfo.fAutoReverseZones))
227 outf.write(' fAutoCacheUpdate : %s\n' % bool_string(serverinfo.fAutoCacheUpdate))
228 outf.write(' fRecurseAfterForwarding : %s\n' % bool_string(serverinfo.fRecurseAfterForwarding))
229 outf.write(' fForwardDelegations : %s\n' % bool_string(serverinfo.fForwardDelegations))
230 outf.write(' fNoRecursion : %s\n' % bool_string(serverinfo.fNoRecursion))
231 outf.write(' fSecureResponses : %s\n' % bool_string(serverinfo.fSecureResponses))
232 outf.write(' fRoundRobin : %s\n' % bool_string(serverinfo.fRoundRobin))
233 outf.write(' fLocalNetPriority : %s\n' % bool_string(serverinfo.fLocalNetPriority))
234 outf.write(' fBindSecondaries : %s\n' % bool_string(serverinfo.fBindSecondaries))
235 outf.write(' fWriteAuthorityNs : %s\n' % bool_string(serverinfo.fWriteAuthorityNs))
236 outf.write(' fStrictFileParsing : %s\n' % bool_string(serverinfo.fStrictFileParsing))
237 outf.write(' fLooseWildcarding : %s\n' % bool_string(serverinfo.fLooseWildcarding))
238 outf.write(' fDefaultAgingState : %s\n' % bool_string(serverinfo.fDefaultAgingState))
240 if typeid != dnsserver.DNSSRV_TYPEID_SERVER_INFO_W2K:
241 outf.write(' dwRpcStructureVersion : 0x%x\n' % serverinfo.dwRpcStructureVersion)
242 outf.write(' aipLogFilter : %s\n' % dns_addr_array_string(serverinfo.aipLogFilter))
243 outf.write(' pwszLogFilePath : %s\n' % serverinfo.pwszLogFilePath)
244 outf.write(' pszDomainName : %s\n' % serverinfo.pszDomainName)
245 outf.write(' pszForestName : %s\n' % serverinfo.pszForestName)
246 outf.write(' pszDomainDirectoryPartition : %s\n' % serverinfo.pszDomainDirectoryPartition)
247 outf.write(' pszForestDirectoryPartition : %s\n' % serverinfo.pszForestDirectoryPartition)
249 outf.write(' dwLocalNetPriorityNetMask : 0x%x\n' % serverinfo.dwLocalNetPriorityNetMask)
250 outf.write(' dwLastScavengeTime : %d\n' % serverinfo.dwLastScavengeTime)
251 outf.write(' dwEventLogLevel : %d\n' % serverinfo.dwEventLogLevel)
252 outf.write(' dwLogFileMaxSize : %d\n' % serverinfo.dwLogFileMaxSize)
253 outf.write(' dwDsForestVersion : %d\n' % serverinfo.dwDsForestVersion)
254 outf.write(' dwDsDomainVersion : %d\n' % serverinfo.dwDsDomainVersion)
255 outf.write(' dwDsDsaVersion : %d\n' % serverinfo.dwDsDsaVersion)
257 if typeid == dnsserver.DNSSRV_TYPEID_SERVER_INFO:
258 outf.write(' fReadOnlyDC : %s\n' % bool_string(serverinfo.fReadOnlyDC))
261 def print_zoneinfo(outf, typeid, zoneinfo):
262 outf.write(' pszZoneName : %s\n' % zoneinfo.pszZoneName)
263 outf.write(' dwZoneType : %s\n' % zone_type_string(zoneinfo.dwZoneType))
264 outf.write(' fReverse : %s\n' % bool_string(zoneinfo.fReverse))
265 outf.write(' fAllowUpdate : %s\n' % zone_update_string(zoneinfo.fAllowUpdate))
266 outf.write(' fPaused : %s\n' % bool_string(zoneinfo.fPaused))
267 outf.write(' fShutdown : %s\n' % bool_string(zoneinfo.fShutdown))
268 outf.write(' fAutoCreated : %s\n' % bool_string(zoneinfo.fAutoCreated))
269 outf.write(' fUseDatabase : %s\n' % bool_string(zoneinfo.fUseDatabase))
270 outf.write(' pszDataFile : %s\n' % zoneinfo.pszDataFile)
271 if typeid != dnsserver.DNSSRV_TYPEID_ZONE_INFO:
272 outf.write(' aipMasters : %s\n' %
273 ip4_array_string(zoneinfo.aipMasters))
274 else:
275 outf.write(' aipMasters : %s\n' %
276 dns_addr_array_string(zoneinfo.aipMasters))
277 outf.write(' fSecureSecondaries : %s\n' % zone_secondary_security_string(zoneinfo.fSecureSecondaries))
278 outf.write(' fNotifyLevel : %s\n' % zone_notify_level_string(zoneinfo.fNotifyLevel))
279 if typeid != dnsserver.DNSSRV_TYPEID_ZONE_INFO:
280 outf.write(' aipSecondaries : %s\n' %
281 ip4_array_string(zoneinfo.aipSecondaries))
282 outf.write(' aipNotify : %s\n' %
283 ip4_array_string(zoneinfo.aipNotify))
284 else:
285 outf.write(' aipSecondaries : %s\n' %
286 dns_addr_array_string(zoneinfo.aipSecondaries))
287 outf.write(' aipNotify : %s\n' %
288 dns_addr_array_string(zoneinfo.aipNotify))
289 outf.write(' fUseWins : %s\n' % bool_string(zoneinfo.fUseWins))
290 outf.write(' fUseNbstat : %s\n' % bool_string(zoneinfo.fUseNbstat))
291 outf.write(' fAging : %s\n' % bool_string(zoneinfo.fAging))
292 outf.write(' dwNoRefreshInterval : %d\n' % zoneinfo.dwNoRefreshInterval)
293 outf.write(' dwRefreshInterval : %d\n' % zoneinfo.dwRefreshInterval)
294 outf.write(' dwAvailForScavengeTime : %d\n' % zoneinfo.dwAvailForScavengeTime)
295 if typeid != dnsserver.DNSSRV_TYPEID_ZONE_INFO:
296 outf.write(' aipScavengeServers : %s\n' %
297 ip4_array_string(zoneinfo.aipScavengeServers))
298 else:
299 outf.write(' aipScavengeServers : %s\n' %
300 dns_addr_array_string(zoneinfo.aipScavengeServers))
302 if typeid != dnsserver.DNSSRV_TYPEID_ZONE_INFO_W2K:
303 outf.write(' dwRpcStructureVersion : 0x%x\n' % zoneinfo.dwRpcStructureVersion)
304 outf.write(' dwForwarderTimeout : %d\n' % zoneinfo.dwForwarderTimeout)
305 outf.write(' fForwarderSlave : %d\n' % zoneinfo.fForwarderSlave)
306 if typeid != dnsserver.DNSSRV_TYPEID_ZONE_INFO:
307 outf.write(' aipLocalMasters : %s\n' %
308 ip4_array_string(zoneinfo.aipLocalMasters))
309 else:
310 outf.write(' aipLocalMasters : %s\n' %
311 dns_addr_array_string(zoneinfo.aipLocalMasters))
312 outf.write(' dwDpFlags : %s\n' % dp_flags_string(zoneinfo.dwDpFlags))
313 outf.write(' pszDpFqdn : %s\n' % zoneinfo.pszDpFqdn)
314 outf.write(' pwszZoneDn : %s\n' % zoneinfo.pwszZoneDn)
315 outf.write(' dwLastSuccessfulSoaCheck : %d\n' % zoneinfo.dwLastSuccessfulSoaCheck)
316 outf.write(' dwLastSuccessfulXfr : %d\n' % zoneinfo.dwLastSuccessfulXfr)
318 if typeid == dnsserver.DNSSRV_TYPEID_ZONE_INFO:
319 outf.write(' fQueuedForBackgroundLoad : %s\n' % bool_string(zoneinfo.fQueuedForBackgroundLoad))
320 outf.write(' fBackgroundLoadInProgress : %s\n' % bool_string(zoneinfo.fBackgroundLoadInProgress))
321 outf.write(' fReadOnlyZone : %s\n' % bool_string(zoneinfo.fReadOnlyZone))
322 outf.write(' dwLastXfrAttempt : %d\n' % zoneinfo.dwLastXfrAttempt)
323 outf.write(' dwLastXfrResult : %d\n' % zoneinfo.dwLastXfrResult)
326 def print_zone(outf, typeid, zone):
327 outf.write(' pszZoneName : %s\n' % zone.pszZoneName)
328 outf.write(' Flags : %s\n' % zone_flags_string(zone.Flags))
329 outf.write(' ZoneType : %s\n' % zone_type_string(zone.ZoneType))
330 outf.write(' Version : %s\n' % zone.Version)
332 if typeid != dnsserver.DNSSRV_TYPEID_ZONE_W2K:
333 outf.write(' dwDpFlags : %s\n' % dp_flags_string(zone.dwDpFlags))
334 outf.write(' pszDpFqdn : %s\n' % zone.pszDpFqdn)
337 def print_enumzones(outf, typeid, zones):
338 outf.write(' %d zone(s) found\n' % zones.dwZoneCount)
339 for zone in zones.ZoneArray:
340 outf.write('\n')
341 print_zone(outf, typeid, zone)
344 def print_dns_record(outf, rec):
345 if rec.wType == dnsp.DNS_TYPE_A:
346 mesg = 'A: %s' % (rec.data)
347 elif rec.wType == dnsp.DNS_TYPE_AAAA:
348 mesg = 'AAAA: %s' % (rec.data)
349 elif rec.wType == dnsp.DNS_TYPE_PTR:
350 mesg = 'PTR: %s' % (rec.data.str)
351 elif rec.wType == dnsp.DNS_TYPE_NS:
352 mesg = 'NS: %s' % (rec.data.str)
353 elif rec.wType == dnsp.DNS_TYPE_CNAME:
354 mesg = 'CNAME: %s' % (rec.data.str)
355 elif rec.wType == dnsp.DNS_TYPE_SOA:
356 mesg = 'SOA: serial=%d, refresh=%d, retry=%d, expire=%d, ns=%s, email=%s' % (
357 rec.data.dwSerialNo,
358 rec.data.dwRefresh,
359 rec.data.dwRetry,
360 rec.data.dwExpire,
361 rec.data.NamePrimaryServer.str,
362 rec.data.ZoneAdministratorEmail.str)
363 elif rec.wType == dnsp.DNS_TYPE_MX:
364 mesg = 'MX: %s (%d)' % (rec.data.nameExchange.str, rec.data.wPreference)
365 elif rec.wType == dnsp.DNS_TYPE_SRV:
366 mesg = 'SRV: %s (%d, %d, %d)' % (rec.data.nameTarget.str, rec.data.wPort,
367 rec.data.wPriority, rec.data.wWeight)
368 elif rec.wType == dnsp.DNS_TYPE_TXT:
369 slist = ['"%s"' % name.str for name in rec.data.str]
370 mesg = 'TXT: %s' % ','.join(slist)
371 else:
372 mesg = 'Unknown: '
373 outf.write(' %s (flags=%x, serial=%d, ttl=%d)\n' % (
374 mesg, rec.dwFlags, rec.dwSerial, rec.dwTtlSeconds))
377 def print_dnsrecords(outf, records):
378 for rec in records.rec:
379 outf.write(' Name=%s, Records=%d, Children=%d\n' % (
380 rec.dnsNodeName.str,
381 rec.wRecordCount,
382 rec.dwChildCount))
383 for dns_rec in rec.records:
384 print_dns_record(outf, dns_rec)
388 # Always create a copy of strings when creating DNS_RPC_RECORDs
389 # to overcome the bug in pidl generated python bindings.
392 class ARecord(dnsserver.DNS_RPC_RECORD):
393 def __init__(self, ip_addr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
394 node_flag=0):
395 super(ARecord, self).__init__()
396 self.wType = dnsp.DNS_TYPE_A
397 self.dwFlags = rank | node_flag
398 self.dwSerial = serial
399 self.dwTtlSeconds = ttl
400 self._ip_addr = ip_addr[:]
401 self.data = self._ip_addr
404 class AAAARecord(dnsserver.DNS_RPC_RECORD):
406 def __init__(self, ip6_addr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
407 node_flag=0):
408 super(AAAARecord, self).__init__()
409 self.wType = dnsp.DNS_TYPE_AAAA
410 self.dwFlags = rank | node_flag
411 self.dwSerial = serial
412 self.dwTtlSeconds = ttl
413 self._ip6_addr = ip6_addr[:]
414 self.data = self._ip6_addr
417 class PTRRecord(dnsserver.DNS_RPC_RECORD):
419 def __init__(self, ptr, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
420 node_flag=0):
421 super(PTRRecord, self).__init__()
422 self.wType = dnsp.DNS_TYPE_PTR
423 self.dwFlags = rank | node_flag
424 self.dwSerial = serial
425 self.dwTtleSeconds = ttl
426 self._ptr = ptr[:]
427 ptr_name = dnsserver.DNS_RPC_NAME()
428 ptr_name.str = self._ptr
429 ptr_name.len = len(ptr)
430 self.data = ptr_name
433 class CNameRecord(dnsserver.DNS_RPC_RECORD):
435 def __init__(self, cname, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
436 node_flag=0):
437 super(CNameRecord, self).__init__()
438 self.wType = dnsp.DNS_TYPE_CNAME
439 self.dwFlags = rank | node_flag
440 self.dwSerial = serial
441 self.dwTtlSeconds = ttl
442 self._cname = cname[:]
443 cname_name = dnsserver.DNS_RPC_NAME()
444 cname_name.str = self._cname
445 cname_name.len = len(cname)
446 self.data = cname_name
449 class NSRecord(dnsserver.DNS_RPC_RECORD):
451 def __init__(self, dns_server, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
452 node_flag=0):
453 super(NSRecord, self).__init__()
454 self.wType = dnsp.DNS_TYPE_NS
455 self.dwFlags = rank | node_flag
456 self.dwSerial = serial
457 self.dwTtlSeconds = ttl
458 self._dns_server = dns_server[:]
459 ns = dnsserver.DNS_RPC_NAME()
460 ns.str = self._dns_server
461 ns.len = len(dns_server)
462 self.data = ns
465 class MXRecord(dnsserver.DNS_RPC_RECORD):
467 def __init__(self, mail_server, preference, serial=1, ttl=900,
468 rank=dnsp.DNS_RANK_ZONE, node_flag=0):
469 super(MXRecord, self).__init__()
470 self.wType = dnsp.DNS_TYPE_MX
471 self.dwFlags = rank | node_flag
472 self.dwSerial = serial
473 self.dwTtlSeconds = ttl
474 self._mail_server = mail_server[:]
475 mx = dnsserver.DNS_RPC_RECORD_NAME_PREFERENCE()
476 mx.wPreference = preference
477 mx.nameExchange.str = self._mail_server
478 mx.nameExchange.len = len(mail_server)
479 self.data = mx
482 class SOARecord(dnsserver.DNS_RPC_RECORD):
484 def __init__(self, mname, rname, serial=1, refresh=900, retry=600,
485 expire=86400, minimum=3600, ttl=3600, rank=dnsp.DNS_RANK_ZONE,
486 node_flag=dnsp.DNS_RPC_FLAG_AUTH_ZONE_ROOT):
487 super(SOARecord, self).__init__()
488 self.wType = dnsp.DNS_TYPE_SOA
489 self.dwFlags = rank | node_flag
490 self.dwSerial = serial
491 self.dwTtlSeconds = ttl
492 self._mname = mname[:]
493 self._rname = rname[:]
494 soa = dnsserver.DNS_RPC_RECORD_SOA()
495 soa.dwSerialNo = serial
496 soa.dwRefresh = refresh
497 soa.dwRetry = retry
498 soa.dwExpire = expire
499 soa.NamePrimaryServer.str = self._mname
500 soa.NamePrimaryServer.len = len(mname)
501 soa.ZoneAdministratorEmail.str = self._rname
502 soa.ZoneAdministratorEmail.len = len(rname)
503 self.data = soa
506 class SRVRecord(dnsserver.DNS_RPC_RECORD):
508 def __init__(self, target, port, priority=0, weight=100, serial=1, ttl=900,
509 rank=dnsp.DNS_RANK_ZONE, node_flag=0):
510 super(SRVRecord, self).__init__()
511 self.wType = dnsp.DNS_TYPE_SRV
512 self.dwFlags = rank | node_flag
513 self.dwSerial = serial
514 self.dwTtlSeconds = ttl
515 self._target = target[:]
516 srv = dnsserver.DNS_RPC_RECORD_SRV()
517 srv.wPriority = priority
518 srv.wWeight = weight
519 srv.wPort = port
520 srv.nameTarget.str = self._target
521 srv.nameTarget.len = len(target)
522 self.data = srv
525 class TXTRecord(dnsserver.DNS_RPC_RECORD):
527 def __init__(self, slist, serial=1, ttl=900, rank=dnsp.DNS_RANK_ZONE,
528 node_flag=0):
529 super(TXTRecord, self).__init__()
530 self.wType = dnsp.DNS_TYPE_TXT
531 self.dwFlags = rank | node_flag
532 self.dwSerial = serial
533 self.dwTtlSeconds = ttl
534 self._slist = []
535 for s in slist:
536 self._slist.append(s[:])
537 names = []
538 for s in self._slist:
539 name = dnsserver.DNS_RPC_NAME()
540 name.str = s
541 name.len = len(s)
542 names.append(name)
543 txt = dnsserver.DNS_RPC_RECORD_STRING()
544 txt.count = len(slist)
545 txt.str = names
546 self.data = txt
549 # Convert data into a dns record
550 def data_to_dns_record(record_type, data):
551 if record_type == dnsp.DNS_TYPE_A:
552 rec = ARecord(data)
553 elif record_type == dnsp.DNS_TYPE_AAAA:
554 rec = AAAARecord(data)
555 elif record_type == dnsp.DNS_TYPE_PTR:
556 rec = PTRRecord(data)
557 elif record_type == dnsp.DNS_TYPE_CNAME:
558 rec = CNameRecord(data)
559 elif record_type == dnsp.DNS_TYPE_NS:
560 rec = NSRecord(data)
561 elif record_type == dnsp.DNS_TYPE_MX:
562 tmp = data.split(' ')
563 if len(tmp) != 2:
564 raise CommandError('Data requires 2 elements - mail_server, preference')
565 mail_server = tmp[0]
566 preference = int(tmp[1])
567 rec = MXRecord(mail_server, preference)
568 elif record_type == dnsp.DNS_TYPE_SRV:
569 tmp = data.split(' ')
570 if len(tmp) != 4:
571 raise CommandError('Data requires 4 elements - server, port, priority, weight')
572 server = tmp[0]
573 port = int(tmp[1])
574 priority = int(tmp[2])
575 weight = int(tmp[3])
576 rec = SRVRecord(server, port, priority=priority, weight=weight)
577 elif record_type == dnsp.DNS_TYPE_SOA:
578 tmp = data.split(' ')
579 if len(tmp) != 7:
580 raise CommandError('Data requires 7 elements - nameserver, email, serial, '
581 'refresh, retry, expire, minimumttl')
582 nameserver = tmp[0]
583 email = tmp[1]
584 serial = int(tmp[2])
585 refresh = int(tmp[3])
586 retry = int(tmp[4])
587 expire = int(tmp[5])
588 minimum = int(tmp[6])
589 rec = SOARecord(nameserver, email, serial=serial, refresh=refresh,
590 retry=retry, expire=expire, minimum=minimum)
591 elif record_type == dnsp.DNS_TYPE_TXT:
592 slist = shlex.split(data)
593 rec = TXTRecord(slist)
594 else:
595 raise CommandError('Unsupported record type')
596 return rec
599 # Match dns name (of type DNS_RPC_NAME)
600 def dns_name_equal(n1, n2):
601 return n1.str.rstrip('.').lower() == n2.str.rstrip('.').lower()
604 # Match a dns record with specified data
605 def dns_record_match(dns_conn, server, zone, name, record_type, data):
606 urec = data_to_dns_record(record_type, data)
608 select_flags = dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA
610 try:
611 buflen, res = dns_conn.DnssrvEnumRecords2(
612 dnsserver.DNS_CLIENT_VERSION_LONGHORN, 0, server, zone, name, None,
613 record_type, select_flags, None, None)
614 except RuntimeError, e:
615 return None
617 if not res or res.count == 0:
618 return None
620 rec_match = None
621 for rec in res.rec[0].records:
622 if rec.wType != record_type:
623 continue
625 found = False
626 if record_type == dnsp.DNS_TYPE_A:
627 if rec.data == urec.data:
628 found = True
629 elif record_type == dnsp.DNS_TYPE_AAAA:
630 if rec.data == urec.data:
631 found = True
632 elif record_type == dnsp.DNS_TYPE_PTR:
633 if dns_name_equal(rec.data, urec.data):
634 found = True
635 elif record_type == dnsp.DNS_TYPE_CNAME:
636 if dns_name_equal(rec.data, urec.data):
637 found = True
638 elif record_type == dnsp.DNS_TYPE_NS:
639 if dns_name_equal(rec.data, urec.data):
640 found = True
641 elif record_type == dnsp.DNS_TYPE_MX:
642 if dns_name_equal(rec.data.nameExchange, urec.data.nameExchange) and \
643 rec.data.wPreference == urec.data.wPreference:
644 found = True
645 elif record_type == dnsp.DNS_TYPE_SRV:
646 if rec.data.wPriority == urec.data.wPriority and \
647 rec.data.wWeight == urec.data.wWeight and \
648 rec.data.wPort == urec.data.wPort and \
649 dns_name_equal(rec.data.nameTarget, urec.data.nameTarget):
650 found = True
651 elif record_type == dnsp.DNS_TYPE_SOA:
652 if rec.data.dwSerialNo == urec.data.dwSerialNo and \
653 rec.data.dwRefresh == urec.data.dwRefresh and \
654 rec.data.dwRetry == urec.data.dwRetry and \
655 rec.data.dwExpire == urec.data.dwExpire and \
656 rec.data.dwMinimumTtl == urec.data.dwMinimumTtl and \
657 dns_name_equal(rec.data.NamePrimaryServer,
658 urec.data.NamePrimaryServer) and \
659 dns_name_equal(rec.data.ZoneAdministratorEmail,
660 urec.data.ZoneAdministratorEmail):
661 found = True
662 elif record_type == dnsp.DNS_TYPE_TXT:
663 if rec.data.count == urec.data.count:
664 found = True
665 for i in xrange(rec.data.count):
666 found = found and \
667 (rec.data.str[i].str == urec.data.str[i].str)
669 if found:
670 rec_match = rec
671 break
673 return rec_match
676 class cmd_serverinfo(Command):
677 """Query for Server information."""
679 synopsis = '%prog <server> [options]'
681 takes_args = [ 'server' ]
683 takes_optiongroups = {
684 "sambaopts": options.SambaOptions,
685 "versionopts": options.VersionOptions,
686 "credopts": options.CredentialsOptions,
689 takes_options = [
690 Option('--client-version', help='Client Version',
691 default='longhorn', metavar='w2k|dotnet|longhorn',
692 choices=['w2k','dotnet','longhorn'], dest='cli_ver'),
695 def run(self, server, cli_ver, sambaopts=None, credopts=None,
696 versionopts=None):
697 self.lp = sambaopts.get_loadparm()
698 self.creds = credopts.get_credentials(self.lp)
699 dns_conn = dns_connect(server, self.lp, self.creds)
701 client_version = dns_client_version(cli_ver)
703 typeid, res = dns_conn.DnssrvQuery2(client_version, 0, server,
704 None, 'ServerInfo')
705 print_serverinfo(self.outf, typeid, res)
708 class cmd_zoneinfo(Command):
709 """Query for zone information."""
711 synopsis = '%prog <server> <zone> [options]'
713 takes_args = [ 'server', 'zone' ]
715 takes_optiongroups = {
716 "sambaopts": options.SambaOptions,
717 "versionopts": options.VersionOptions,
718 "credopts": options.CredentialsOptions,
721 takes_options = [
722 Option('--client-version', help='Client Version',
723 default='longhorn', metavar='w2k|dotnet|longhorn',
724 choices=['w2k','dotnet','longhorn'], dest='cli_ver'),
727 def run(self, server, zone, cli_ver, sambaopts=None, credopts=None,
728 versionopts=None):
729 self.lp = sambaopts.get_loadparm()
730 self.creds = credopts.get_credentials(self.lp)
731 dns_conn = dns_connect(server, self.lp, self.creds)
733 client_version = dns_client_version(cli_ver)
735 typeid, res = dns_conn.DnssrvQuery2(client_version, 0, server, zone,
736 'ZoneInfo')
737 print_zoneinfo(self.outf, typeid, res)
740 class cmd_zonelist(Command):
741 """Query for zones."""
743 synopsis = '%prog <server> [options]'
745 takes_args = [ 'server' ]
747 takes_optiongroups = {
748 "sambaopts": options.SambaOptions,
749 "versionopts": options.VersionOptions,
750 "credopts": options.CredentialsOptions,
753 takes_options = [
754 Option('--client-version', help='Client Version',
755 default='longhorn', metavar='w2k|dotnet|longhorn',
756 choices=['w2k','dotnet','longhorn'], dest='cli_ver'),
757 Option('--primary', help='List primary zones (default)',
758 action='store_true', dest='primary'),
759 Option('--secondary', help='List secondary zones',
760 action='store_true', dest='secondary'),
761 Option('--cache', help='List cached zones',
762 action='store_true', dest='cache'),
763 Option('--auto', help='List automatically created zones',
764 action='store_true', dest='auto'),
765 Option('--forward', help='List forward zones',
766 action='store_true', dest='forward'),
767 Option('--reverse', help='List reverse zones',
768 action='store_true', dest='reverse'),
769 Option('--ds', help='List directory integrated zones',
770 action='store_true', dest='ds'),
771 Option('--non-ds', help='List non-directory zones',
772 action='store_true', dest='nonds')
775 def run(self, server, cli_ver, primary=False, secondary=False, cache=False,
776 auto=False, forward=False, reverse=False, ds=False, nonds=False,
777 sambaopts=None, credopts=None, versionopts=None):
778 request_filter = 0
780 if primary:
781 request_filter |= dnsserver.DNS_ZONE_REQUEST_PRIMARY
782 if secondary:
783 request_filter |= dnsserver.DNS_ZONE_REQUEST_SECONDARY
784 if cache:
785 request_filter |= dnsserver.DNS_ZONE_REQUEST_CACHE
786 if auto:
787 request_filter |= dnsserver.DNS_ZONE_REQUEST_AUTO
788 if forward:
789 request_filter |= dnsserver.DNS_ZONE_REQUEST_FORWARD
790 if reverse:
791 request_filter |= dnsserver.DNS_ZONE_REQUEST_REVERSE
792 if ds:
793 request_filter |= dnsserver.DNS_ZONE_REQUEST_DS
794 if nonds:
795 request_filter |= dnsserver.DNS_ZONE_REQUEST_NON_DS
797 if request_filter == 0:
798 request_filter = dnsserver.DNS_ZONE_REQUEST_PRIMARY
800 self.lp = sambaopts.get_loadparm()
801 self.creds = credopts.get_credentials(self.lp)
802 dns_conn = dns_connect(server, self.lp, self.creds)
804 client_version = dns_client_version(cli_ver)
806 typeid, res = dns_conn.DnssrvComplexOperation2(client_version,
807 0, server, None,
808 'EnumZones',
809 dnsserver.DNSSRV_TYPEID_DWORD,
810 request_filter)
812 if client_version == dnsserver.DNS_CLIENT_VERSION_W2K:
813 typeid = dnsserver.DNSSRV_TYPEID_ZONE_W2K
814 else:
815 typeid = dnsserver.DNSSRV_TYPEID_ZONE
816 print_enumzones(self.outf, typeid, res)
819 class cmd_zonecreate(Command):
820 """Create a zone."""
822 synopsis = '%prog <server> <zone> [options]'
824 takes_args = [ 'server', 'zone' ]
826 takes_optiongroups = {
827 "sambaopts": options.SambaOptions,
828 "versionopts": options.VersionOptions,
829 "credopts": options.CredentialsOptions,
832 takes_options = [
833 Option('--client-version', help='Client Version',
834 default='longhorn', metavar='w2k|dotnet|longhorn',
835 choices=['w2k','dotnet','longhorn'], dest='cli_ver')
838 def run(self, server, zone, cli_ver, sambaopts=None, credopts=None,
839 versionopts=None):
841 self.lp = sambaopts.get_loadparm()
842 self.creds = credopts.get_credentials(self.lp)
843 dns_conn = dns_connect(server, self.lp, self.creds)
845 zone = zone.lower()
847 client_version = dns_client_version(cli_ver)
848 if client_version == dnsserver.DNS_CLIENT_VERSION_W2K:
849 typeid = dnsserver.DNSSRV_TYPEID_ZONE_CREATE_W2K
850 zone_create_info = dnsserver.DNS_RPC_ZONE_CREATE_INFO_W2K()
851 zone_create_info.pszZoneName = zone
852 zone_create_info.dwZoneType = dnsp.DNS_ZONE_TYPE_PRIMARY
853 zone_create_info.fAllowUpdate = dnsp.DNS_ZONE_UPDATE_SECURE
854 zone_create_info.fAging = 0
855 elif client_version == dnsserver.DNS_CLIENT_VERSION_DOTNET:
856 typeid = dnsserver.DNSSRV_TYPEID_ZONE_CREATE_DOTNET
857 zone_create_info = dnsserver.DNS_RPC_ZONE_CREATE_INFO_DOTNET()
858 zone_create_info.pszZoneName = zone
859 zone_create_info.dwZoneType = dnsp.DNS_ZONE_TYPE_PRIMARY
860 zone_create_info.fAllowUpdate = dnsp.DNS_ZONE_UPDATE_SECURE
861 zone_create_info.fAging = 0
862 zone_create_info.dwDpFlags = dnsserver.DNS_DP_DOMAIN_DEFAULT
863 else:
864 typeid = dnsserver.DNSSRV_TYPEID_ZONE_CREATE
865 zone_create_info = dnsserver.DNS_RPC_ZONE_CREATE_INFO_LONGHORN()
866 zone_create_info.pszZoneName = zone
867 zone_create_info.dwZoneType = dnsp.DNS_ZONE_TYPE_PRIMARY
868 zone_create_info.fAllowUpdate = dnsp.DNS_ZONE_UPDATE_SECURE
869 zone_create_info.fAging = 0
870 zone_create_info.dwDpFlags = dnsserver.DNS_DP_DOMAIN_DEFAULT
872 res = dns_conn.DnssrvOperation2(client_version, 0, server, None,
873 0, 'ZoneCreate', typeid,
874 zone_create_info)
875 self.outf.write('Zone %s created successfully\n' % zone)
878 class cmd_zonedelete(Command):
879 """Delete a zone."""
881 synopsis = '%prog <server> <zone> [options]'
883 takes_args = [ 'server', 'zone' ]
885 takes_optiongroups = {
886 "sambaopts": options.SambaOptions,
887 "versionopts": options.VersionOptions,
888 "credopts": options.CredentialsOptions,
891 def run(self, server, zone, sambaopts=None, credopts=None,
892 versionopts=None):
894 self.lp = sambaopts.get_loadparm()
895 self.creds = credopts.get_credentials(self.lp)
896 dns_conn = dns_connect(server, self.lp, self.creds)
898 zone = zone.lower()
899 res = dns_conn.DnssrvOperation2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
900 0, server, zone, 0, 'DeleteZoneFromDs',
901 dnsserver.DNSSRV_TYPEID_NULL,
902 None)
903 self.outf.write('Zone %s delete successfully\n' % zone)
906 class cmd_query(Command):
907 """Query a name."""
909 synopsis = '%prog <server> <zone> <name> <A|AAAA|CNAME|MX|NS|SOA|SRV|TXT|ALL> [options]'
911 takes_args = [ 'server', 'zone', 'name', 'rtype' ]
913 takes_optiongroups = {
914 "sambaopts": options.SambaOptions,
915 "versionopts": options.VersionOptions,
916 "credopts": options.CredentialsOptions,
919 takes_options = [
920 Option('--authority', help='Search authoritative records (default)',
921 action='store_true', dest='authority'),
922 Option('--cache', help='Search cached records',
923 action='store_true', dest='cache'),
924 Option('--glue', help='Search glue records',
925 action='store_true', dest='glue'),
926 Option('--root', help='Search root hints',
927 action='store_true', dest='root'),
928 Option('--additional', help='List additional records',
929 action='store_true', dest='additional'),
930 Option('--no-children', help='Do not list children',
931 action='store_true', dest='no_children'),
932 Option('--only-children', help='List only children',
933 action='store_true', dest='only_children')
936 def run(self, server, zone, name, rtype, authority=False, cache=False,
937 glue=False, root=False, additional=False, no_children=False,
938 only_children=False, sambaopts=None, credopts=None,
939 versionopts=None):
940 record_type = dns_type_flag(rtype)
942 select_flags = 0
943 if authority:
944 select_flags |= dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA
945 if cache:
946 select_flags |= dnsserver.DNS_RPC_VIEW_CACHE_DATA
947 if glue:
948 select_flags |= dnsserver.DNS_RPC_VIEW_GLUE_DATA
949 if root:
950 select_flags |= dnsserver.DNS_RPC_VIEW_ROOT_HINT_DATA
951 if additional:
952 select_flags |= dnsserver.DNS_RPC_VIEW_ADDITIONAL_DATA
953 if no_children:
954 select_flags |= dnsserver.DNS_RPC_VIEW_NO_CHILDREN
955 if only_children:
956 select_flags |= dnsserver.DNS_RPC_VIEW_ONLY_CHILDREN
958 if select_flags == 0:
959 select_flags = dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA
961 if select_flags == dnsserver.DNS_RPC_VIEW_ADDITIONAL_DATA:
962 self.outf.write('Specify either --authority or --root along with --additional.\n')
963 self.outf.write('Assuming --authority.\n')
964 select_flags |= dnsserver.DNS_RPC_VIEW_AUTHORITY_DATA
966 self.lp = sambaopts.get_loadparm()
967 self.creds = credopts.get_credentials(self.lp)
968 dns_conn = dns_connect(server, self.lp, self.creds)
970 buflen, res = dns_conn.DnssrvEnumRecords2(
971 dnsserver.DNS_CLIENT_VERSION_LONGHORN, 0, server, zone, name,
972 None, record_type, select_flags, None, None)
973 print_dnsrecords(self.outf, res)
976 class cmd_roothints(Command):
977 """Query root hints."""
979 synopsis = '%prog <server> [<name>] [options]'
981 takes_args = [ 'server', 'name?' ]
983 takes_optiongroups = {
984 "sambaopts": options.SambaOptions,
985 "versionopts": options.VersionOptions,
986 "credopts": options.CredentialsOptions,
989 def run(self, server, name='.', sambaopts=None, credopts=None,
990 versionopts=None):
991 record_type = dnsp.DNS_TYPE_NS
992 select_flags = (dnsserver.DNS_RPC_VIEW_ROOT_HINT_DATA |
993 dnsserver.DNS_RPC_VIEW_ADDITIONAL_DATA)
995 self.lp = sambaopts.get_loadparm()
996 self.creds = credopts.get_credentials(self.lp)
997 dns_conn = dns_connect(server, self.lp, self.creds)
999 buflen, res = dns_conn.DnssrvEnumRecords2(
1000 dnsserver.DNS_CLIENT_VERSION_LONGHORN, 0, server, '..RootHints',
1001 name, None, record_type, select_flags, None, None)
1002 print_dnsrecords(self.outf, res)
1005 class cmd_add_record(Command):
1006 """Add a DNS record
1008 For each type data contents are as follows:
1009 A ipv4_address_string
1010 AAAA ipv6_address_string
1011 PTR fqdn_string
1012 CNAME fqdn_string
1013 NS fqdn_string
1014 MX "fqdn_string preference"
1015 SRV "fqdn_string port priority weight"
1016 TXT "'string1' 'string2' ..."
1019 synopsis = '%prog <server> <zone> <name> <A|AAAA|PTR|CNAME|NS|MX|SRV|TXT> <data>'
1021 takes_args = [ 'server', 'zone', 'name', 'rtype', 'data' ]
1023 takes_optiongroups = {
1024 "sambaopts": options.SambaOptions,
1025 "versionopts": options.VersionOptions,
1026 "credopts": options.CredentialsOptions,
1029 def run(self, server, zone, name, rtype, data, sambaopts=None,
1030 credopts=None, versionopts=None):
1032 if rtype.upper() not in ('A','AAAA','PTR','CNAME','NS','MX','SRV','TXT'):
1033 raise CommandError('Adding record of type %s is not supported' % rtype)
1035 record_type = dns_type_flag(rtype)
1036 rec = data_to_dns_record(record_type, data)
1038 self.lp = sambaopts.get_loadparm()
1039 self.creds = credopts.get_credentials(self.lp)
1040 dns_conn = dns_connect(server, self.lp, self.creds)
1042 rec_match = dns_record_match(dns_conn, server, zone, name, record_type,
1043 data)
1044 if rec_match is not None:
1045 raise CommandError('Record already exists')
1047 add_rec_buf = dnsserver.DNS_RPC_RECORD_BUF()
1048 add_rec_buf.rec = rec
1050 dns_conn.DnssrvUpdateRecord2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
1051 0, server, zone, name, add_rec_buf, None)
1052 self.outf.write('Record added successfully\n')
1055 class cmd_update_record(Command):
1056 """Update a DNS record
1058 For each type data contents are as follows:
1059 A ipv4_address_string
1060 AAAA ipv6_address_string
1061 PTR fqdn_string
1062 CNAME fqdn_string
1063 NS fqdn_string
1064 MX "fqdn_string preference"
1065 SRV "fqdn_string port priority weight"
1066 TXT "'string1' 'string2' ..."
1069 synopsis = '%prog <server> <zone> <name> <A|AAAA|PTR|CNAME|NS|MX|SRV|TXT> <olddata> <newdata>'
1071 takes_args = [ 'server', 'zone', 'name', 'rtype', 'olddata', 'newdata' ]
1073 takes_optiongroups = {
1074 "sambaopts": options.SambaOptions,
1075 "versionopts": options.VersionOptions,
1076 "credopts": options.CredentialsOptions,
1079 def run(self, server, zone, name, rtype, olddata, newdata,
1080 sambaopts=None, credopts=None, versionopts=None):
1082 if rtype.upper() not in ('A','AAAA','PTR','CNAME','NS','MX','SRV','TXT'):
1083 raise CommandError('Updating record of type %s is not supported' % rtype)
1085 record_type = dns_type_flag(rtype)
1086 rec = data_to_dns_record(record_type, newdata)
1088 self.lp = sambaopts.get_loadparm()
1089 self.creds = credopts.get_credentials(self.lp)
1090 dns_conn = dns_connect(server, self.lp, self.creds)
1092 rec_match = dns_record_match(dns_conn, server, zone, name, record_type,
1093 olddata)
1094 if not rec_match:
1095 raise CommandError('Record does not exist')
1097 # Copy properties from existing record to new record
1098 rec.dwFlags = rec_match.dwFlags
1099 rec.dwSerial = rec_match.dwSerial
1100 rec.dwTtlSeconds = rec_match.dwTtlSeconds
1101 rec.dwTimeStamp = rec_match.dwTimeStamp
1103 add_rec_buf = dnsserver.DNS_RPC_RECORD_BUF()
1104 add_rec_buf.rec = rec
1106 del_rec_buf = dnsserver.DNS_RPC_RECORD_BUF()
1107 del_rec_buf.rec = rec_match
1109 dns_conn.DnssrvUpdateRecord2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
1111 server,
1112 zone,
1113 name,
1114 add_rec_buf,
1115 del_rec_buf)
1116 self.outf.write('Record updated succefully\n')
1119 class cmd_delete_record(Command):
1120 """Delete a DNS record
1122 For each type data contents are as follows:
1123 A ipv4_address_string
1124 AAAA ipv6_address_string
1125 PTR fqdn_string
1126 CNAME fqdn_string
1127 NS fqdn_string
1128 MX "fqdn_string preference"
1129 SRV "fqdn_string port priority weight"
1130 TXT "'string1' 'string2' ..."
1133 synopsis = '%prog <server> <zone> <name> <A|AAAA|PTR|CNAME|NS|MX|SRV|TXT> <data>'
1135 takes_args = [ 'server', 'zone', 'name', 'rtype', 'data' ]
1137 takes_optiongroups = {
1138 "sambaopts": options.SambaOptions,
1139 "versionopts": options.VersionOptions,
1140 "credopts": options.CredentialsOptions,
1143 def run(self, server, zone, name, rtype, data, sambaopts=None, credopts=None, versionopts=None):
1145 if rtype.upper() not in ('A','AAAA','PTR','CNAME','NS','MX','SRV','TXT'):
1146 raise CommandError('Deleting record of type %s is not supported' % rtype)
1148 record_type = dns_type_flag(rtype)
1150 self.lp = sambaopts.get_loadparm()
1151 self.creds = credopts.get_credentials(self.lp)
1152 dns_conn = dns_connect(server, self.lp, self.creds)
1154 rec_match = dns_record_match(dns_conn, server, zone, name, record_type, data)
1155 if not rec_match:
1156 raise CommandError('Record does not exist')
1158 del_rec_buf = dnsserver.DNS_RPC_RECORD_BUF()
1159 del_rec_buf.rec = rec_match
1161 dns_conn.DnssrvUpdateRecord2(dnsserver.DNS_CLIENT_VERSION_LONGHORN,
1163 server,
1164 zone,
1165 name,
1166 None,
1167 del_rec_buf)
1168 self.outf.write('Record deleted succefully\n')
1171 class cmd_dns(SuperCommand):
1172 """Domain Name Service (DNS) management."""
1174 subcommands = {}
1175 subcommands['serverinfo'] = cmd_serverinfo()
1176 subcommands['zoneinfo'] = cmd_zoneinfo()
1177 subcommands['zonelist'] = cmd_zonelist()
1178 subcommands['zonecreate'] = cmd_zonecreate()
1179 subcommands['zonedelete'] = cmd_zonedelete()
1180 subcommands['query'] = cmd_query()
1181 subcommands['roothints'] = cmd_roothints()
1182 subcommands['add'] = cmd_add_record()
1183 subcommands['update'] = cmd_update_record()
1184 subcommands['delete'] = cmd_delete_record()