1 # Unix SMB/CIFS implementation.
2 # backend code for provisioning DNS for a Samba4 server
4 # Copyright (C) Kai Blin <kai@samba.org> 2011
5 # Copyright (C) Amitay Isaacs <amitay@gmail.com> 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 """DNS-related provisioning"""
27 from samba
.ndr
import ndr_pack
, ndr_unpack
28 from samba
import read_and_sub_file
29 from samba
.dcerpc
import dnsp
, misc
30 from samba
.dsdb
import (
31 DS_DOMAIN_FUNCTION_2000
,
32 DS_DOMAIN_FUNCTION_2003
,
33 DS_DOMAIN_FUNCTION_2008
,
34 DS_DOMAIN_FUNCTION_2008_R2
38 def add_ldif(ldb
, ldif_file
, subst_vars
, controls
=["relax:0"]):
39 ldif_file_path
= os
.path
.join(samba
.param
.setup_dir(), ldif_file
)
40 data
= read_and_sub_file(ldif_file_path
, subst_vars
)
41 ldb
.add_ldif(data
, controls
)
43 def modify_ldif(ldb
, ldif_file
, subst_vars
, controls
=["relax:0"]):
44 ldif_file_path
= os
.path
.join(samba
.param
.setup_dir(), ldif_file
)
45 data
= read_and_sub_file(ldif_file_path
, subst_vars
)
46 ldb
.modify_ldif(data
, controls
)
48 def get_domainguid(samdb
, domaindn
):
49 res
= samdb
.search(base
=domaindn
, scope
=ldb
.SCOPE_BASE
, attrs
=["objectGUID"])
50 domainguid
= str(ndr_unpack(misc
.GUID
, res
[0]["objectGUID"][0]))
53 def get_ntdsguid(samdb
, domaindn
):
54 configdn
= samdb
.get_config_basedn()
56 res1
= samdb
.search(base
="OU=Domain Controllers,%s" % domaindn
, scope
=ldb
.SCOPE_ONELEVEL
,
57 attrs
=["dNSHostName"])
59 res2
= samdb
.search(expression
="serverReference=%s" % res1
[0].dn
, base
=configdn
)
61 res3
= samdb
.search(base
="CN=NTDS Settings,%s" % res2
[0].dn
, scope
=ldb
.SCOPE_BASE
,
63 ntdsguid
= str(ndr_unpack(misc
.GUID
, res3
[0]["objectGUID"][0]))
67 class ARecord(dnsp
.DnssrvRpcRecord
):
68 def __init__(self
, ip_addr
, serial
=1, ttl
=900):
69 super(ARecord
, self
).__init
__()
70 self
.wType
= dnsp
.DNS_TYPE_A
71 self
.dwSerial
= serial
72 self
.dwTtlSeconds
= ttl
75 class AAAARecord(dnsp
.DnssrvRpcRecord
):
76 def __init__(self
, ip6_addr
, serial
=1, ttl
=900):
77 super(AAAARecord
, self
).__init
__()
78 self
.wType
= dnsp
.DNS_TYPE_AAAA
79 self
.dwSerial
= serial
80 self
.dwTtlSeconds
= ttl
83 class CNameRecord(dnsp
.DnssrvRpcRecord
):
84 def __init__(self
, cname
, serial
=1, ttl
=900):
85 super(CNameRecord
, self
).__init
__()
86 self
.wType
= dnsp
.DNS_TYPE_CNAME
87 self
.dwSerial
= serial
88 self
.dwTtlSeconds
= ttl
91 class NSRecord(dnsp
.DnssrvRpcRecord
):
92 def __init__(self
, dns_server
, serial
=1, ttl
=900):
93 super(NSRecord
, self
).__init
__()
94 self
.wType
= dnsp
.DNS_TYPE_NS
95 self
.dwSerial
= serial
96 self
.dwTtlSeconds
= ttl
97 self
.data
= dns_server
99 class RootNSRecord(dnsp
.DnssrvRpcRecord
):
100 def __init__(self
, dns_server
, serial
=1, ttl
=3600):
101 super(RootNSRecord
, self
).__init
__()
102 self
.wType
= dnsp
.DNS_TYPE_NS
103 self
.dwSerial
= serial
104 self
.dwTtlSeconds
= ttl
105 self
.data
= dns_server
106 self
.rank
= dnsp
.DNS_RANK_ROOT_HINT
108 class SOARecord(dnsp
.DnssrvRpcRecord
):
109 def __init__(self
, mname
, rname
, serial
=1, refresh
=900, retry
=600,
110 expire
=86400, minimum
=3600, ttl
=3600):
111 super(SOARecord
, self
).__init
__()
112 self
.wType
= dnsp
.DNS_TYPE_SOA
113 self
.dwSerial
= serial
114 self
.dwTtlSeconds
= ttl
117 soa
.refresh
= refresh
124 class SRVRecord(dnsp
.DnssrvRpcRecord
):
125 def __init__(self
, target
, port
, priority
=0, weight
=100, serial
=1, ttl
=900):
126 super(SRVRecord
, self
).__init
__()
127 self
.wType
= dnsp
.DNS_TYPE_SRV
128 self
.dwSerial
= serial
129 self
.dwTtlSeconds
= ttl
131 srv
.nameTarget
= target
133 srv
.wPriority
= priority
138 def setup_dns_partitions(samdb
, domaindn
, forestdn
, configdn
, serverdn
):
140 # FIXME: Default security descriptor for Domain-DNS objectCategory is different in
141 # our documentation from windows
143 domainzone_dn
= "DC=DomainDnsZones,%s" % domaindn
144 forestzone_dn
= "DC=ForestDnsZones,%s" % forestdn
146 add_ldif(samdb
, "provision_dnszones_partitions.ldif", {
147 "DOMAINZONE_DN": domainzone_dn
,
148 "FORESTZONE_DN": forestzone_dn
,
151 domainzone_guid
= get_domainguid(samdb
, domainzone_dn
)
152 forestzone_guid
= get_domainguid(samdb
, forestzone_dn
)
154 domainzone_guid
= str(uuid
.uuid4())
155 forestzone_guid
= str(uuid
.uuid4())
157 domainzone_dns
= ldb
.Dn(samdb
, domainzone_dn
).canonical_ex_str().strip()
158 forestzone_dns
= ldb
.Dn(samdb
, forestzone_dn
).canonical_ex_str().strip()
160 add_ldif(samdb
, "provision_dnszones_add.ldif", {
161 "DOMAINZONE_DN": domainzone_dn
,
162 "FORESTZONE_DN": forestzone_dn
,
163 "DOMAINZONE_GUID": domainzone_guid
,
164 "FORESTZONE_GUID": forestzone_guid
,
165 "DOMAINZONE_DNS": domainzone_dns
,
166 "FORESTZONE_DNS": forestzone_dns
,
167 "CONFIGDN": configdn
,
168 "SERVERDN": serverdn
,
171 modify_ldif(samdb
, "provision_dnszones_modify.ldif", {
172 "CONFIGDN": configdn
,
173 "SERVERDN": serverdn
,
174 "DOMAINZONE_DN": domainzone_dn
,
175 "FORESTZONE_DN": forestzone_dn
,
179 def add_dns_accounts(samdb
, domaindn
):
180 add_ldif(samdb
, "provision_dns_accounts_add.ldif", {
181 "DOMAINDN": domaindn
,
184 def add_dns_container(samdb
, domaindn
, prefix
):
185 # CN=MicrosoftDNS,<PREFIX>,<DOMAINDN>
186 msg
= ldb
.Message(ldb
.Dn(samdb
, "CN=MicrosoftDNS,%s,%s" % (prefix
, domaindn
)))
187 msg
["objectClass"] = ["top", "container"]
188 msg
["displayName"] = ldb
.MessageElement("DNS Servers", ldb
.FLAG_MOD_ADD
, "displayName")
192 def add_rootservers(samdb
, domaindn
, prefix
):
194 rootservers
["a.root-servers.net"] = "198.41.0.4"
195 rootservers
["b.root-servers.net"] = "192.228.79.201"
196 rootservers
["c.root-servers.net"] = "192.33.4.12"
197 rootservers
["d.root-servers.net"] = "128.8.10.90"
198 rootservers
["e.root-servers.net"] = "192.203.230.10"
199 rootservers
["f.root-servers.net"] = "192.5.5.241"
200 rootservers
["g.root-servers.net"] = "192.112.36.4"
201 rootservers
["h.root-servers.net"] = "128.63.2.53"
202 rootservers
["i.root-servers.net"] = "192.36.148.17"
203 rootservers
["j.root-servers.net"] = "192.58.128.30"
204 rootservers
["k.root-servers.net"] = "193.0.14.129"
205 rootservers
["l.root-servers.net"] = "199.7.83.42"
206 rootservers
["m.root-servers.net"] = "202.12.27.33"
209 rootservers_v6
["a.root-servers.net"] = "2001:503:ba3e::2:30"
210 rootservers_v6
["f.root-servers.net"] = "2001:500:2f::f"
211 rootservers_v6
["h.root-servers.net"] = "2001:500:1::803f:235"
212 rootservers_v6
["j.root-servers.net"] = "2001:503:c27::2:30"
213 rootservers_v6
["k.root-servers.net"] = "2001:7fd::1"
214 rootservers_v6
["m.root-servers.net"] = "2001:dc3::35"
216 container_dn
= "DC=RootDNSServers,CN=MicrosoftDNS,%s,%s" % (prefix
, domaindn
)
218 # Add DC=RootDNSServers,CN=MicrosoftDNS,<PREFIX>,<DOMAINDN>
219 msg
= ldb
.Message(ldb
.Dn(samdb
, container_dn
))
220 msg
["objectClass"] = ["top", "dnsZone"]
223 # Add DC=@,DC=RootDNSServers,CN=MicrosoftDNS,<PREFIX>,<DOMAINDN>
225 for rserver
in rootservers
:
226 record
.append(ndr_pack(RootNSRecord(rserver
, serial
=0, ttl
=0)))
228 msg
= ldb
.Message(ldb
.Dn(samdb
, "DC=@,%s" % container_dn
))
229 msg
["objectClass"] = ["top", "dnsNode"]
230 msg
["dnsRecord"] = ldb
.MessageElement(record
, ldb
.FLAG_MOD_ADD
, "dnsRecord")
233 # Add DC=<rootserver>,DC=RootDNSServers,CN=MicrosoftDNS,<PREFIX>,<DOMAINDN>
234 for rserver
in rootservers
:
235 record
= [ndr_pack(ARecord(rootservers
[rserver
], serial
=0, ttl
=0))]
236 # Add AAAA record as well (How does W2K* add IPv6 records?)
237 #if rserver in rootservers_v6:
238 # record.append(ndr_pack(AAAARecord(rootservers_v6[rserver], serial=0, ttl=0)))
239 msg
= ldb
.Message(ldb
.Dn(samdb
, "DC=%s,%s" % (rserver
, container_dn
)))
240 msg
["objectClass"] = ["top", "dnsNode"]
241 msg
["dnsRecord"] = ldb
.MessageElement(record
, ldb
.FLAG_MOD_ADD
, "dnsRecord")
244 def add_at_record(samdb
, container_dn
, prefix
, hostname
, dnsdomain
, hostip
, hostip6
):
246 fqdn_hostname
= "%s.%s" % (hostname
, dnsdomain
)
251 at_soa_record
= SOARecord(fqdn_hostname
, "hostmaster.%s" % dnsdomain
)
252 at_records
.append(ndr_pack(at_soa_record
))
255 at_ns_record
= NSRecord(fqdn_hostname
)
256 at_records
.append(ndr_pack(at_ns_record
))
258 if hostip
is not None:
260 at_a_record
= ARecord(hostip
)
261 at_records
.append(ndr_pack(at_a_record
))
263 if hostip6
is not None:
265 at_aaaa_record
= AAAARecord(hostip6
)
266 at_records
.append(ndr_pack(at_aaaa_record
))
268 msg
= ldb
.Message(ldb
.Dn(samdb
, "DC=@,%s" % container_dn
))
269 msg
["objectClass"] = ["top", "dnsNode"]
270 msg
["dnsRecord"] = ldb
.MessageElement(at_records
, ldb
.FLAG_MOD_ADD
, "dnsRecord")
273 def add_srv_record(samdb
, container_dn
, prefix
, host
, port
):
274 srv_record
= SRVRecord(host
, port
)
275 msg
= ldb
.Message(ldb
.Dn(samdb
, "%s,%s" % (prefix
, container_dn
)))
276 msg
["objectClass"] = ["top", "dnsNode"]
277 msg
["dnsRecord"] = ldb
.MessageElement(ndr_pack(srv_record
), ldb
.FLAG_MOD_ADD
, "dnsRecord")
280 def add_ns_record(samdb
, container_dn
, prefix
, host
):
281 ns_record
= NSRecord(host
)
282 msg
= ldb
.Message(ldb
.Dn(samdb
, "%s,%s" % (prefix
, container_dn
)))
283 msg
["objectClass"] = ["top", "dnsNode"]
284 msg
["dnsRecord"] = ldb
.MessageElement(ndr_pack(ns_record
), ldb
.FLAG_MOD_ADD
, "dnsRecord")
287 def add_cname_record(samdb
, container_dn
, prefix
, host
):
288 cname_record
= CNameRecord(host
)
289 msg
= ldb
.Message(ldb
.Dn(samdb
, "%s,%s" % (prefix
, container_dn
)))
290 msg
["objectClass"] = ["top", "dnsNode"]
291 msg
["dnsRecord"] = ldb
.MessageElement(ndr_pack(cname_record
), ldb
.FLAG_MOD_ADD
, "dnsRecord")
294 def add_host_record(samdb
, container_dn
, prefix
, hostip
, hostip6
):
297 a_record
= ARecord(hostip
)
298 host_records
.append(ndr_pack(a_record
))
300 aaaa_record
= AAAARecord(hostip6
)
301 host_records
.append(ndr_pack(aaaa_record
))
303 msg
= ldb
.Message(ldb
.Dn(samdb
, "%s,%s" % (prefix
, container_dn
)))
304 msg
["objectClass"] = ["top", "dnsNode"]
305 msg
["dnsRecord"] = ldb
.MessageElement(host_records
, ldb
.FLAG_MOD_ADD
, "dnsRecord")
308 def add_domain_record(samdb
, domaindn
, prefix
, dnsdomain
):
309 # DC=<DNSDOMAIN>,CN=MicrosoftDNS,<PREFIX>,<DOMAINDN>
310 msg
= ldb
.Message(ldb
.Dn(samdb
, "DC=%s,CN=MicrosoftDNS,%s,%s" % (dnsdomain
, prefix
, domaindn
)))
311 msg
["objectClass"] = ["top", "dnsZone"]
314 def add_msdcs_record(samdb
, forestdn
, prefix
, dnsforest
):
315 # DC=_msdcs.<DNSFOREST>,CN=MicrosoftDNS,<PREFIX>,<FORESTDN>
316 msg
= ldb
.Message(ldb
.Dn(samdb
, "DC=_msdcs.%s,CN=MicrosoftDNS,%s,%s" %
317 (dnsforest
, prefix
, forestdn
)))
318 msg
["objectClass"] = ["top", "dnsZone"]
322 def add_dc_domain_records(samdb
, domaindn
, prefix
, site
, dnsdomain
, hostname
, hostip
, hostip6
):
324 fqdn_hostname
= "%s.%s" % (hostname
, dnsdomain
)
326 # Set up domain container - DC=<DNSDOMAIN>,CN=MicrosoftDNS,<PREFIX>,<DOMAINDN>
327 domain_container_dn
= ldb
.Dn(samdb
, "DC=%s,CN=MicrosoftDNS,%s,%s" %
328 (dnsdomain
, prefix
, domaindn
))
331 add_at_record(samdb
, domain_container_dn
, "DC=@", hostname
, dnsdomain
, hostip
, hostip6
)
333 # DC=<HOSTNAME> record
334 add_host_record(samdb
, domain_container_dn
, "DC=%s" % hostname
, hostip
, hostip6
)
336 # DC=_kerberos._tcp record
337 add_srv_record(samdb
, domain_container_dn
, "DC=_kerberos._tcp", fqdn_hostname
, 88)
339 # DC=_kerberos._tcp.<SITENAME>._sites record
340 add_srv_record(samdb
, domain_container_dn
, "DC=_kerberos._tcp.%s._sites" % site
,
343 # DC=_kerberos._udp record
344 add_srv_record(samdb
, domain_container_dn
, "DC=_kerberos._udp", fqdn_hostname
, 88)
346 # DC=_kpasswd._tcp record
347 add_srv_record(samdb
, domain_container_dn
, "DC=_kpasswd._tcp", fqdn_hostname
, 464)
349 # DC=_kpasswd._udp record
350 add_srv_record(samdb
, domain_container_dn
, "DC=_kpasswd._udp", fqdn_hostname
, 464)
352 # DC=_ldap._tcp record
353 add_srv_record(samdb
, domain_container_dn
, "DC=_ldap._tcp", fqdn_hostname
, 389)
355 # DC=_ldap._tcp.<SITENAME>._sites record
356 add_srv_record(samdb
, domain_container_dn
, "DC=_ldap._tcp.%s._sites" % site
,
359 # FIXME: The number of SRV records depend on the various roles this DC has.
360 # _gc and _msdcs records are added if the we are the forest dc and not subdomain dc
362 # Assumption: current DC is GC and add all the entries
365 add_srv_record(samdb
, domain_container_dn
, "DC=_gc._tcp", fqdn_hostname
, 3268)
367 # DC=_gc._tcp.<SITENAME>,_sites record
368 add_srv_record(samdb
, domain_container_dn
, "DC=_gc._tcp.%s._sites" % site
, fqdn_hostname
, 3268)
371 add_ns_record(samdb
, domain_container_dn
, "DC=_msdcs", fqdn_hostname
)
373 # FIXME: Following entries are added only if DomainDnsZones and ForestDnsZones partitions
376 # Assumption: Additional entries won't hurt on os_level = 2000
378 # DC=_ldap._tcp.<SITENAME>._sites.DomainDnsZones
379 add_srv_record(samdb
, domain_container_dn
, "DC=_ldap._tcp.%s._sites.DomainDnsZones" % site
,
382 # DC=_ldap._tcp.<SITENAME>._sites.ForestDnsZones
383 add_srv_record(samdb
, domain_container_dn
, "DC=_ldap._tcp.%s._sites.ForestDnsZones" % site
,
386 # DC=_ldap._tcp.DomainDnsZones
387 add_srv_record(samdb
, domain_container_dn
, "DC=_ldap._tcp.DomainDnsZones",
390 # DC=_ldap._tcp.ForestDnsZones
391 add_srv_record(samdb
, domain_container_dn
, "DC=_ldap._tcp.ForestDnsZones",
395 add_host_record(samdb
, domain_container_dn
, "DC=DomainDnsZones", hostip
, hostip6
)
398 add_host_record(samdb
, domain_container_dn
, "DC=ForestDnsZones", hostip
, hostip6
)
401 def add_dc_msdcs_records(samdb
, forestdn
, prefix
, site
, dnsforest
, hostname
,
402 hostip
, hostip6
, domainguid
, ntdsguid
):
404 fqdn_hostname
= "%s.%s" % (hostname
, dnsforest
)
406 # Set up forest container - DC=<DNSDOMAIN>,CN=MicrosoftDNS,<PREFIX>,<DOMAINDN>
407 forest_container_dn
= ldb
.Dn(samdb
, "DC=_msdcs.%s,CN=MicrosoftDNS,%s,%s" %
408 (dnsforest
, prefix
, forestdn
))
411 add_at_record(samdb
, forest_container_dn
, "DC=@", hostname
, dnsforest
, None, None)
413 # DC=_kerberos._tcp.dc record
414 add_srv_record(samdb
, forest_container_dn
, "DC=_kerberos._tcp.dc", fqdn_hostname
, 88)
416 # DC=_kerberos._tcp.<SITENAME>._sites.dc record
417 add_srv_record(samdb
, forest_container_dn
, "DC=_kerberos._tcp.%s._sites.dc" % site
,
420 # DC=_ldap._tcp.dc record
421 add_srv_record(samdb
, forest_container_dn
, "DC=_ldap._tcp.dc", fqdn_hostname
, 389)
423 # DC=_ldap._tcp.<SITENAME>._sites.dc record
424 add_srv_record(samdb
, forest_container_dn
, "DC=_ldap._tcp.%s._sites.dc" % site
,
427 # DC=_ldap._tcp.<SITENAME>._sites.gc record
428 add_srv_record(samdb
, forest_container_dn
, "DC=_ldap._tcp.%s._sites.gc" % site
,
431 # DC=_ldap._tcp.gc record
432 add_srv_record(samdb
, forest_container_dn
, "DC=_ldap._tcp.gc", fqdn_hostname
, 3268)
434 # DC=_ldap._tcp.pdc record
435 add_srv_record(samdb
, forest_container_dn
, "DC=_ldap._tcp.pdc", fqdn_hostname
, 389)
438 add_host_record(samdb
, forest_container_dn
, "DC=gc", hostip
, hostip6
)
440 # DC=_ldap._tcp.<DOMAINGUID>.domains record
441 add_srv_record(samdb
, forest_container_dn
, "DC=_ldap._tcp.%s.domains" % domainguid
,
445 add_cname_record(samdb
, forest_container_dn
, "DC=%s" % ntdsguid
, fqdn_hostname
)
448 def setup_ad_dns(samdb
, names
, logger
, hostip
=None, hostip6
=None, dns_backend
=None,
450 """Provision DNS information (assuming GC role)
452 :param samdb: LDB object connected to sam.ldb file
453 :param names: Names shortcut
454 :param logger: Logger object
455 :param hostip: IPv4 address
456 :param hostip6: IPv6 address
457 :param dns_backend: Type of DNS backend
458 :param os_level: Functional level (treated as os level)
461 if dns_backend
is None:
462 dns_backend
= "BIND9_FLATFILE"
463 logger
.info("Assuming bind9 DNS server backend")
465 # If dns_backend is BIND9_FLATFILE
466 # Populate only CN=MicrosoftDNS,CN=System,<DOMAINDN>
468 # If dns_backend is SAMBA or BIND9_DLZ
469 # Populate DNS partitions
472 os_level
= DS_DOMAIN_FUNCTION_2003
474 # If os_level < 2003 (DS_DOMAIN_FUNCTION_2000)
475 # All dns records are in CN=MicrosoftDNS,CN=System,<DOMAINDN>
477 # If os_level >= 2003 (DS_DOMAIN_FUNCTION_2003, DS_DOMAIN_FUNCTION_2008,
478 # DS_DOMAIN_FUNCTION_2008_R2)
479 # Root server records are in CN=MicrosoftDNS,CN=System,<DOMAINDN>
480 # Domain records are in CN=MicrosoftDNS,CN=System,<DOMAINDN>
481 # Domain records are in CN=MicrosoftDNS,DC=DomainDnsZones,<DOMAINDN>
482 # Forest records are in CN=MicrosoftDNS,DC=ForestDnsZones,<DOMAINDN>
484 domaindn
= names
.domaindn
485 forestdn
= samdb
.get_root_basedn().get_linearized()
487 dnsdomain
= names
.dnsdomain
.lower()
488 dnsforest
= dnsdomain
490 hostname
= names
.netbiosname
.lower()
491 site
= names
.sitename
493 domainguid
= get_domainguid(samdb
, domaindn
)
494 ntdsguid
= get_ntdsguid(samdb
, domaindn
)
496 # Add dns accounts (DnsAdmins, DnsUpdateProxy) in domain
497 logger
.info("Adding DNS accounts")
498 add_dns_accounts(samdb
, domaindn
)
500 logger
.info("Populating CN=MicrosoftDNS,CN=System,%s" % domaindn
)
502 # Set up MicrosoftDNS container
503 add_dns_container(samdb
, domaindn
, "CN=System")
506 add_rootservers(samdb
, domaindn
, "CN=System")
508 if os_level
== DS_DOMAIN_FUNCTION_2000
:
511 add_domain_record(samdb
, domaindn
, "CN=System", dnsdomain
)
513 # Add DNS records for a DC in domain
514 add_dc_domain_records(samdb
, domaindn
, "CN=System", site
, dnsdomain
,
515 hostname
, hostip
, hostip6
)
517 elif (dns_backend
== "SAMBA" or dns_backend
== "BIND9_DLZ") and (
518 os_level
== DS_DOMAIN_FUNCTION_2003
or
519 os_level
== DS_DOMAIN_FUNCTION_2008
or
520 os_level
== DS_DOMAIN_FUNCTION_2008_R2
):
522 # Set up additional partitions (DomainDnsZones, ForstDnsZones)
523 logger
.info("Creating DomainDnsZones and ForestDnsZones partitions")
524 setup_dns_partitions(samdb
, domaindn
, forestdn
, names
.configdn
, names
.serverdn
)
526 ##### Set up DC=DomainDnsZones,<DOMAINDN>
527 logger
.info("Populating DomainDnsZones partition")
529 # Set up MicrosoftDNS container
530 add_dns_container(samdb
, domaindn
, "DC=DomainDnsZones")
532 # Add rootserver records
533 add_rootservers(samdb
, domaindn
, "DC=DomainDnsZones")
536 add_domain_record(samdb
, domaindn
, "DC=DomainDnsZones", dnsdomain
)
538 # Add DNS records for a DC in domain
539 add_dc_domain_records(samdb
, domaindn
, "DC=DomainDnsZones", site
, dnsdomain
,
540 hostname
, hostip
, hostip6
)
542 ##### Set up DC=ForestDnsZones,<DOMAINDN>
543 logger
.info("Populating ForestDnsZones partition")
545 # Set up MicrosoftDNS container
546 add_dns_container(samdb
, forestdn
, "DC=ForestDnsZones")
549 add_msdcs_record(samdb
, forestdn
, "DC=ForestDnsZones", dnsforest
)
551 # Add DNS records for a DC in forest
552 add_dc_msdcs_records(samdb
, forestdn
, "DC=ForestDnsZones", site
, dnsforest
,
553 hostname
, hostip
, hostip6
, domainguid
, ntdsguid
)