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 (
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
)
39 def bool_string(flag
):
45 ret
= 'UNKNOWN (0x%x)' % flag
48 def enum_string(module
, enum_defs
, value
):
51 if value
== getattr(module
, e
):
55 ret
= 'UNKNOWN (0x%x)' % value
58 def bitmap_string(module
, bitmap_defs
, value
):
61 if value
& getattr(module
, b
):
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
):
115 for i
in xrange(array
.AddrCount
):
116 addr
= '%s' % inet_ntoa(pack('i', array
.AddrArray
[i
]))
120 def dns_addr_array_string(array
):
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]])
136 def dns_type_flag(rec_type
):
137 rtype
= rec_type
.upper()
139 record_type
= dnsp
.DNS_TYPE_A
140 elif rtype
== 'AAAA':
141 record_type
= dnsp
.DNS_TYPE_AAAA
143 record_type
= dnsp
.DNS_TYPE_PTR
145 record_type
= dnsp
.DNS_TYPE_NS
146 elif rtype
== 'CNAME':
147 record_type
= dnsp
.DNS_TYPE_CNAME
149 record_type
= dnsp
.DNS_TYPE_SOA
151 record_type
= dnsp
.DNS_TYPE_MX
153 record_type
= dnsp
.DNS_TYPE_SRV
155 record_type
= dnsp
.DNS_TYPE_ALL
157 raise CommandError('Unknown type of DNS record %s' % rec_type
)
160 def dns_client_version(cli_version
):
161 version
= cli_version
.upper()
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
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
))
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
))
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
))
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
))
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
))
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
:
324 print_zone(outf
, typeid
, zone
)
327 def print_dns_record(outf
, rec
):
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' % (
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' % (
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
,
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
375 class AAAARecord(dnsserver
.DNS_RPC_RECORD
):
376 def __init__(self
, ip6_addr
, serial
=1, ttl
=900, rank
=dnsp
.DNS_RANK_ZONE
,
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
385 class PTRRecord(dnsserver
.DNS_RPC_RECORD
):
386 def __init__(self
, ptr
, serial
=1, ttl
=900, rank
=dnsp
.DNS_RANK_ZONE
,
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()
395 ptr_name
.len = len(ptr
)
398 class CNameRecord(dnsserver
.DNS_RPC_RECORD
):
399 def __init__(self
, cname
, serial
=1, ttl
=900, rank
=dnsp
.DNS_RANK_ZONE
,
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
,
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()
421 ns
.len = len(dns_server
)
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
)
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
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
)
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
470 srv
.nameTarget
.str = target
471 srv
.nameTarget
.len = len(target
)
475 # Convert data into a dns record
476 def data_to_dns_record(record_type
, data
):
477 if record_type
== dnsp
.DNS_TYPE_A
:
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
:
487 elif record_type
== dnsp
.DNS_TYPE_MX
:
488 tmp
= data
.split(' ')
490 raise CommandError('Data requires 2 elements - mail_server, preference')
492 preference
= int(tmp
[1])
493 rec
= MXRecord(mail_server
, preference
)
494 elif record_type
== dnsp
.DNS_TYPE_SRV
:
495 tmp
= data
.split(' ')
497 raise CommandError('Data requires 4 elements - server, port, priority, weight')
500 priority
= int(tmp
[2])
502 rec
= SRVRecord(server
, port
, priority
=priority
, weight
=weight
)
503 elif record_type
== dnsp
.DNS_TYPE_SOA
:
504 tmp
= data
.split(' ')
506 raise CommandError('Data requires 7 elements - nameserver, email, serial, '
507 'refresh, retry, expire, minimumttl')
511 refresh
= int(tmp
[3])
514 minimum
= int(tmp
[6])
515 rec
= SOARecord(nameserver
, email
, serial
=serial
, refresh
=refresh
,
516 retry
=retry
, expire
=expire
, minimum
=minimum
)
518 raise CommandError('Unsupported record type')
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
534 buflen
, res
= dns_conn
.DnssrvEnumRecords2(dnsserver
.DNS_CLIENT_VERSION_LONGHORN
,
544 except RuntimeError, e
:
547 if not res
or res
.count
== 0:
551 for rec
in res
.rec
[0].records
:
552 if rec
.wType
!= record_type
:
556 if record_type
== dnsp
.DNS_TYPE_A
:
557 if rec
.data
== urec
.data
:
559 elif record_type
== dnsp
.DNS_TYPE_AAAA
:
560 if rec
.data
== urec
.data
:
562 elif record_type
== dnsp
.DNS_TYPE_PTR
:
563 if dns_name_equal(rec
.data
, urec
.data
):
565 elif record_type
== dnsp
.DNS_TYPE_CNAME
:
566 if dns_name_equal(rec
.data
, urec
.data
):
568 elif record_type
== dnsp
.DNS_TYPE_NS
:
569 if dns_name_equal(rec
.data
, urec
.data
):
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
:
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
):
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
):
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
,
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
,
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
,
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
,
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
,
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):
708 request_filter |
= dnsserver
.DNS_ZONE_REQUEST_PRIMARY
710 request_filter |
= dnsserver
.DNS_ZONE_REQUEST_SECONDARY
712 request_filter |
= dnsserver
.DNS_ZONE_REQUEST_CACHE
714 request_filter |
= dnsserver
.DNS_ZONE_REQUEST_AUTO
716 request_filter |
= dnsserver
.DNS_ZONE_REQUEST_FORWARD
718 request_filter |
= dnsserver
.DNS_ZONE_REQUEST_REVERSE
720 request_filter |
= dnsserver
.DNS_ZONE_REQUEST_DS
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
,
738 dnsserver
.DNSSRV_TYPEID_DWORD
,
741 if client_version
== dnsserver
.DNS_CLIENT_VERSION_W2K
:
742 typeid
= dnsserver
.DNSSRV_TYPEID_ZONE_W2K
744 typeid
= dnsserver
.DNSSRV_TYPEID_ZONE
745 print_enumzones(self
.outf
, typeid
, res
)
748 class cmd_zonecreate(Command
):
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
,
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,
770 self
.lp
= sambaopts
.get_loadparm()
771 self
.creds
= credopts
.get_credentials(self
.lp
)
772 dns_conn
= dns_connect(server
, self
.lp
, self
.creds
)
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
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
,
809 self
.outf
.write('Zone %s created successfully\n' % zone
)
812 class cmd_zonedelete(Command
):
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
)
832 res
= dns_conn
.DnssrvOperation2(dnsserver
.DNS_CLIENT_VERSION_LONGHORN
,
838 dnsserver
.DNSSRV_TYPEID_NULL
,
840 self
.outf
.write('Zone %s delete successfully\n' % zone
)
843 class cmd_query(Command
):
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
,
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
)
880 select_flags |
= dnsserver
.DNS_RPC_VIEW_AUTHORITY_DATA
882 select_flags |
= dnsserver
.DNS_RPC_VIEW_CACHE_DATA
884 select_flags |
= dnsserver
.DNS_RPC_VIEW_GLUE_DATA
886 select_flags |
= dnsserver
.DNS_RPC_VIEW_ROOT_HINT_DATA
888 select_flags |
= dnsserver
.DNS_RPC_VIEW_ADDITIONAL_DATA
890 select_flags |
= dnsserver
.DNS_RPC_VIEW_NO_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
,
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
,
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
:
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
:
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
,
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
)
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
)
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
,
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
:
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
)
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
)
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
,
1113 self
.outf
.write('Record deleted succefully\n')
1116 class cmd_dns(SuperCommand
):
1117 """Domain Name Service (DNS) management"""
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()