diff options
Diffstat (limited to 'source4/scripting/python/samba/join.py')
-rw-r--r-- | source4/scripting/python/samba/join.py | 172 |
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) |