Service can then utilize to replicate naming contexts
:param unix_now: The putative current time in seconds since 1970.
- :param read_only: Don't write to the database.
+ :param readonly: Don't write to the database.
:param verify: Check topological invariants for the generated graphs
:param debug: Write verbosely to stderr.
"param dot_file_dir: write diagnostic Graphviz files in this directory
:return: None
"""
# TODO Figure out how best to handle the RODC case
- # The RODC is ITSG, but shouldn't act on anyone's behalf.
+ # The RODC is ISTG, but shouldn't act on anyone's behalf.
if self.my_dsa.is_ro():
return
if s_dnstr not in local_dsas:
from_dsa = self.get_dsa(s_dnstr)
# Samba ONLY: ISTG removes connections to dead DCs
- if from_dsa is None and '\\0ADEL' in s_dnstr:
- logger.info("DSA appears deleted, removing connection %s" % s_dnstr)
+ if from_dsa is None or '\\0ADEL' in s_dnstr:
+ logger.info("DSA appears deleted, removing connection %s"
+ % s_dnstr)
cn.to_be_deleted = True
continue
connections_and_dsas.append((cn, dsa, from_dsa))
drsuapi.DRSUAPI_DRS_PER_SYNC |
drsuapi.DRSUAPI_DRS_ADD_REF |
drsuapi.DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING |
- drsuapi.DRSUAPI_DRS_GET_ALL_GROUP_MEMBERSHIP |
drsuapi.DRSUAPI_DRS_NONGC_RO_REP)
if t_repsFrom.replica_flags != replica_flags:
t_repsFrom.replica_flags = replica_flags
- c_rep.commit_repsFrom(self.samdb)
+ c_rep.commit_repsFrom(self.samdb, ro=self.readonly)
else:
if dnstr not in needed_rep_table:
delete_reps.add(dnstr)
for dnstr in delete_reps:
del current_rep_table[dnstr]
+ # HANDLE REPS-FROM
+ #
# Now perform the scan of replicas we'll need
# and compare any current repsFrom against the
# connections
# Commit any modified repsFrom to the NC replica
n_rep.commit_repsFrom(self.samdb)
+ # HANDLE REPS-TO:
+ #
+ # Now perform the scan of replicas we'll need
+ # and compare any current repsTo against the
+ # connections
+
+ # RODC should never push to anybody (should we check this?)
+ if ro:
+ return
+
+ for n_rep in needed_rep_table.values():
+
+ # load any repsTo and fsmo roles as we'll
+ # need them during connection translation
+ n_rep.load_repsTo(self.samdb)
+
+ # Loop thru the existing repsTo tuples (if any)
+ # XXX This is a list and could contain duplicates
+ # (multiple load_repsTo calls)
+ for t_repsTo in n_rep.rep_repsTo:
+
+ # for each tuple t in n!repsTo, let s be the nTDSDSA
+ # object such that s!objectGUID = t.uuidDsa
+ guidstr = str(t_repsTo.source_dsa_obj_guid)
+ s_dsa = self.get_dsa_by_guidstr(guidstr)
+
+ # Source dsa is gone from config (strange)
+ # so cleanup stale repsTo for unlisted DSA
+ if s_dsa is None:
+ logger.warning("repsTo source DSA guid (%s) not found" %
+ guidstr)
+ t_repsTo.to_be_deleted = True
+ continue
+
+ # Find the connection that this repsTo would use. If
+ # there isn't a good one (i.e. non-RODC_TOPOLOGY,
+ # meaning non-FRS), we delete the repsTo.
+ s_dnstr = s_dsa.dsa_dnstr
+ if '\\0ADEL' in s_dnstr:
+ logger.warning("repsTo source DSA guid (%s) appears deleted" %
+ guidstr)
+ t_repsTo.to_be_deleted = True
+ continue
+
+ connections = s_dsa.get_connection_by_from_dnstr(self.my_dsa_dnstr)
+ if len(connections) > 0:
+ # Then this repsTo is tentatively valid
+ continue
+ else:
+ # There is no plausible connection for this repsTo
+ t_repsTo.to_be_deleted = True
+
+ if self.readonly:
+ # Display any to be deleted or modified repsTo
+ text = n_rep.dumpstr_reps_to()
+ if text:
+ logger.info("REMOVING REPS-TO:\n%s" % text)
+
+ # Peform deletion from our tables but perform
+ # no database modification
+ n_rep.commit_repsTo(self.samdb, ro=True)
+ else:
+ # Commit any modified repsTo to the NC replica
+ n_rep.commit_repsTo(self.samdb)
+
+ # TODO Remove any duplicate repsTo values. This should never happen in
+ # any normal situations.
+
def merge_failed_links(self, ping=None):
"""Merge of kCCFailedLinks and kCCFailedLinks from bridgeheads.
if not needed:
debug.DEBUG_RED("%s lacks 'should be present' status, "
- "aborting construct_intersite_graph!" %
+ "aborting construct_intrasite_graph!" %
nc_x.nc_dnstr)
return
while candidates and not tnode.has_sufficient_edges():
other = random.choice(candidates)
DEBUG("trying to add candidate %s" % other.dsa_dnstr)
- if not tnode.add_edge_from(other):
+ if not tnode.add_edge_from(other.dsa_dnstr):
debug.DEBUG_RED("could not add %s" % other.dsa_dnstr)
candidates.remove(other)
else: