diff -Nuar samba4-4.0.0~alpha17~git201110100928.orig/source4/scripting/python/samba/join.py samba4-4.0.0~alpha17~git201110100928/source4/scripting/python/samba/join.py --- samba4-4.0.0~alpha17~git201110100928.orig/source4/scripting/python/samba/join.py 2012-07-04 08:28:59.000000000 +0200 +++ samba4-4.0.0~alpha17~git201110100928/source4/scripting/python/samba/join.py 2012-07-10 17:52:01.000000000 +0200 @@ -50,7 +50,7 @@ def __init__(ctx, server=None, creds=None, lp=None, site=None, netbios_name=None, targetdir=None, domain=None, - machinepass=None, promote_existing=False): + machinepass=None, promote_existing=False, keep_existing=False): ctx.creds = creds ctx.lp = lp ctx.site = site @@ -59,6 +59,7 @@ ctx.promote_existing = promote_existing ctx.promote_from_dn = None + ctx.keep_existing = keep_existing ctx.creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL) ctx.net = Net(creds=ctx.creds, lp=ctx.lp) @@ -220,6 +221,25 @@ ctx.promote_from_dn = res[0].dn + def dc_account_exists(ctx): + res = ctx.samdb.search(base=ctx.samdb.get_default_basedn(), + expression='sAMAccountName=%s' % ldb.binary_encode(ctx.samname), + attrs=["msDS-krbTgtLink", "userAccountControl", "serverReferenceBL", "rIDSetReferences"]) + + if len(res) == 0: + print "Could not find domain account '%s'" % ctx.samname + elif (int(res[0]["userAccountControl"][0]) & (samba.dsdb.UF_WORKSTATION_TRUST_ACCOUNT|samba.dsdb.UF_SERVER_TRUST_ACCOUNT) != 0): + raise Exception("Account %s is a domain member or a bare NT4 BDC, use 'samba-tool domain dcpromo' instead'" % ctx.samname) + elif "msDS-krbTgtLink" in res[0] or "serverReferenceBL" in res[0] or "rIDSetReferences" in res[0]: + print "Account '%s' appears to be an active DC" % ctx.samname + + if len(res) != 0: + ctx.promote_from_dn = res[0].dn + return True + else + return False + + def find_dc(ctx, domain): '''find a writeable DC for the given domain''' try: @@ -868,6 +888,8 @@ def do_join(ctx): if ctx.promote_existing: ctx.promote_possible() + elif ctr.keep_existing and ctx.dc_account_exists(): + ctx.promote_existing = True else: ctx.cleanup_old_join() @@ -888,11 +910,11 @@ def join_RODC(server=None, creds=None, lp=None, site=None, netbios_name=None, targetdir=None, domain=None, domain_critical_only=False, - machinepass=None, promote_existing=False): + machinepass=None, promote_existing=False, keep_existing=False): """join as a RODC""" ctx = dc_join(server, creds, lp, site, netbios_name, targetdir, domain, - machinepass, promote_existing) + machinepass, promote_existing, keep_existing) lp.set("workgroup", ctx.domain_name) print("workgroup is %s" % ctx.domain_name) @@ -942,10 +964,10 @@ def join_DC(server=None, creds=None, lp=None, site=None, netbios_name=None, targetdir=None, domain=None, domain_critical_only=False, - machinepass=None, promote_existing=False): + machinepass=None, promote_existing=False, keep_existing=False): """join as a DC""" ctx = dc_join(server, creds, lp, site, netbios_name, targetdir, domain, - machinepass, promote_existing) + machinepass, promote_existing, keep_existing) lp.set("workgroup", ctx.domain_name) print("workgroup is %s" % ctx.domain_name) diff -Nuar samba4-4.0.0~alpha17~git201110100928.orig/source4/scripting/python/samba/netcmd/domain.py samba4-4.0.0~alpha17~git201110100928/source4/scripting/python/samba/netcmd/domain.py --- samba4-4.0.0~alpha17~git201110100928.orig/source4/scripting/python/samba/netcmd/domain.py 2012-07-04 08:28:59.000000000 +0200 +++ samba4-4.0.0~alpha17~git201110100928/source4/scripting/python/samba/netcmd/domain.py 2012-07-10 18:00:27.000000000 +0200 @@ -155,6 +155,9 @@ Option("--domain-critical-only", help="only replicate critical domain objects", action="store_true"), + Option("--keep-existing", + help="keep the SID during join", + action="store_true"), Option("--machinepass", type=str, metavar="PASSWORD", help="choose machine password (otherwise random)") ] @@ -177,6 +180,7 @@ role = role.upper() if role is None or role == "MEMBER": + self.outf.write("ignoring option --keep-exising, currently not implemented for MEMBER\n") (join_password, sid, domain_name) = net.join_member(domain, netbios_name, LIBNET_JOIN_AUTOMATIC, @@ -188,13 +192,13 @@ 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) + machinepass=machinepass, keep_existing=keep_existing) 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) + machinepass=machinepass, keep_existing=keep_existing) return elif role == "SUBDOMAIN": netbios_domain = lp.get("workgroup")