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,
|
DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL,
|
||||||
UF_WORKSTATION_TRUST_ACCOUNT,
|
UF_WORKSTATION_TRUST_ACCOUNT,
|
||||||
UF_SERVER_TRUST_ACCOUNT,
|
UF_SERVER_TRUST_ACCOUNT,
|
||||||
UF_TRUSTED_FOR_DELEGATION
|
UF_TRUSTED_FOR_DELEGATION,
|
||||||
|
UF_PARTIAL_SECRETS_ACCOUNT
|
||||||
)
|
)
|
||||||
|
|
||||||
from samba.provision import (
|
from samba.provision import (
|
||||||
@ -734,6 +735,7 @@ class cmd_domain_demote(Command):
|
|||||||
|
|
||||||
self.errf.write("Deactivating inbound replication\n")
|
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 = ldb.Message()
|
||||||
nmsg.dn = msg[0].dn
|
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")
|
nmsg["options"] = ldb.MessageElement(str(dsa_options), ldb.FLAG_MOD_REPLACE, "options")
|
||||||
samdb.modify(nmsg)
|
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"
|
self.errf.write("Asking partner server %s to synchronize from us\n"
|
||||||
% server)
|
% server)
|
||||||
for part in (samdb.get_schema_basedn(),
|
for part in (samdb.get_schema_basedn(),
|
||||||
samdb.get_config_basedn(),
|
samdb.get_config_basedn(),
|
||||||
samdb.get_root_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:
|
try:
|
||||||
sendDsReplicaSync(drsuapiBind, drsuapi_handle, ntds_guid, str(part), drsuapi.DRSUAPI_DRS_WRIT_REP)
|
drsuapiBind.DsReplicaSync(drsuapi_handle, 1, req1)
|
||||||
except drsException, e:
|
except RuntimeError as (werr, string):
|
||||||
|
if werr == 8452: #WERR_DS_DRA_NO_REPLICA
|
||||||
|
pass
|
||||||
|
else:
|
||||||
self.errf.write(
|
self.errf.write(
|
||||||
"Error while demoting, "
|
"Error while demoting, "
|
||||||
"re-enabling inbound replication\n")
|
"re-enabling inbound replication\n")
|
||||||
@ -764,7 +776,7 @@ class cmd_domain_demote(Command):
|
|||||||
credentials=creds, lp=lp)
|
credentials=creds, lp=lp)
|
||||||
|
|
||||||
self.errf.write("Changing userControl and container\n")
|
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$))" %
|
expression="(&(objectClass=user)(sAMAccountName=%s$))" %
|
||||||
netbios_name.upper(),
|
netbios_name.upper(),
|
||||||
attrs=["userAccountControl"])
|
attrs=["userAccountControl"])
|
||||||
@ -790,7 +802,7 @@ class cmd_domain_demote(Command):
|
|||||||
|
|
||||||
olduac = uac
|
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
|
uac |= UF_WORKSTATION_TRUST_ACCOUNT
|
||||||
|
|
||||||
msg = ldb.Message()
|
msg = ldb.Message()
|
||||||
@ -811,13 +823,12 @@ class cmd_domain_demote(Command):
|
|||||||
raise CommandError("Error while changing account control", e)
|
raise CommandError("Error while changing account control", e)
|
||||||
|
|
||||||
parent = msg.dn.parent()
|
parent = msg.dn.parent()
|
||||||
rdn = str(res[0].dn)
|
rdn = "%s=%s" % (res[0].dn.get_rdn_name(), res[0].dn.get_rdn_value())
|
||||||
rdn = string.replace(rdn, ",%s" % str(parent), "")
|
|
||||||
# Let's move to the Computer container
|
# Let's move to the Computer container
|
||||||
i = 0
|
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)
|
res = remote_samdb.search(base=computer_dn, expression=rdn, scope=ldb.SCOPE_ONELEVEL)
|
||||||
|
|
||||||
if (len(res) != 0):
|
if (len(res) != 0):
|
||||||
@ -875,8 +886,14 @@ class cmd_domain_demote(Command):
|
|||||||
domain = remote_samdb.get_root_basedn()
|
domain = remote_samdb.get_root_basedn()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sendRemoveDsServer(drsuapiBind, drsuapi_handle, server_dsa_dn, domain)
|
req1 = drsuapi.DsRemoveDSServerRequest1()
|
||||||
except drsException, e:
|
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(
|
self.errf.write(
|
||||||
"Error while demoting, re-enabling inbound replication\n")
|
"Error while demoting, re-enabling inbound replication\n")
|
||||||
dsa_options ^= DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL
|
dsa_options ^= DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL
|
||||||
@ -889,20 +906,16 @@ class cmd_domain_demote(Command):
|
|||||||
msg["userAccountControl"] = ldb.MessageElement("%d" % uac,
|
msg["userAccountControl"] = ldb.MessageElement("%d" % uac,
|
||||||
ldb.FLAG_MOD_REPLACE,
|
ldb.FLAG_MOD_REPLACE,
|
||||||
"userAccountControl")
|
"userAccountControl")
|
||||||
print str(dc_dn)
|
|
||||||
remote_samdb.modify(msg)
|
remote_samdb.modify(msg)
|
||||||
remote_samdb.rename(newdn, dc_dn)
|
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",
|
remove_dc.remove_sysvol_references(remote_samdb, rdn)
|
||||||
"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
|
|
||||||
|
|
||||||
|
# These are objects under the computer account that should be deleted
|
||||||
for s in ("CN=Enterprise,CN=NTFRS Subscriptions",
|
for s in ("CN=Enterprise,CN=NTFRS Subscriptions",
|
||||||
"CN=%s, CN=NTFRS Subscriptions" % lp.get("realm"),
|
"CN=%s, CN=NTFRS Subscriptions" % lp.get("realm"),
|
||||||
"CN=Domain system Volumes (SYSVOL Share), CN=NTFRS Subscriptions",
|
"CN=Domain system Volumes (SYSVOL Share), CN=NTFRS Subscriptions",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user