From: Andrew Bartlett Date: Thu, 21 Jun 2012 13:46:21 +0000 (+1000) Subject: s4-join: Import DNS zones in AD DC join X-Git-Tag: samba-4.0.0beta3~200 X-Git-Url: http://git.samba.org/?p=ddiss%2Fsamba.git;a=commitdiff_plain;h=01f52239dc8e13af6e5134667c55d8e0fb7b2f26 s4-join: Import DNS zones in AD DC join --- diff --git a/source4/dsdb/tests/python/acl.py b/source4/dsdb/tests/python/acl.py index bbd4343a212..94bc504804f 100755 --- a/source4/dsdb/tests/python/acl.py +++ b/source4/dsdb/tests/python/acl.py @@ -1627,6 +1627,7 @@ class AclSPNTests(AclTests): # same as for join_RODC, but do not set any SPNs def create_rodc(self, ctx): + ctx.nc_list = [ ctx.base_dn, ctx.config_dn, ctx.schema_dn ] ctx.krbtgt_dn = "CN=krbtgt_%s,CN=Users,%s" % (ctx.myname, ctx.base_dn) ctx.never_reveal_sid = [ "" % (ctx.domsid, security.DOMAIN_RID_RODC_DENY), @@ -1656,6 +1657,7 @@ class AclSPNTests(AclTests): ctx.join_add_objects() def create_dc(self, ctx): + ctx.nc_list = [ ctx.base_dn, ctx.config_dn, ctx.schema_dn ] ctx.userAccountControl = samba.dsdb.UF_SERVER_TRUST_ACCOUNT | samba.dsdb.UF_TRUSTED_FOR_DELEGATION ctx.secure_channel_type = misc.SEC_CHAN_BDC ctx.replica_flags = (drsuapi.DRSUAPI_DRS_WRIT_REP | diff --git a/source4/scripting/python/samba/join.py b/source4/scripting/python/samba/join.py index a683ee6963e..b1901e0421c 100644 --- a/source4/scripting/python/samba/join.py +++ b/source4/scripting/python/samba/join.py @@ -47,13 +47,20 @@ class dc_join(object): def __init__(ctx, server=None, creds=None, lp=None, site=None, netbios_name=None, targetdir=None, domain=None, - machinepass=None, use_ntvfs=False): + machinepass=None, use_ntvfs=False, dns_backend=None): ctx.creds = creds ctx.lp = lp ctx.site = site ctx.netbios_name = netbios_name ctx.targetdir = targetdir ctx.use_ntvfs = use_ntvfs + if dns_backend is None: + ctx.dns_backend = "NONE" + else: + ctx.dns_backend = dns_backend + + ctx.nc_list = [] + ctx.full_nc_list = [] ctx.creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL) ctx.net = Net(creds=ctx.creds, lp=ctx.lp) @@ -402,14 +409,14 @@ class dc_join(object): if ctx.RODC: rec["objectCategory"] = "CN=NTDS-DSA-RO,%s" % ctx.schema_dn - rec["msDS-HasFullReplicaNCs"] = nc_list + rec["msDS-HasFullReplicaNCs"] = ctx.nc_list rec["options"] = "37" ctx.samdb.add(rec, ["rodc_join:1:1"]) else: rec["objectCategory"] = "CN=NTDS-DSA,%s" % ctx.schema_dn rec["HasMasterNCs"] = nc_list if ctx.behavior_version >= samba.dsdb.DS_DOMAIN_FUNCTION_2003: - rec["msDS-HasMasterNCs"] = nc_list + rec["msDS-HasMasterNCs"] = ctx.nc_list rec["options"] = "1" rec["invocationId"] = ndr_pack(ctx.invocation_id) ctx.DsAddEntry([rec]) @@ -555,7 +562,7 @@ class dc_join(object): rec2["objectCategory"] = "CN=NTDS-DSA,%s" % ctx.schema_dn rec2["HasMasterNCs"] = nc_list if ctx.behavior_version >= samba.dsdb.DS_DOMAIN_FUNCTION_2003: - rec2["msDS-HasMasterNCs"] = nc_list + rec2["msDS-HasMasterNCs"] = ctx.nc_list rec2["options"] = "1" rec2["invocationId"] = ndr_pack(ctx.invocation_id) @@ -596,7 +603,7 @@ class dc_join(object): hostname=ctx.myname, domainsid=ctx.domsid, machinepass=ctx.acct_pass, serverrole="domain controller", sitename=ctx.site, lp=ctx.lp, ntdsguid=ctx.ntds_guid, - use_ntvfs=ctx.use_ntvfs, dns_backend="NONE") + use_ntvfs=ctx.use_ntvfs, dns_backend=ctx.dns_backend) print "Provision OK for domain DN %s" % presult.domaindn ctx.local_samdb = presult.samdb ctx.lp = presult.lp @@ -687,6 +694,17 @@ class dc_join(object): repl.replicate(ctx.base_dn, source_dsa_invocation_id, destination_dsa_guid, rodc=ctx.RODC, replica_flags=ctx.domain_replica_flags) + + if 'DC=DomainDnsZones,%s' % ctx.base_dn in ctx.nc_list: + repl.replicate('DC=DomainDnsZones,%s' % ctx.base_dn, source_dsa_invocation_id, + destination_dsa_guid, rodc=ctx.RODC, + replica_flags=ctx.replica_flags) + + if 'DC=ForestDnsZones,%s' % ctx.root_dn in ctx.nc_list: + repl.replicate('DC=ForestDnsZones,%s' % ctx.root_dn, source_dsa_invocation_id, + destination_dsa_guid, rodc=ctx.RODC, + replica_flags=ctx.replica_flags) + if ctx.RODC: repl.replicate(ctx.acct_dn, source_dsa_invocation_id, destination_dsa_guid, @@ -724,9 +742,8 @@ class dc_join(object): '''finalise the join, mark us synchronised and setup secrets db''' print "Sending DsReplicateUpdateRefs for all the partitions" - ctx.send_DsReplicaUpdateRefs(ctx.schema_dn) - ctx.send_DsReplicaUpdateRefs(ctx.config_dn) - ctx.send_DsReplicaUpdateRefs(ctx.base_dn) + for nc in ctx.full_nc_list: + ctx.send_DsReplicaUpdateRefs(nc) print "Setting isSynchronized and dsServiceName" m = ldb.Message() @@ -865,6 +882,20 @@ class dc_join(object): def do_join(ctx): + ctx.nc_list = [ ctx.config_dn, ctx.schema_dn ] + ctx.full_nc_list = [ctx.base_dn, ctx.config_dn, ctx.schema_dn ] + + if not ctx.subdomain: + ctx.nc_list += [ctx.base_dn] + if ctx.dns_backend != "NONE": + ctx.nc_list += ['DC=DomainDnsZones,%s' % ctx.base_dn] + + if ctx.dns_backend != "NONE": + ctx.full_nc_list += ['DC=DomainDnsZones,%s' % ctx.base_dn] + ctx.full_nc_list += ['DC=ForestDnsZones,%s' % ctx.root_dn] + ctx.nc_list += ['DC=ForestDnsZones,%s' % ctx.root_dn] + + ctx.cleanup_old_join() try: ctx.join_add_objects() @@ -883,11 +914,11 @@ class dc_join(object): def join_RODC(server=None, creds=None, lp=None, site=None, netbios_name=None, targetdir=None, domain=None, domain_critical_only=False, - machinepass=None, use_ntvfs=False): + machinepass=None, use_ntvfs=False, dns_backend=None): """join as a RODC""" ctx = dc_join(server, creds, lp, site, netbios_name, targetdir, domain, - machinepass, use_ntvfs) + machinepass, use_ntvfs, dns_backend) lp.set("workgroup", ctx.domain_name) print("workgroup is %s" % ctx.domain_name) @@ -937,10 +968,10 @@ def join_RODC(server=None, creds=None, lp=None, site=None, netbios_name=None, def join_DC(server=None, creds=None, lp=None, site=None, netbios_name=None, targetdir=None, domain=None, domain_critical_only=False, - machinepass=None, use_ntvfs=False): + machinepass=None, use_ntvfs=False, dns_backend=None): """join as a DC""" ctx = dc_join(server, creds, lp, site, netbios_name, targetdir, domain, - machinepass, use_ntvfs) + machinepass, use_ntvfs, dns_backend) lp.set("workgroup", ctx.domain_name) print("workgroup is %s" % ctx.domain_name) @@ -967,10 +998,10 @@ def join_DC(server=None, creds=None, lp=None, site=None, netbios_name=None, def join_subdomain(server=None, creds=None, lp=None, site=None, netbios_name=None, targetdir=None, parent_domain=None, dnsdomain=None, netbios_domain=None, - machinepass=None, use_ntvfs=False): + machinepass=None, use_ntvfs=False, dns_backend=None): """join as a DC""" ctx = dc_join(server, creds, lp, site, netbios_name, targetdir, parent_domain, - machinepass, use_ntvfs) + machinepass, use_ntvfs, dns_backend) ctx.subdomain = True ctx.parent_domain_name = ctx.domain_name ctx.domain_name = netbios_domain diff --git a/source4/scripting/python/samba/netcmd/domain.py b/source4/scripting/python/samba/netcmd/domain.py index 8199c41aba7..4e73a29140e 100644 --- a/source4/scripting/python/samba/netcmd/domain.py +++ b/source4/scripting/python/samba/netcmd/domain.py @@ -148,15 +148,21 @@ class cmd_domain_join(Command): Option("--machinepass", type=str, metavar="PASSWORD", help="choose machine password (otherwise random)"), Option("--use-ntvfs", help="Use NTVFS for the fileserver (default = no)", - action="store_true") - ] + action="store_true"), + Option("--dns-backend", type="choice", metavar="NAMESERVER-BACKEND", + choices=["SAMBA_INTERNAL", "BIND9_DLZ", "NONE"], + help="The DNS server backend. SAMBA_INTERNAL is the builtin name server, " \ + "BIND9_DLZ uses samba4 AD to store zone information (default), " \ + "NONE skips the DNS setup entirely (this DC will not be a DNS server)", + default="BIND9_DLZ") + ] takes_args = ["domain", "role?"] def run(self, domain, role=None, sambaopts=None, credopts=None, versionopts=None, server=None, site=None, targetdir=None, domain_critical_only=False, parent_domain=None, machinepass=None, - use_ntvfs=False): + use_ntvfs=False, dns_backend=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) net = Net(creds, lp, server=credopts.ipaddress) @@ -181,13 +187,13 @@ class cmd_domain_join(Command): join_DC(server=server, creds=creds, lp=lp, domain=domain, site=site, netbios_name=netbios_name, targetdir=targetdir, domain_critical_only=domain_critical_only, - machinepass=machinepass, use_ntvfs=use_ntvfs) + machinepass=machinepass, use_ntvfs=use_ntvfs, dns_backend=dns_backend) return elif role == "RODC": join_RODC(server=server, creds=creds, lp=lp, domain=domain, site=site, netbios_name=netbios_name, targetdir=targetdir, domain_critical_only=domain_critical_only, - machinepass=machinepass, use_ntvfs=use_ntvfs) + machinepass=machinepass, use_ntvfs=use_ntvfs, dns_backend=dns_backend) return elif role == "SUBDOMAIN": netbios_domain = lp.get("workgroup") @@ -195,7 +201,7 @@ class cmd_domain_join(Command): parent_domain = ".".join(domain.split(".")[1:]) join_subdomain(server=server, creds=creds, lp=lp, dnsdomain=domain, parent_domain=parent_domain, site=site, netbios_name=netbios_name, netbios_domain=netbios_domain, targetdir=targetdir, - machinepass=machinepass, use_ntvfs=use_ntvfs) + machinepass=machinepass, use_ntvfs=use_ntvfs, dns_backend=dns_backend) return else: raise CommandError("Invalid role '%s' (possible values: MEMBER, DC, RODC, SUBDOMAIN)" % role)