summaryrefslogtreecommitdiffstats
path: root/source4/scripting/python/samba/join.py
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2011-08-24 15:39:51 +1000
committerAndrew Bartlett <abartlet@samba.org>2011-09-13 15:37:11 +1000
commit6635bb70d32d5214bc027428ac4a3737e8327c17 (patch)
treecb10c836cbf06c67d612918d47f05c16b394b390 /source4/scripting/python/samba/join.py
parent6d9b0ee26ea05ac23fe8b4f7e1fd756045c0b409 (diff)
downloadsamba-6635bb70d32d5214bc027428ac4a3737e8327c17.tar.gz
samba-6635bb70d32d5214bc027428ac4a3737e8327c17.tar.xz
samba-6635bb70d32d5214bc027428ac4a3737e8327c17.zip
s4-provision Add initial support for joining as a new subdomain
To do this we need to reorganise a lot of the provision code, so that we can create the framework for the inbound replicaton of the config and schema partitions and then add in the new subdomain locally. Andrew Bartlett
Diffstat (limited to 'source4/scripting/python/samba/join.py')
-rw-r--r--source4/scripting/python/samba/join.py172
1 files changed, 117 insertions, 55 deletions
diff --git a/source4/scripting/python/samba/join.py b/source4/scripting/python/samba/join.py
index 3d81a296f7..1759990deb 100644
--- a/source4/scripting/python/samba/join.py
+++ b/source4/scripting/python/samba/join.py
@@ -27,9 +27,10 @@ import ldb, samba, sys, os, uuid
from samba.ndr import ndr_pack
from samba.dcerpc import security, drsuapi, misc, nbt
from samba.credentials import Credentials, DONT_USE_KERBEROS
-from samba.provision import secretsdb_self_join, provision, FILL_DRS
+from samba.provision import secretsdb_self_join, provision, provision_fill, FILL_DRS, FILL_SUBDOMAIN
from samba.schema import Schema
from samba.net import Net
+from samba.dcerpc import security
import logging
import talloc
@@ -82,9 +83,6 @@ class dc_join(object):
ctx.domsid = ctx.samdb.get_domain_sid()
ctx.domain_name = ctx.get_domain_name()
- lp.set("workgroup", ctx.domain_name)
- print("workgroup is %s" % ctx.domain_name)
-
ctx.dc_ntds_dn = ctx.get_dsServiceName()
ctx.dc_dnsHostName = ctx.get_dnsHostName()
ctx.behavior_version = ctx.get_behavior_version()
@@ -105,9 +103,6 @@ class dc_join(object):
ctx.dnshostname = "%s.%s" % (ctx.myname, ctx.dnsdomain)
ctx.realm = ctx.dnsdomain
- lp.set("realm", ctx.realm)
-
- print("realm is %s" % ctx.realm)
ctx.acct_dn = "CN=%s,OU=Domain Controllers,%s" % (ctx.myname, ctx.base_dn)
@@ -314,23 +309,24 @@ class dc_join(object):
def join_add_objects(ctx):
'''add the various objects needed for the join'''
- print "Adding %s" % ctx.acct_dn
- rec = {
- "dn" : ctx.acct_dn,
- "objectClass": "computer",
- "displayname": ctx.samname,
- "samaccountname" : ctx.samname,
- "userAccountControl" : str(ctx.userAccountControl | samba.dsdb.UF_ACCOUNTDISABLE),
- "dnshostname" : ctx.dnshostname}
- if ctx.behavior_version >= samba.dsdb.DS_DOMAIN_FUNCTION_2008:
- rec['msDS-SupportedEncryptionTypes'] = str(samba.dsdb.ENC_ALL_TYPES)
- if ctx.managedby:
- rec["managedby"] = ctx.managedby
- if ctx.never_reveal_sid:
- rec["msDS-NeverRevealGroup"] = ctx.never_reveal_sid
- if ctx.reveal_sid:
- rec["msDS-RevealOnDemandGroup"] = ctx.reveal_sid
- ctx.samdb.add(rec)
+ if ctx.acct_dn:
+ print "Adding %s" % ctx.acct_dn
+ rec = {
+ "dn" : ctx.acct_dn,
+ "objectClass": "computer",
+ "displayname": ctx.samname,
+ "samaccountname" : ctx.samname,
+ "userAccountControl" : str(ctx.userAccountControl | samba.dsdb.UF_ACCOUNTDISABLE),
+ "dnshostname" : ctx.dnshostname}
+ if ctx.behavior_version >= samba.dsdb.DS_DOMAIN_FUNCTION_2008:
+ rec['msDS-SupportedEncryptionTypes'] = str(samba.dsdb.ENC_ALL_TYPES)
+ if ctx.managedby:
+ rec["managedby"] = ctx.managedby
+ if ctx.never_reveal_sid:
+ rec["msDS-NeverRevealGroup"] = ctx.never_reveal_sid
+ if ctx.reveal_sid:
+ rec["msDS-RevealOnDemandGroup"] = ctx.reveal_sid
+ ctx.samdb.add(rec)
if ctx.krbtgt_dn:
ctx.add_krbtgt_account()
@@ -342,8 +338,11 @@ class dc_join(object):
"systemFlags" : str(samba.dsdb.SYSTEM_FLAG_CONFIG_ALLOW_RENAME |
samba.dsdb.SYSTEM_FLAG_CONFIG_ALLOW_LIMITED_MOVE |
samba.dsdb.SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE),
- "serverReference" : ctx.acct_dn,
"dnsHostName" : ctx.dnshostname}
+
+ if ctx.acct_dn:
+ rec["serverReference"] = ctx.acct_dn
+
ctx.samdb.add(rec)
# FIXME: the partition (NC) assignment has to be made dynamic
@@ -388,7 +387,7 @@ class dc_join(object):
"fromServer" : ctx.dc_ntds_dn}
ctx.samdb.add(rec)
- if ctx.topology_dn:
+ if ctx.topology_dn and ctx.acct_dn:
print "Adding %s" % ctx.topology_dn
rec = {
"dn" : ctx.topology_dn,
@@ -397,31 +396,32 @@ class dc_join(object):
"serverReference" : ctx.ntds_dn}
ctx.samdb.add(rec)
- print "Adding SPNs to %s" % ctx.acct_dn
- m = ldb.Message()
- m.dn = ldb.Dn(ctx.samdb, ctx.acct_dn)
- for i in range(len(ctx.SPNs)):
- ctx.SPNs[i] = ctx.SPNs[i].replace("$NTDSGUID", str(ctx.ntds_guid))
- m["servicePrincipalName"] = ldb.MessageElement(ctx.SPNs,
- ldb.FLAG_MOD_ADD,
- "servicePrincipalName")
- ctx.samdb.modify(m)
-
- print "Setting account password for %s" % ctx.samname
- ctx.samdb.setpassword("(&(objectClass=user)(sAMAccountName=%s))" % ldb.binary_encode(ctx.samname),
- ctx.acct_pass,
- force_change_at_next_login=False,
- username=ctx.samname)
- res = ctx.samdb.search(base=ctx.acct_dn, scope=ldb.SCOPE_BASE, attrs=["msDS-keyVersionNumber"])
- ctx.key_version_number = int(res[0]["msDS-keyVersionNumber"][0])
-
- print("Enabling account")
- m = ldb.Message()
- m.dn = ldb.Dn(ctx.samdb, ctx.acct_dn)
- m["userAccountControl"] = ldb.MessageElement(str(ctx.userAccountControl),
- ldb.FLAG_MOD_REPLACE,
- "userAccountControl")
- ctx.samdb.modify(m)
+ if ctx.acct_dn:
+ print "Adding SPNs to %s" % ctx.acct_dn
+ m = ldb.Message()
+ m.dn = ldb.Dn(ctx.samdb, ctx.acct_dn)
+ for i in range(len(ctx.SPNs)):
+ ctx.SPNs[i] = ctx.SPNs[i].replace("$NTDSGUID", str(ctx.ntds_guid))
+ m["servicePrincipalName"] = ldb.MessageElement(ctx.SPNs,
+ ldb.FLAG_MOD_ADD,
+ "servicePrincipalName")
+ ctx.samdb.modify(m)
+
+ print "Setting account password for %s" % ctx.samname
+ ctx.samdb.setpassword("(&(objectClass=user)(sAMAccountName=%s))" % ldb.binary_encode(ctx.samname),
+ ctx.acct_pass,
+ force_change_at_next_login=False,
+ username=ctx.samname)
+ res = ctx.samdb.search(base=ctx.acct_dn, scope=ldb.SCOPE_BASE, attrs=["msDS-keyVersionNumber"])
+ ctx.key_version_number = int(res[0]["msDS-keyVersionNumber"][0])
+
+ print("Enabling account")
+ m = ldb.Message()
+ m.dn = ldb.Dn(ctx.samdb, ctx.acct_dn)
+ m["userAccountControl"] = ldb.MessageElement(str(ctx.userAccountControl),
+ ldb.FLAG_MOD_REPLACE,
+ "userAccountControl")
+ ctx.samdb.modify(m)
def join_provision(ctx):
'''provision the local SAM'''
@@ -445,6 +445,24 @@ class dc_join(object):
ctx.local_samdb = presult.samdb
ctx.lp = presult.lp
ctx.paths = presult.paths
+ ctx.names = presult.names
+
+ def join_provision_own_domain(ctx):
+ '''provision the local SAM'''
+
+ print "Calling bare provision"
+
+ logger = logging.getLogger("provision")
+ logger.addHandler(logging.StreamHandler(sys.stdout))
+
+ secrets_ldb = Ldb(ctx.paths.secrets, session_info=system_session(), lp=ctx.lp)
+
+ presult = provision_fill(ctx.local_samdb, secrets_ldb,
+ logger, ctx.names, ctx.paths, domainsid=security.dom_sid(ctx.domsid),
+ targetdir=ctx.targetdir, samdb_fill=FILL_SUBDOMAIN,
+ machinepass=ctx.acct_pass, serverrole="domain controller",
+ lp=ctx.lp)
+ print "Provision OK for domain %s" % ctx.names.dnsdomain
def join_replicate(ctx):
@@ -478,9 +496,10 @@ class dc_join(object):
repl.replicate(ctx.config_dn, source_dsa_invocation_id,
destination_dsa_guid, rodc=ctx.RODC,
replica_flags=ctx.replica_flags)
- repl.replicate(ctx.base_dn, source_dsa_invocation_id,
- destination_dsa_guid, rodc=ctx.RODC,
- replica_flags=ctx.domain_replica_flags)
+ if not ctx.subdomain:
+ repl.replicate(ctx.base_dn, source_dsa_invocation_id,
+ destination_dsa_guid, rodc=ctx.RODC,
+ replica_flags=ctx.domain_replica_flags)
if ctx.RODC:
repl.replicate(ctx.acct_dn, source_dsa_invocation_id,
destination_dsa_guid,
@@ -526,7 +545,10 @@ class dc_join(object):
ctx.join_add_objects()
ctx.join_provision()
ctx.join_replicate()
- ctx.join_finalise()
+ if ctx.subdomain:
+ ctx.join_provision_own_domain()
+ else:
+ ctx.join_finalise()
except Exception:
print "Join failed - cleaning up"
ctx.cleanup_old_join()
@@ -539,6 +561,12 @@ def join_RODC(server=None, creds=None, lp=None, site=None, netbios_name=None,
ctx = dc_join(server, creds, lp, site, netbios_name, targetdir, domain)
+ lp.set("workgroup", ctx.domain_name)
+ print("workgroup is %s" % ctx.domain_name)
+
+ lp.set("realm", ctx.realm)
+ print("realm is %s" % ctx.realm)
+
ctx.krbtgt_dn = "CN=krbtgt_%s,CN=Users,%s" % (ctx.myname, ctx.base_dn)
# setup some defaults for accounts that should be replicated to this RODC
@@ -584,6 +612,12 @@ def join_DC(server=None, creds=None, lp=None, site=None, netbios_name=None,
"""join as a DC"""
ctx = dc_join(server, creds, lp, site, netbios_name, targetdir, domain)
+ lp.set("workgroup", ctx.domain_name)
+ print("workgroup is %s" % ctx.domain_name)
+
+ lp.set("realm", ctx.realm)
+ print("realm is %s" % ctx.realm)
+
ctx.userAccountControl = samba.dsdb.UF_SERVER_TRUST_ACCOUNT | samba.dsdb.UF_TRUSTED_FOR_DELEGATION
ctx.SPNs.append('E3514235-4B06-11D1-AB04-00C04FC2DCD2/$NTDSGUID/%s' % ctx.dnsdomain)
@@ -600,3 +634,31 @@ def join_DC(server=None, creds=None, lp=None, site=None, netbios_name=None,
ctx.do_join()
print "Joined domain %s (SID %s) as a DC" % (ctx.domain_name, ctx.domsid)
+
+def join_subdomain(server=None, creds=None, lp=None, site=None, netbios_name=None,
+ targetdir=None, parent_domain=None, dnsdomain=None, netbios_domain=None):
+ """join as a DC"""
+ ctx = dc_join(server, creds, lp, site, netbios_name, targetdir, parent_domain)
+ ctx.subdomain = True
+ ctx.domain_name = netbios_domain
+ ctx.realm = dnsdomain
+ ctx.dnsdomain = dnsdomain
+ ctx.base_dn = samba.dn_from_dns_name(dnsdomain)
+ ctx.domsid = str(security.random_sid())
+ ctx.acct_dn = None
+ ctx.dnshostname = "%s.%s" % (ctx.myname, ctx.dnsdomain)
+
+ ctx.userAccountControl = samba.dsdb.UF_SERVER_TRUST_ACCOUNT | samba.dsdb.UF_TRUSTED_FOR_DELEGATION
+
+ ctx.SPNs.append('E3514235-4B06-11D1-AB04-00C04FC2DCD2/$NTDSGUID/%s' % ctx.dnsdomain)
+ ctx.secure_channel_type = misc.SEC_CHAN_BDC
+
+ ctx.replica_flags = (drsuapi.DRSUAPI_DRS_WRIT_REP |
+ drsuapi.DRSUAPI_DRS_INIT_SYNC |
+ drsuapi.DRSUAPI_DRS_PER_SYNC |
+ drsuapi.DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS |
+ drsuapi.DRSUAPI_DRS_NEVER_SYNCED)
+ ctx.domain_replica_flags = ctx.replica_flags
+
+ ctx.do_join()
+ print "Created domain %s (SID %s) as a DC" % (ctx.domain_name, ctx.domsid)