def drsuapi_connect(ctx): '''make a DRSUAPI connection to the server''' try: (ctx.drsuapi, ctx.drsuapi_handle, ctx.bind_supported_extensions) = drs_utils.drsuapi_connect( ctx.server, ctx.lp, ctx.creds) except Exception as e: raise CommandError("DRS connection to %s failed" % ctx.server, e)
def _force_all_reps(self, samdb, dc, direction): if direction == 'inbound': info_type = drsuapi.DRSUAPI_DS_REPLICA_INFO_NEIGHBORS elif direction == 'outbound': info_type = drsuapi.DRSUAPI_DS_REPLICA_INFO_REPSTO else: raise ValueError("expected 'inbound' or 'outbound'") self._enable_all_repl(dc) lp = self.get_loadparm() creds = self.get_credentials() drsuapi_conn, drsuapi_handle, _ = drs_utils.drsuapi_connect( dc, lp, creds) req1 = drsuapi.DsReplicaGetInfoRequest1() req1.info_type = info_type _, info = drsuapi_conn.DsReplicaGetInfo(drsuapi_handle, 1, req1) for x in info.array: # you might think x.source_dsa_address was the thing, but no. # and we need to filter out RODCs and deleted DCs res = [] try: res = samdb.search(base=x.source_dsa_obj_dn, scope=ldb.SCOPE_BASE, attrs=['msDS-isRODC', 'isDeleted'], controls=['show_deleted:0']) except ldb.LdbError as e: if e.args[0] != ldb.ERR_NO_SUCH_OBJECT: raise if (len(res) == 0 or len(res[0].get('msDS-isRODC', '')) > 0 or res[0]['isDeleted'] == 'TRUE'): continue dsa_dn = str(ldb.Dn(samdb, x.source_dsa_obj_dn).parent()) try: res = samdb.search(base=dsa_dn, scope=ldb.SCOPE_BASE, attrs=['dNSHostName']) except ldb.LdbError as e: if e.args[0] != ldb.ERR_NO_SUCH_OBJECT: raise continue if len(res) == 0: print("server %s has no dNSHostName" % dsa_dn) continue remote = res[0].get('dNSHostName', [''])[0] if remote: self._enable_all_repl(remote) if direction == 'inbound': src, dest = remote, dc else: src, dest = dc, remote self._net_drs_replicate(dest, src, forced=True)
def __init__(self, dc=None): (self.load_param, self.credentials) = self.samba_credentials() self.server = dc or self.netcmd_dnsname(self.load_param) drs_tuple = drs_utils.drsuapi_connect(self.server, self.load_param, self.credentials) (self.drsuapi, self.handle, _bind_supported_extensions) = drs_tuple
def run(self, sambaopts=None, credopts=None, versionopts=None, server=None, targetdir=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) net = Net(creds, lp, server=credopts.ipaddress) netbios_name = lp.get("netbios name") samdb = SamDB(session_info=system_session(), credentials=creds, lp=lp) if not server: res = samdb.search(expression='(&(objectClass=computer)(serverReferenceBL=*))', attrs=["dnsHostName", "name"]) if (len(res) == 0): raise CommandError("Unable to search for servers") if (len(res) == 1): raise CommandError("You are the latest server in the domain") server = None for e in res: if str(e["name"]).lower() != netbios_name.lower(): server = e["dnsHostName"] break ntds_guid = samdb.get_ntds_GUID() msg = samdb.search(base=str(samdb.get_config_basedn()), scope=ldb.SCOPE_SUBTREE, expression="(objectGUID=%s)" % ntds_guid, attrs=['options']) if len(msg) == 0 or "options" not in msg[0]: raise CommandError("Failed to find options on %s" % ntds_guid) ntds_dn = msg[0].dn dsa_options = int(str(msg[0]['options'])) res = samdb.search(expression="(fSMORoleOwner=%s)" % str(ntds_dn), controls=["search_options:1:2"]) if len(res) != 0: raise CommandError("Current DC is still the owner of %d role(s), use the role command to transfer roles to another DC" % len(res)) print "Using %s as partner server for the demotion" % server (drsuapiBind, drsuapi_handle, supportedExtensions) = drsuapi_connect(server, lp, creds) print "Desactivating inbound replication" nmsg = ldb.Message() nmsg.dn = msg[0].dn dsa_options |= DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL 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(): print "Asking partner server %s to synchronize from us" % server for part in (samdb.get_schema_basedn(), samdb.get_config_basedn(), samdb.get_root_basedn()): try: sendDsReplicaSync(drsuapiBind, drsuapi_handle, ntds_guid, str(part), drsuapi.DRSUAPI_DRS_WRIT_REP) except drsException, e: print "Error while demoting, re-enabling inbound replication" dsa_options ^= DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL nmsg["options"] = ldb.MessageElement(str(dsa_options), ldb.FLAG_MOD_REPLACE, "options") samdb.modify(nmsg) raise CommandError("Error while sending a DsReplicaSync for partion %s" % str(part), e)
def drsuapi_connect(ctx): '''make a DRSUAPI connection to the server''' try: (ctx.drsuapi, ctx.drsuapi_handle, ctx.bind_supported_extensions) = drs_utils.drsuapi_connect(ctx.server, ctx.lp, ctx.creds) except Exception as e: raise CommandError("DRS connection to %s failed" % ctx.server, e)
def run(self, sambaopts=None, credopts=None, versionopts=None, server=None, targetdir=None): lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) net = Net(creds, lp, server=credopts.ipaddress) netbios_name = lp.get("netbios name") samdb = SamDB(session_info=system_session(), credentials=creds, lp=lp) if not server: res = samdb.search( expression='(&(objectClass=computer)(serverReferenceBL=*))', attrs=["dnsHostName", "name"]) if (len(res) == 0): raise CommandError("Unable to search for servers") if (len(res) == 1): raise CommandError("You are the latest server in the domain") server = None for e in res: if str(e["name"]).lower() != netbios_name.lower(): server = e["dnsHostName"] break ntds_guid = samdb.get_ntds_GUID() msg = samdb.search(base=str(samdb.get_config_basedn()), scope=ldb.SCOPE_SUBTREE, expression="(objectGUID=%s)" % ntds_guid, attrs=['options']) if len(msg) == 0 or "options" not in msg[0]: raise CommandError("Failed to find options on %s" % ntds_guid) ntds_dn = msg[0].dn dsa_options = int(str(msg[0]['options'])) res = samdb.search(expression="(fSMORoleOwner=%s)" % str(ntds_dn), controls=["search_options:1:2"]) if len(res) != 0: raise CommandError( "Current DC is still the owner of %d role(s), use the role command to transfer roles to another DC" ) print "Using %s as partner server for the demotion" % server (drsuapiBind, drsuapi_handle, supportedExtensions) = drsuapi_connect(server, lp, creds) print "Desactivating inbound replication" nmsg = ldb.Message() nmsg.dn = msg[0].dn dsa_options |= DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL 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(): print "Asking partner server %s to synchronize from us" % server for part in (samdb.get_schema_basedn(), samdb.get_config_basedn(), samdb.get_root_basedn()): try: sendDsReplicaSync(drsuapiBind, drsuapi_handle, ntds_guid, str(part), drsuapi.DRSUAPI_DRS_WRIT_REP) except drsException, e: print "Error while demoting, re-enabling inbound replication" dsa_options ^= DS_NTDSDSA_OPT_DISABLE_INBOUND_REPL nmsg["options"] = ldb.MessageElement( str(dsa_options), ldb.FLAG_MOD_REPLACE, "options") samdb.modify(nmsg) raise CommandError( "Error while sending a DsReplicaSync for partion %s" % str(part), e)