mirror of
https://github.com/samba-team/samba.git
synced 2025-02-28 01:58:17 +03:00
samba-tool domain demote: Allow to operate on an RODC and a subdomain
On an RODC the local database cannot be modified, and the flags to remove are different, we need instead to remove UF_PARTIAL_SECRETS_ACCOUNT. If we are in a subdomain, then db.get_root_basedn() points to the forest root, not the root of our domain If the removeDsServer() fails with WERR_DS_DRA_NO_REPLICA this may be reasonably considered to be success in this case. Finally, the remove_dc.remove_sysvol_references() is reused for objects not under the computer account. Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Garming Sam <garming@catalyst.net.nz> domain demote Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Garming Sam <garming@catalyst.net.nz>
This commit is contained in:
parent
1874f59200
commit
f121173cbf
@ -71,7 +71,8 @@ from samba.dsdb import (
|
||||
DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL,
|
||||
UF_WORKSTATION_TRUST_ACCOUNT,
|
||||
UF_SERVER_TRUST_ACCOUNT,
|
||||
UF_TRUSTED_FOR_DELEGATION
|
||||
UF_TRUSTED_FOR_DELEGATION,
|
||||
UF_PARTIAL_SECRETS_ACCOUNT
|
||||
)
|
||||
|
||||
from samba.provision import (
|
||||
@ -734,6 +735,7 @@ class cmd_domain_demote(Command):
|
||||
|
||||
self.errf.write("Deactivating inbound replication\n")
|
||||
|
||||
if not (dsa_options & DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL) and not samdb.am_rodc():
|
||||
nmsg = ldb.Message()
|
||||
nmsg.dn = msg[0].dn
|
||||
|
||||
@ -741,16 +743,26 @@ class cmd_domain_demote(Command):
|
||||
nmsg["options"] = ldb.MessageElement(str(dsa_options), ldb.FLAG_MOD_REPLACE, "options")
|
||||
samdb.modify(nmsg)
|
||||
|
||||
if not (dsa_options & DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL) and not samdb.am_rodc():
|
||||
|
||||
self.errf.write("Asking partner server %s to synchronize from us\n"
|
||||
% server)
|
||||
for part in (samdb.get_schema_basedn(),
|
||||
samdb.get_config_basedn(),
|
||||
samdb.get_root_basedn()):
|
||||
nc = drsuapi.DsReplicaObjectIdentifier()
|
||||
nc.dn = str(part)
|
||||
|
||||
req1 = drsuapi.DsReplicaSyncRequest1()
|
||||
req1.naming_context = nc;
|
||||
req1.options = drsuapi.DRSUAPI_DRS_WRIT_REP
|
||||
req1.source_dsa_guid = misc.GUID(ntds_guid)
|
||||
|
||||
try:
|
||||
sendDsReplicaSync(drsuapiBind, drsuapi_handle, ntds_guid, str(part), drsuapi.DRSUAPI_DRS_WRIT_REP)
|
||||
except drsException, e:
|
||||
drsuapiBind.DsReplicaSync(drsuapi_handle, 1, req1)
|
||||
except RuntimeError as (werr, string):
|
||||
if werr == 8452: #WERR_DS_DRA_NO_REPLICA
|
||||
pass
|
||||
else:
|
||||
self.errf.write(
|
||||
"Error while demoting, "
|
||||
"re-enabling inbound replication\n")
|
||||
@ -764,7 +776,7 @@ class cmd_domain_demote(Command):
|
||||
credentials=creds, lp=lp)
|
||||
|
||||
self.errf.write("Changing userControl and container\n")
|
||||
res = remote_samdb.search(base=str(remote_samdb.get_root_basedn()),
|
||||
res = remote_samdb.search(base=str(remote_samdb.domain_dn()),
|
||||
expression="(&(objectClass=user)(sAMAccountName=%s$))" %
|
||||
netbios_name.upper(),
|
||||
attrs=["userAccountControl"])
|
||||
@ -790,7 +802,7 @@ class cmd_domain_demote(Command):
|
||||
|
||||
olduac = uac
|
||||
|
||||
uac ^= (UF_SERVER_TRUST_ACCOUNT|UF_TRUSTED_FOR_DELEGATION)
|
||||
uac &= ~(UF_SERVER_TRUST_ACCOUNT|UF_TRUSTED_FOR_DELEGATION|UF_PARTIAL_SECRETS_ACCOUNT)
|
||||
uac |= UF_WORKSTATION_TRUST_ACCOUNT
|
||||
|
||||
msg = ldb.Message()
|
||||
@ -811,13 +823,12 @@ class cmd_domain_demote(Command):
|
||||
raise CommandError("Error while changing account control", e)
|
||||
|
||||
parent = msg.dn.parent()
|
||||
rdn = str(res[0].dn)
|
||||
rdn = string.replace(rdn, ",%s" % str(parent), "")
|
||||
rdn = "%s=%s" % (res[0].dn.get_rdn_name(), res[0].dn.get_rdn_value())
|
||||
# Let's move to the Computer container
|
||||
i = 0
|
||||
newrdn = rdn
|
||||
newrdn = str(rdn)
|
||||
|
||||
computer_dn = ldb.Dn(remote_samdb, "CN=Computers,%s" % str(remote_samdb.get_root_basedn()))
|
||||
computer_dn = ldb.Dn(remote_samdb, "CN=Computers,%s" % str(remote_samdb.domain_dn()))
|
||||
res = remote_samdb.search(base=computer_dn, expression=rdn, scope=ldb.SCOPE_ONELEVEL)
|
||||
|
||||
if (len(res) != 0):
|
||||
@ -875,8 +886,14 @@ class cmd_domain_demote(Command):
|
||||
domain = remote_samdb.get_root_basedn()
|
||||
|
||||
try:
|
||||
sendRemoveDsServer(drsuapiBind, drsuapi_handle, server_dsa_dn, domain)
|
||||
except drsException, e:
|
||||
req1 = drsuapi.DsRemoveDSServerRequest1()
|
||||
req1.server_dn = str(server_dsa_dn)
|
||||
req1.domain_dn = str(domain)
|
||||
req1.commit = 1
|
||||
|
||||
drsuapiBind.DsRemoveDSServer(drsuapi_handle, 1, req1)
|
||||
except RuntimeError as (werr, string):
|
||||
if not (dsa_options & DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL) and not samdb.am_rodc():
|
||||
self.errf.write(
|
||||
"Error while demoting, re-enabling inbound replication\n")
|
||||
dsa_options ^= DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL
|
||||
@ -889,20 +906,16 @@ class cmd_domain_demote(Command):
|
||||
msg["userAccountControl"] = ldb.MessageElement("%d" % uac,
|
||||
ldb.FLAG_MOD_REPLACE,
|
||||
"userAccountControl")
|
||||
print str(dc_dn)
|
||||
remote_samdb.modify(msg)
|
||||
remote_samdb.rename(newdn, dc_dn)
|
||||
raise CommandError("Error while sending a removeDsServer", e)
|
||||
if werr == 8452: #WERR_DS_DRA_NO_REPLICA
|
||||
raise CommandError("The DC %s is not present on (already removed from) the remote server: " % server_dsa_dn, e)
|
||||
else:
|
||||
raise CommandError("Error while sending a removeDsServer of %s: " % server_dsa_dn, e)
|
||||
|
||||
for s in ("CN=Enterprise,CN=Microsoft System Volumes,CN=System,CN=Configuration",
|
||||
"CN=%s,CN=Microsoft System Volumes,CN=System,CN=Configuration" % lp.get("realm"),
|
||||
"CN=Domain System Volumes (SYSVOL share),CN=File Replication Service,CN=System"):
|
||||
try:
|
||||
remote_samdb.delete(ldb.Dn(remote_samdb,
|
||||
"%s,%s,%s" % (str(rdn), s, str(remote_samdb.get_root_basedn()))))
|
||||
except ldb.LdbError, l:
|
||||
pass
|
||||
remove_dc.remove_sysvol_references(remote_samdb, rdn)
|
||||
|
||||
# These are objects under the computer account that should be deleted
|
||||
for s in ("CN=Enterprise,CN=NTFRS Subscriptions",
|
||||
"CN=%s, CN=NTFRS Subscriptions" % lp.get("realm"),
|
||||
"CN=Domain system Volumes (SYSVOL Share), CN=NTFRS Subscriptions",
|
||||
|
Loading…
x
Reference in New Issue
Block a user