<s> import ldb <EOL> import uuid <EOL> import time <EOL> from samba import dsdb , unix2nttime <EOL> from samba . dcerpc import ( <EOL> drsblobs , <EOL> drsuapi , <EOL> misc , <EOL> ) <EOL> from samba . common import dsdb_Dn <EOL> from samba . ndr import ( ndr_unpack , ndr_pack ) <EOL> class NCType ( object ) : <EOL> ( unknown , schema , domain , config , application ) = range ( <NUM_LIT:0> , <NUM_LIT:5> ) <EOL> class NamingContext ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , nc_dnstr ) : <EOL> """<STR_LIT>""" <EOL> self . nc_dnstr = nc_dnstr <EOL> self . nc_guid = None <EOL> self . nc_sid = None <EOL> self . nc_type = NCType . unknown <EOL> def __str__ ( self ) : <EOL> '''<STR_LIT>''' <EOL> text = "<STR_LIT>" % self . __class__ . __name__ <EOL> text = text + "<STR_LIT>" % self . nc_dnstr <EOL> text = text + "<STR_LIT>" % str ( self . nc_guid ) <EOL> if self . nc_sid is None : <EOL> text = text + "<STR_LIT>" <EOL> else : <EOL> text = text + "<STR_LIT>" <EOL> text = text + "<STR_LIT>" % self . nc_type <EOL> return text <EOL> def load_nc ( self , samdb ) : <EOL> attrs = [ "<STR_LIT>" , <EOL> "<STR_LIT>" ] <EOL> try : <EOL> res = samdb . search ( base = self . nc_dnstr , <EOL> scope = ldb . SCOPE_BASE , attrs = attrs ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . nc_dnstr , estr ) ) <EOL> msg = res [ <NUM_LIT:0> ] <EOL> if "<STR_LIT>" in msg : <EOL> self . nc_guid = misc . GUID ( samdb . schema_format_value ( "<STR_LIT>" , <EOL> msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) ) <EOL> if "<STR_LIT>" in msg : <EOL> self . nc_sid = msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] <EOL> assert self . nc_guid is not None <EOL> def is_schema ( self ) : <EOL> '''<STR_LIT>''' <EOL> assert self . nc_type != NCType . unknown <EOL> return self . nc_type == NCType . schema <EOL> def is_domain ( self ) : <EOL> '''<STR_LIT>''' <EOL> assert self . nc_type != NCType . unknown <EOL> return self . nc_type == NCType . domain <EOL> def is_application ( self ) : <EOL> '''<STR_LIT>''' <EOL> assert self . nc_type != NCType . unknown <EOL> return self . nc_type == NCType . application <EOL> def is_config ( self ) : <EOL> '''<STR_LIT>''' <EOL> assert self . nc_type != NCType . unknown <EOL> return self . nc_type == NCType . config <EOL> def identify_by_basedn ( self , samdb ) : <EOL> """<STR_LIT>""" <EOL> if self . nc_guid is None : <EOL> self . load_nc ( samdb ) <EOL> if self . nc_dnstr == str ( samdb . get_schema_basedn ( ) ) : <EOL> self . nc_type = NCType . schema <EOL> elif self . nc_dnstr == str ( samdb . get_config_basedn ( ) ) : <EOL> self . nc_type = NCType . config <EOL> elif self . nc_sid is not None : <EOL> self . nc_type = NCType . domain <EOL> else : <EOL> self . nc_type = NCType . application <EOL> def identify_by_dsa_attr ( self , samdb , attr ) : <EOL> """<STR_LIT>""" <EOL> if attr == "<STR_LIT>" : <EOL> self . nc_type = NCType . domain <EOL> elif attr == "<STR_LIT>" : <EOL> self . nc_type = NCType . domain <EOL> elif attr == "<STR_LIT>" : <EOL> self . identify_by_basedn ( samdb ) <EOL> if self . nc_type == NCType . unknown : <EOL> self . identify_by_basedn ( samdb ) <EOL> class NCReplica ( NamingContext ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , dsa_dnstr , dsa_guid , nc_dnstr ) : <EOL> """<STR_LIT>""" <EOL> self . rep_dsa_dnstr = dsa_dnstr <EOL> self . rep_dsa_guid = dsa_guid <EOL> self . rep_default = False <EOL> self . rep_partial = False <EOL> self . rep_ro = False <EOL> self . rep_instantiated_flags = <NUM_LIT:0> <EOL> self . rep_fsmo_role_owner = None <EOL> self . rep_repsFrom = [ ] <EOL> self . rep_present_criteria_one = False <EOL> NamingContext . __init__ ( self , nc_dnstr ) <EOL> def __str__ ( self ) : <EOL> '''<STR_LIT>''' <EOL> text = "<STR_LIT>" % self . __class__ . __name__ <EOL> text = text + "<STR_LIT>" % self . rep_dsa_dnstr <EOL> text = text + "<STR_LIT>" % str ( self . rep_dsa_guid ) <EOL> text = text + "<STR_LIT>" % self . rep_default <EOL> text = text + "<STR_LIT>" % self . rep_ro <EOL> text = text + "<STR_LIT>" % self . rep_partial <EOL> text = text + "<STR_LIT>" % self . is_present ( ) <EOL> text = text + "<STR_LIT>" % self . rep_fsmo_role_owner <EOL> for rep in self . rep_repsFrom : <EOL> text = text + "<STR_LIT>" % rep <EOL> return "<STR_LIT>" % ( NamingContext . __str__ ( self ) , text ) <EOL> def set_instantiated_flags ( self , flags = None ) : <EOL> '''<STR_LIT>''' <EOL> if flags is None : <EOL> self . rep_instantiated_flags = <NUM_LIT:0> <EOL> else : <EOL> self . rep_instantiated_flags = flags <EOL> def identify_by_dsa_attr ( self , samdb , attr ) : <EOL> """<STR_LIT>""" <EOL> if attr == "<STR_LIT>" : <EOL> self . rep_partial = True <EOL> self . rep_present_criteria_one = True <EOL> elif attr == "<STR_LIT>" : <EOL> self . rep_default = True <EOL> elif attr == "<STR_LIT>" : <EOL> self . rep_present_criteria_one = True <EOL> if self . nc_dnstr != str ( samdb . get_schema_basedn ( ) ) and self . nc_dnstr != str ( samdb . get_config_basedn ( ) ) : <EOL> self . rep_default = True <EOL> elif attr == "<STR_LIT>" : <EOL> self . rep_present_criteria_one = True <EOL> self . rep_ro = True <EOL> elif attr == "<STR_LIT>" : <EOL> self . rep_ro = False <EOL> NamingContext . identify_by_dsa_attr ( self , samdb , attr ) <EOL> def is_default ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . rep_default <EOL> def is_ro ( self ) : <EOL> '''<STR_LIT>''' <EOL> return self . rep_ro <EOL> def is_partial ( self ) : <EOL> '''<STR_LIT>''' <EOL> return self . rep_partial <EOL> def is_present ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . rep_present_criteria_one and self . rep_instantiated_flags & dsdb . INSTANCE_TYPE_NC_GOING == <NUM_LIT:0> : <EOL> return True <EOL> return False <EOL> def load_repsFrom ( self , samdb ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> res = samdb . search ( base = self . nc_dnstr , scope = ldb . SCOPE_BASE , <EOL> attrs = [ "<STR_LIT>" ] ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . nc_dnstr , estr ) ) <EOL> msg = res [ <NUM_LIT:0> ] <EOL> if "<STR_LIT>" in msg : <EOL> for value in msg [ "<STR_LIT>" ] : <EOL> rep = RepsFromTo ( self . nc_dnstr , <EOL> ndr_unpack ( drsblobs . repsFromToBlob , value ) ) <EOL> self . rep_repsFrom . append ( rep ) <EOL> def commit_repsFrom ( self , samdb , ro = False ) : <EOL> """<STR_LIT>""" <EOL> modify = False <EOL> newreps = [ ] <EOL> delreps = [ ] <EOL> for repsFrom in self . rep_repsFrom : <EOL> if repsFrom . to_be_deleted : <EOL> delreps . append ( repsFrom ) <EOL> modify = True <EOL> continue <EOL> if repsFrom . is_modified ( ) : <EOL> repsFrom . set_unmodified ( ) <EOL> modify = True <EOL> newreps . append ( ndr_pack ( repsFrom . ndr_blob ) ) <EOL> for repsFrom in delreps : <EOL> self . rep_repsFrom . remove ( repsFrom ) <EOL> delreps = [ ] <EOL> if not modify or ro : <EOL> return <EOL> m = ldb . Message ( ) <EOL> m . dn = ldb . Dn ( samdb , self . nc_dnstr ) <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( newreps , ldb . FLAG_MOD_REPLACE , "<STR_LIT>" ) <EOL> try : <EOL> samdb . modify ( m ) <EOL> except ldb . LdbError , estr : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . dsa_dnstr , estr ) ) <EOL> def dumpstr_to_be_deleted ( self ) : <EOL> text = "<STR_LIT>" <EOL> for repsFrom in self . rep_repsFrom : <EOL> if repsFrom . to_be_deleted : <EOL> if text : <EOL> text = text + "<STR_LIT>" % repsFrom <EOL> else : <EOL> text = "<STR_LIT:%s>" % repsFrom <EOL> return text <EOL> def dumpstr_to_be_modified ( self ) : <EOL> text = "<STR_LIT>" <EOL> for repsFrom in self . rep_repsFrom : <EOL> if repsFrom . is_modified ( ) : <EOL> if text : <EOL> text = text + "<STR_LIT>" % repsFrom <EOL> else : <EOL> text = "<STR_LIT:%s>" % repsFrom <EOL> return text <EOL> def load_fsmo_roles ( self , samdb ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> res = samdb . search ( base = self . nc_dnstr , scope = ldb . SCOPE_BASE , <EOL> attrs = [ "<STR_LIT>" ] ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . nc_dnstr , estr ) ) <EOL> msg = res [ <NUM_LIT:0> ] <EOL> if "<STR_LIT>" in msg : <EOL> self . rep_fsmo_role_owner = msg [ "<STR_LIT>" ] <EOL> def is_fsmo_role_owner ( self , dsa_dnstr ) : <EOL> if self . rep_fsmo_role_owner is not None and self . rep_fsmo_role_owner == dsa_dnstr : <EOL> return True <EOL> return False <EOL> class DirectoryServiceAgent ( object ) : <EOL> def __init__ ( self , dsa_dnstr ) : <EOL> """<STR_LIT>""" <EOL> self . dsa_dnstr = dsa_dnstr <EOL> self . dsa_guid = None <EOL> self . dsa_ivid = None <EOL> self . dsa_is_ro = False <EOL> self . dsa_is_istg = False <EOL> self . dsa_options = <NUM_LIT:0> <EOL> self . dsa_behavior = <NUM_LIT:0> <EOL> self . default_dnstr = None <EOL> self . current_rep_table = { } <EOL> self . needed_rep_table = { } <EOL> self . connect_table = { } <EOL> def __str__ ( self ) : <EOL> '''<STR_LIT>''' <EOL> text = "<STR_LIT>" % self . __class__ . __name__ <EOL> if self . dsa_dnstr is not None : <EOL> text = text + "<STR_LIT>" % self . dsa_dnstr <EOL> if self . dsa_guid is not None : <EOL> text = text + "<STR_LIT>" % str ( self . dsa_guid ) <EOL> if self . dsa_ivid is not None : <EOL> text = text + "<STR_LIT>" % str ( self . dsa_ivid ) <EOL> text = text + "<STR_LIT>" % self . is_ro ( ) <EOL> text = text + "<STR_LIT>" % self . is_gc ( ) <EOL> text = text + "<STR_LIT>" % self . is_istg ( ) <EOL> text = text + "<STR_LIT>" <EOL> text = text + "<STR_LIT>" % self . dumpstr_current_replica_table ( ) <EOL> text = text + "<STR_LIT>" <EOL> text = text + "<STR_LIT>" % self . dumpstr_needed_replica_table ( ) <EOL> text = text + "<STR_LIT>" <EOL> text = text + "<STR_LIT>" % self . dumpstr_connect_table ( ) <EOL> return text <EOL> def get_current_replica ( self , nc_dnstr ) : <EOL> if nc_dnstr in self . current_rep_table . keys ( ) : <EOL> return self . current_rep_table [ nc_dnstr ] <EOL> else : <EOL> return None <EOL> def is_istg ( self ) : <EOL> '''<STR_LIT>''' <EOL> return self . dsa_is_istg or self . dsa_is_ro <EOL> def is_ro ( self ) : <EOL> '''<STR_LIT>''' <EOL> return self . dsa_is_ro <EOL> def is_gc ( self ) : <EOL> '''<STR_LIT>''' <EOL> if ( self . options & dsdb . DS_NTDSDSA_OPT_IS_GC ) != <NUM_LIT:0> : <EOL> return True <EOL> return False <EOL> def is_minimum_behavior ( self , version ) : <EOL> """<STR_LIT>""" <EOL> if self . dsa_behavior >= version : <EOL> return True <EOL> return False <EOL> def is_translate_ntdsconn_disabled ( self ) : <EOL> """<STR_LIT>""" <EOL> if ( self . options & dsdb . DS_NTDSDSA_OPT_DISABLE_NTDSCONN_XLATE ) != <NUM_LIT:0> : <EOL> return True <EOL> return False <EOL> def get_rep_tables ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . current_rep_table , self . needed_rep_table <EOL> def get_parent_dnstr ( self ) : <EOL> """<STR_LIT>""" <EOL> head , sep , tail = self . dsa_dnstr . partition ( '<STR_LIT:U+002C>' ) <EOL> return tail <EOL> def load_dsa ( self , samdb ) : <EOL> """<STR_LIT>""" <EOL> attrs = [ "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" ] <EOL> try : <EOL> res = samdb . search ( base = self . dsa_dnstr , scope = ldb . SCOPE_BASE , <EOL> attrs = attrs ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . dsa_dnstr , estr ) ) <EOL> msg = res [ <NUM_LIT:0> ] <EOL> self . dsa_guid = misc . GUID ( samdb . schema_format_value ( "<STR_LIT>" , <EOL> msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) ) <EOL> if "<STR_LIT>" in msg : <EOL> self . dsa_ivid = misc . GUID ( samdb . schema_format_value ( "<STR_LIT>" , <EOL> msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) ) <EOL> if "<STR_LIT>" in msg : <EOL> self . options = int ( msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT>" in msg and msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] == "<STR_LIT>" : <EOL> self . dsa_is_ro = True <EOL> else : <EOL> self . dsa_is_ro = False <EOL> if "<STR_LIT>" in msg : <EOL> self . dsa_behavior = int ( msg [ '<STR_LIT>' ] [ <NUM_LIT:0> ] ) <EOL> self . load_current_replica_table ( samdb ) <EOL> self . load_connection_table ( samdb ) <EOL> def load_current_replica_table ( self , samdb ) : <EOL> """<STR_LIT>""" <EOL> ncattrs = [ <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" ] <EOL> try : <EOL> res = samdb . search ( base = self . dsa_dnstr , scope = ldb . SCOPE_BASE , <EOL> attrs = ncattrs ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . dsa_dnstr , estr ) ) <EOL> tmp_table = { } <EOL> if len ( res [ <NUM_LIT:0> ] ) > <NUM_LIT:0> : <EOL> for k in res [ <NUM_LIT:0> ] . keys ( ) : <EOL> if k == "<STR_LIT>" : <EOL> continue <EOL> for value in res [ <NUM_LIT:0> ] [ k ] : <EOL> dsdn = dsdb_Dn ( samdb , value ) <EOL> flags = dsdn . get_binary_integer ( ) <EOL> dnstr = str ( dsdn . dn ) <EOL> if not dnstr in tmp_table . keys ( ) : <EOL> rep = NCReplica ( self . dsa_dnstr , self . dsa_guid , dnstr ) <EOL> tmp_table [ dnstr ] = rep <EOL> else : <EOL> rep = tmp_table [ dnstr ] <EOL> if k == "<STR_LIT>" : <EOL> rep . set_instantiated_flags ( flags ) <EOL> continue <EOL> rep . identify_by_dsa_attr ( samdb , k ) <EOL> if rep . is_default ( ) : <EOL> self . default_dnstr = dnstr <EOL> else : <EOL> raise Exception ( "<STR_LIT>" % self . dsa_dnstr ) <EOL> self . current_rep_table = tmp_table <EOL> def add_needed_replica ( self , rep ) : <EOL> """<STR_LIT>""" <EOL> if not rep . nc_dnstr in self . needed_rep_table . keys ( ) : <EOL> self . needed_rep_table [ rep . nc_dnstr ] = rep <EOL> def load_connection_table ( self , samdb ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> res = samdb . search ( base = self . dsa_dnstr , <EOL> scope = ldb . SCOPE_SUBTREE , <EOL> expression = "<STR_LIT>" ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . dsa_dnstr , estr ) ) <EOL> for msg in res : <EOL> dnstr = str ( msg . dn ) <EOL> if dnstr in self . connect_table . keys ( ) : <EOL> continue <EOL> connect = NTDSConnection ( dnstr ) <EOL> connect . load_connection ( samdb ) <EOL> self . connect_table [ dnstr ] = connect <EOL> def commit_connections ( self , samdb , ro = False ) : <EOL> """<STR_LIT>""" <EOL> delconn = [ ] <EOL> for dnstr , connect in self . connect_table . items ( ) : <EOL> if connect . to_be_added : <EOL> connect . commit_added ( samdb , ro ) <EOL> if connect . to_be_modified : <EOL> connect . commit_modified ( samdb , ro ) <EOL> if connect . to_be_deleted : <EOL> connect . commit_deleted ( samdb , ro ) <EOL> delconn . append ( dnstr ) <EOL> for dnstr in delconn : <EOL> del self . connect_table [ dnstr ] <EOL> def add_connection ( self , dnstr , connect ) : <EOL> assert dnstr not in self . connect_table . keys ( ) <EOL> self . connect_table [ dnstr ] = connect <EOL> def get_connection_by_from_dnstr ( self , from_dnstr ) : <EOL> """<STR_LIT>""" <EOL> for dnstr , connect in self . connect_table . items ( ) : <EOL> if connect . get_from_dnstr ( ) == from_dnstr : <EOL> return connect <EOL> return None <EOL> def dumpstr_current_replica_table ( self ) : <EOL> '''<STR_LIT>''' <EOL> text = "<STR_LIT>" <EOL> for k in self . current_rep_table . keys ( ) : <EOL> if text : <EOL> text = text + "<STR_LIT>" % self . current_rep_table [ k ] <EOL> else : <EOL> text = "<STR_LIT:%s>" % self . current_rep_table [ k ] <EOL> return text <EOL> def dumpstr_needed_replica_table ( self ) : <EOL> '''<STR_LIT>''' <EOL> text = "<STR_LIT>" <EOL> for k in self . needed_rep_table . keys ( ) : <EOL> if text : <EOL> text = text + "<STR_LIT>" % self . needed_rep_table [ k ] <EOL> else : <EOL> text = "<STR_LIT:%s>" % self . needed_rep_table [ k ] <EOL> return text <EOL> def dumpstr_connect_table ( self ) : <EOL> '''<STR_LIT>''' <EOL> text = "<STR_LIT>" <EOL> for k in self . connect_table . keys ( ) : <EOL> if text : <EOL> text = text + "<STR_LIT>" % self . connect_table [ k ] <EOL> else : <EOL> text = "<STR_LIT:%s>" % self . connect_table [ k ] <EOL> return text <EOL> def new_connection ( self , options , flags , transport , from_dnstr , sched ) : <EOL> """<STR_LIT>""" <EOL> dnstr = "<STR_LIT>" % str ( uuid . uuid4 ( ) ) + self . dsa_dnstr <EOL> connect = NTDSConnection ( dnstr ) <EOL> connect . to_be_added = True <EOL> connect . enabled = True <EOL> connect . from_dnstr = from_dnstr <EOL> connect . options = options <EOL> connect . flags = flags <EOL> if transport is not None : <EOL> connect . transport_dnstr = transport . dnstr <EOL> if sched is not None : <EOL> connect . schedule = sched <EOL> else : <EOL> connect . schedule = drsblobs . schedule ( ) <EOL> connect . schedule . size = <NUM_LIT> <EOL> connect . schedule . bandwidth = <NUM_LIT:0> <EOL> connect . schedule . numberOfSchedules = <NUM_LIT:1> <EOL> header = drsblobs . scheduleHeader ( ) <EOL> header . type = <NUM_LIT:0> <EOL> header . offset = <NUM_LIT:20> <EOL> connect . schedule . headerArray = [ header ] <EOL> data = drsblobs . scheduleSlots ( ) <EOL> data . slots = [ <NUM_LIT> ] * <NUM_LIT> <EOL> connect . schedule . dataArray = [ data ] <EOL> self . add_connection ( dnstr , connect ) ; <EOL> return connect <EOL> class NTDSConnection ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , dnstr ) : <EOL> self . dnstr = dnstr <EOL> self . guid = None <EOL> self . enabled = False <EOL> self . whenCreated = <NUM_LIT:0> <EOL> self . to_be_added = False <EOL> self . to_be_deleted = False <EOL> self . to_be_modified = False <EOL> self . options = <NUM_LIT:0> <EOL> self . system_flags = <NUM_LIT:0> <EOL> self . transport_dnstr = None <EOL> self . transport_guid = None <EOL> self . from_dnstr = None <EOL> self . schedule = None <EOL> def __str__ ( self ) : <EOL> '''<STR_LIT>''' <EOL> text = "<STR_LIT>" % ( self . __class__ . __name__ , self . dnstr ) <EOL> text = text + "<STR_LIT>" % self . enabled <EOL> text = text + "<STR_LIT>" % self . to_be_added <EOL> text = text + "<STR_LIT>" % self . to_be_deleted <EOL> text = text + "<STR_LIT>" % self . to_be_modified <EOL> text = text + "<STR_LIT>" % self . options <EOL> text = text + "<STR_LIT>" % self . system_flags <EOL> text = text + "<STR_LIT>" % self . whenCreated <EOL> text = text + "<STR_LIT>" % self . transport_dnstr <EOL> if self . guid is not None : <EOL> text = text + "<STR_LIT>" % str ( self . guid ) <EOL> if self . transport_guid is not None : <EOL> text = text + "<STR_LIT>" % str ( self . transport_guid ) <EOL> text = text + "<STR_LIT>" % self . from_dnstr <EOL> if self . schedule is not None : <EOL> text = text + "<STR_LIT>" % self . schedule . size <EOL> text = text + "<STR_LIT>" % self . schedule . bandwidth <EOL> text = text + "<STR_LIT>" % self . schedule . numberOfSchedules <EOL> for i , header in enumerate ( self . schedule . headerArray ) : <EOL> text = text + "<STR_LIT>" % ( i , header . type ) <EOL> text = text + "<STR_LIT>" % ( i , header . offset ) <EOL> text = text + "<STR_LIT>" % i <EOL> for slot in self . schedule . dataArray [ i ] . slots : <EOL> text = text + "<STR_LIT>" % slot <EOL> text = text + "<STR_LIT:]>" <EOL> return text <EOL> def load_connection ( self , samdb ) : <EOL> """<STR_LIT>""" <EOL> attrs = [ "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" ] <EOL> try : <EOL> res = samdb . search ( base = self . dnstr , scope = ldb . SCOPE_BASE , <EOL> attrs = attrs ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . dnstr , estr ) ) <EOL> msg = res [ <NUM_LIT:0> ] <EOL> if "<STR_LIT>" in msg : <EOL> self . options = int ( msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT>" in msg : <EOL> if msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] . upper ( ) . lstrip ( ) . rstrip ( ) == "<STR_LIT>" : <EOL> self . enabled = True <EOL> if "<STR_LIT>" in msg : <EOL> self . system_flags = int ( msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT>" in msg : <EOL> self . guid = misc . GUID ( samdb . schema_format_value ( "<STR_LIT>" , <EOL> msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) ) <EOL> if "<STR_LIT>" in msg : <EOL> dsdn = dsdb_Dn ( samdb , msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> self . load_connection_transport ( str ( dsdn . dn ) ) <EOL> if "<STR_LIT>" in msg : <EOL> self . schedule = ndr_unpack ( drsblobs . replSchedule , msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT>" in msg : <EOL> self . whenCreated = ldb . string_to_time ( msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT>" in msg : <EOL> dsdn = dsdb_Dn ( samdb , msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> self . from_dnstr = str ( dsdn . dn ) <EOL> assert self . from_dnstr is not None <EOL> def load_connection_transport ( self , tdnstr ) : <EOL> """<STR_LIT>""" <EOL> attrs = [ "<STR_LIT>" ] <EOL> try : <EOL> res = samdb . search ( base = tdnstr , <EOL> scope = ldb . SCOPE_BASE , attrs = attrs ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( tdnstr , estr ) ) <EOL> if "<STR_LIT>" in res [ <NUM_LIT:0> ] : <EOL> self . transport_dnstr = tdnstr <EOL> self . transport_guid = misc . GUID ( samdb . schema_format_value ( "<STR_LIT>" , <EOL> msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) ) <EOL> assert self . transport_dnstr is not None <EOL> assert self . transport_guid is not None <EOL> def commit_deleted ( self , samdb , ro = False ) : <EOL> """<STR_LIT>""" <EOL> assert self . to_be_deleted <EOL> self . to_be_deleted = False <EOL> if ro : <EOL> return <EOL> try : <EOL> samdb . delete ( self . dnstr ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . dnstr , estr ) ) <EOL> def commit_added ( self , samdb , ro = False ) : <EOL> """<STR_LIT>""" <EOL> assert self . to_be_added <EOL> self . to_be_added = False <EOL> if ro : <EOL> return <EOL> found = False <EOL> try : <EOL> msg = samdb . search ( base = self . dnstr , scope = ldb . SCOPE_BASE ) <EOL> if len ( msg ) != <NUM_LIT:0> : <EOL> found = True <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> if enum != ldb . ERR_NO_SUCH_OBJECT : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . dnstr , estr ) ) <EOL> if found : <EOL> raise Exception ( "<STR_LIT>" % <EOL> self . dnstr ) <EOL> if self . enabled : <EOL> enablestr = "<STR_LIT>" <EOL> else : <EOL> enablestr = "<STR_LIT>" <EOL> m = ldb . Message ( ) <EOL> m . dn = ldb . Dn ( samdb , self . dnstr ) <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( "<STR_LIT>" , ldb . FLAG_MOD_ADD , <EOL> "<STR_LIT>" ) <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( "<STR_LIT>" , ldb . FLAG_MOD_ADD , <EOL> "<STR_LIT>" ) <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( enablestr , ldb . FLAG_MOD_ADD , "<STR_LIT>" ) <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( self . from_dnstr , ldb . FLAG_MOD_ADD , "<STR_LIT>" ) <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( str ( self . options ) , ldb . FLAG_MOD_ADD , "<STR_LIT>" ) <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( str ( self . system_flags ) , ldb . FLAG_MOD_ADD , <EOL> "<STR_LIT>" ) <EOL> if self . transport_dnstr is not None : <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( str ( self . transport_dnstr ) , ldb . FLAG_MOD_ADD , <EOL> "<STR_LIT>" ) <EOL> if self . schedule is not None : <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( ndr_pack ( self . schedule ) , <EOL> ldb . FLAG_MOD_ADD , "<STR_LIT>" ) <EOL> try : <EOL> samdb . add ( m ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . dnstr , estr ) ) <EOL> def commit_modified ( self , samdb , ro = False ) : <EOL> """<STR_LIT>""" <EOL> assert self . to_be_modified <EOL> self . to_be_modified = False <EOL> if ro : <EOL> return <EOL> try : <EOL> msg = samdb . search ( base = self . dnstr , scope = ldb . SCOPE_BASE ) <EOL> found = True <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> if enum == ldb . ERR_NO_SUCH_OBJECT : <EOL> found = False <EOL> else : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . dnstr , estr ) ) <EOL> if not found : <EOL> raise Exception ( "<STR_LIT>" % <EOL> self . dnstr ) <EOL> if self . enabled : <EOL> enablestr = "<STR_LIT>" <EOL> else : <EOL> enablestr = "<STR_LIT>" <EOL> m = ldb . Message ( ) <EOL> m . dn = ldb . Dn ( samdb , self . dnstr ) <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( enablestr , ldb . FLAG_MOD_REPLACE , <EOL> "<STR_LIT>" ) <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( self . from_dnstr , ldb . FLAG_MOD_REPLACE , <EOL> "<STR_LIT>" ) <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( str ( self . options ) , ldb . FLAG_MOD_REPLACE , <EOL> "<STR_LIT>" ) <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( str ( self . system_flags ) , ldb . FLAG_MOD_REPLACE , <EOL> "<STR_LIT>" ) <EOL> if self . transport_dnstr is not None : <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( str ( self . transport_dnstr ) , <EOL> ldb . FLAG_MOD_REPLACE , "<STR_LIT>" ) <EOL> else : <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( [ ] , ldb . FLAG_MOD_DELETE , "<STR_LIT>" ) <EOL> if self . schedule is not None : <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( ndr_pack ( self . schedule ) , <EOL> ldb . FLAG_MOD_REPLACE , "<STR_LIT>" ) <EOL> else : <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( [ ] , ldb . FLAG_MOD_DELETE , "<STR_LIT>" ) <EOL> try : <EOL> samdb . modify ( m ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . dnstr , estr ) ) <EOL> def set_modified ( self , truefalse ) : <EOL> self . to_be_modified = truefalse <EOL> def set_added ( self , truefalse ) : <EOL> self . to_be_added = truefalse <EOL> def set_deleted ( self , truefalse ) : <EOL> self . to_be_deleted = truefalse <EOL> def is_schedule_minimum_once_per_week ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . schedule is None or self . schedule . dataArray [ <NUM_LIT:0> ] is None : <EOL> return False <EOL> for slot in self . schedule . dataArray [ <NUM_LIT:0> ] . slots : <EOL> if ( slot & <NUM_LIT> ) != <NUM_LIT> : <EOL> return True <EOL> return False <EOL> def is_equivalent_schedule ( self , sched ) : <EOL> """<STR_LIT>""" <EOL> if self . schedule is not None : <EOL> if sched is None : <EOL> return False <EOL> elif sched is None : <EOL> return True <EOL> if ( self . schedule . size != sched . size or <EOL> self . schedule . bandwidth != sched . bandwidth or <EOL> self . schedule . numberOfSchedules != sched . numberOfSchedules ) : <EOL> return False <EOL> for i , header in enumerate ( self . schedule . headerArray ) : <EOL> if self . schedule . headerArray [ i ] . type != sched . headerArray [ i ] . type : <EOL> return False <EOL> if self . schedule . headerArray [ i ] . offset != sched . headerArray [ i ] . offset : <EOL> return False <EOL> for a , b in zip ( self . schedule . dataArray [ i ] . slots , <EOL> sched . dataArray [ i ] . slots ) : <EOL> if a != b : <EOL> return False <EOL> return True <EOL> def convert_schedule_to_repltimes ( self ) : <EOL> """<STR_LIT>""" <EOL> times = [ <NUM_LIT> ] * <NUM_LIT> <EOL> for i , slot in enumerate ( times ) : <EOL> if self . schedule is not None and self . schedule . dataArray [ <NUM_LIT:0> ] is not None : <EOL> slot = ( self . schedule . dataArray [ <NUM_LIT:0> ] . slots [ i * <NUM_LIT:2> ] & <NUM_LIT> ) << <NUM_LIT:4> | ( self . schedule . dataArray [ <NUM_LIT:0> ] . slots [ i * <NUM_LIT:2> ] & <NUM_LIT> ) <EOL> return times <EOL> def is_rodc_topology ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . options & dsdb . NTDSCONN_OPT_RODC_TOPOLOGY == <NUM_LIT:0> : <EOL> return False <EOL> return True <EOL> def is_generated ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . options & dsdb . NTDSCONN_OPT_IS_GENERATED == <NUM_LIT:0> : <EOL> return False <EOL> return True <EOL> def is_override_notify_default ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . options & dsdb . NTDSCONN_OPT_OVERRIDE_NOTIFY_DEFAULT == <NUM_LIT:0> : <EOL> return False <EOL> return True <EOL> def is_use_notify ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . options & dsdb . NTDSCONN_OPT_USE_NOTIFY == <NUM_LIT:0> : <EOL> return False <EOL> return True <EOL> def is_twoway_sync ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . options & dsdb . NTDSCONN_OPT_TWOWAY_SYNC == <NUM_LIT:0> : <EOL> return False <EOL> return True <EOL> def is_intersite_compression_disabled ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . options & dsdb . NTDSCONN_OPT_DISABLE_INTERSITE_COMPRESSION == <NUM_LIT:0> : <EOL> return False <EOL> return True <EOL> def is_user_owned_schedule ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . options & dsdb . NTDSCONN_OPT_USER_OWNED_SCHEDULE == <NUM_LIT:0> : <EOL> return False <EOL> return True <EOL> def is_enabled ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . enabled <EOL> def get_from_dnstr ( self ) : <EOL> '''<STR_LIT>''' <EOL> return self . from_dnstr <EOL> class Partition ( NamingContext ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , partstr ) : <EOL> self . partstr = partstr <EOL> self . enabled = True <EOL> self . system_flags = <NUM_LIT:0> <EOL> self . rw_location_list = [ ] <EOL> self . ro_location_list = [ ] <EOL> NamingContext . __init__ ( self , None ) <EOL> def load_partition ( self , samdb ) : <EOL> """<STR_LIT>""" <EOL> attrs = [ "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" ] <EOL> try : <EOL> res = samdb . search ( base = self . partstr , scope = ldb . SCOPE_BASE , <EOL> attrs = attrs ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % ( <EOL> self . partstr , estr ) ) <EOL> msg = res [ <NUM_LIT:0> ] <EOL> for k in msg . keys ( ) : <EOL> if k == "<STR_LIT>" : <EOL> continue <EOL> if k == "<STR_LIT>" : <EOL> if msg [ k ] [ <NUM_LIT:0> ] . upper ( ) . lstrip ( ) . rstrip ( ) == "<STR_LIT>" : <EOL> self . enabled = True <EOL> else : <EOL> self . enabled = False <EOL> continue <EOL> if k == "<STR_LIT>" : <EOL> self . system_flags = int ( msg [ k ] [ <NUM_LIT:0> ] ) <EOL> continue <EOL> for value in msg [ k ] : <EOL> dsdn = dsdb_Dn ( samdb , value ) <EOL> dnstr = str ( dsdn . dn ) <EOL> if k == "<STR_LIT>" : <EOL> self . nc_dnstr = dnstr <EOL> continue <EOL> if k == "<STR_LIT>" : <EOL> self . rw_location_list . append ( dnstr ) <EOL> continue <EOL> if k == "<STR_LIT>" : <EOL> self . ro_location_list . append ( dnstr ) <EOL> continue <EOL> self . identify_by_basedn ( samdb ) <EOL> def is_enabled ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . is_enabled <EOL> def is_foreign ( self ) : <EOL> """<STR_LIT>""" <EOL> if ( self . system_flags & dsdb . SYSTEM_FLAG_CR_NTDS_NC ) == <NUM_LIT:0> : <EOL> return True <EOL> else : <EOL> return False <EOL> def should_be_present ( self , target_dsa ) : <EOL> """<STR_LIT>""" <EOL> needed = False <EOL> ro = False <EOL> partial = False <EOL> if self . nc_type == NCType . config or self . nc_type == NCType . schema or ( self . nc_type == NCType . domain and <EOL> self . nc_dnstr == target_dsa . default_dnstr ) : <EOL> needed = True <EOL> if self . nc_type == NCType . application : <EOL> if target_dsa . is_ro ( ) : <EOL> if target_dsa . dsa_dnstr in self . ro_location_list : <EOL> needed = True <EOL> else : <EOL> if target_dsa . dsa_dnstr in self . rw_location_list : <EOL> needed = True <EOL> if target_dsa . is_gc ( ) and self . nc_type == NCType . domain and self . nc_dnstr != target_dsa . default_dnstr and ( target_dsa . dsa_dnstr in self . ro_location_list or <EOL> target_dsa . dsa_dnstr in self . rw_location_list ) : <EOL> needed = True <EOL> partial = True <EOL> if needed and ( target_dsa . is_ro ( ) or partial ) : <EOL> ro = True <EOL> return needed , ro , partial <EOL> def __str__ ( self ) : <EOL> '''<STR_LIT>''' <EOL> text = "<STR_LIT:%s>" % NamingContext . __str__ ( self ) <EOL> text = text + "<STR_LIT>" % self . partstr <EOL> for k in self . rw_location_list : <EOL> text = text + "<STR_LIT>" % k <EOL> for k in self . ro_location_list : <EOL> text = text + "<STR_LIT>" % k <EOL> return text <EOL> class Site ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , site_dnstr ) : <EOL> self . site_dnstr = site_dnstr <EOL> self . site_options = <NUM_LIT:0> <EOL> self . site_topo_generator = None <EOL> self . site_topo_failover = <NUM_LIT:0> <EOL> self . dsa_table = { } <EOL> def load_site ( self , samdb ) : <EOL> """<STR_LIT>""" <EOL> ssdn = "<STR_LIT>" % self . site_dnstr <EOL> attrs = [ "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" ] <EOL> try : <EOL> res = samdb . search ( base = ssdn , scope = ldb . SCOPE_BASE , <EOL> attrs = attrs ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( ssdn , estr ) ) <EOL> msg = res [ <NUM_LIT:0> ] <EOL> if "<STR_LIT>" in msg : <EOL> self . site_options = int ( msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT>" in msg : <EOL> self . site_topo_generator = str ( msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT>" in msg : <EOL> self . site_topo_failover = int ( msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> self . load_all_dsa ( samdb ) <EOL> def load_all_dsa ( self , samdb ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> res = samdb . search ( self . site_dnstr , <EOL> scope = ldb . SCOPE_SUBTREE , <EOL> expression = "<STR_LIT>" ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % estr ) <EOL> for msg in res : <EOL> dnstr = str ( msg . dn ) <EOL> if dnstr in self . dsa_table . keys ( ) : <EOL> continue <EOL> dsa = DirectoryServiceAgent ( dnstr ) <EOL> dsa . load_dsa ( samdb ) <EOL> self . dsa_table [ dnstr ] = dsa <EOL> def get_dsa_by_guidstr ( self , guidstr ) : <EOL> for dsa in self . dsa_table . values ( ) : <EOL> if str ( dsa . dsa_guid ) == guidstr : <EOL> return dsa <EOL> return None <EOL> def get_dsa ( self , dnstr ) : <EOL> """<STR_LIT>""" <EOL> if dnstr in self . dsa_table . keys ( ) : <EOL> return self . dsa_table [ dnstr ] <EOL> return None <EOL> def select_istg ( self , samdb , mydsa , ro ) : <EOL> """<STR_LIT>""" <EOL> if mydsa . dsa_is_ro : <EOL> mydsa . dsa_is_istg = True <EOL> return True <EOL> for c_rep in mydsa . current_rep_table . values ( ) : <EOL> if c_rep . is_config ( ) : <EOL> break <EOL> if c_rep is None : <EOL> raise Exception ( "<STR_LIT>" % <EOL> mydsa . dsa_dnstr ) <EOL> c_rep . load_repsFrom ( samdb ) <EOL> D_sort = [ ] <EOL> d_dsa = None <EOL> unixnow = int ( time . time ( ) ) <EOL> ntnow = unix2nttime ( unixnow ) <EOL> for dsa in self . dsa_table . values ( ) : <EOL> D_sort . append ( dsa ) <EOL> D_sort . sort ( sort_dsa_by_guid ) <EOL> if self . site_topo_failover == <NUM_LIT:0> : <EOL> f = <NUM_LIT:2> * <NUM_LIT> * <NUM_LIT> * <NUM_LIT> <EOL> else : <EOL> f = self . site_topo_failover * <NUM_LIT> * <NUM_LIT> <EOL> if self . site_topo_generator is not None and self . site_topo_generator in self . dsa_table . keys ( ) : <EOL> d_dsa = self . dsa_table [ self . site_topo_generator ] <EOL> j_idx = D_sort . index ( d_dsa ) <EOL> if d_dsa is not None and d_dsa is not mydsa : <EOL> if d_dsa . dsa_ivid != c_rep . source_dsa_invocation_id : <EOL> i_idx = j_idx <EOL> t_time = <NUM_LIT:0> <EOL> elif ntnow < ( c_rep . last_success - f ) : <EOL> i_idx = <NUM_LIT:0> <EOL> t_time = <NUM_LIT:0> <EOL> else : <EOL> i_idx = j_idx <EOL> t_time = c_rep . last_success <EOL> else : <EOL> i_idx = D_sort . index ( mydsa ) <EOL> t_time = ntnow <EOL> k_idx = ( i_idx + ( ( ntnow - t_time ) / f ) ) % len ( D_sort ) <EOL> d_dsa = D_sort [ k_idx ] <EOL> d_dsa . dsa_is_istg = True <EOL> if d_dsa is not mydsa : <EOL> return False <EOL> if self . site_topo_generator == mydsa . dsa_dnstr : <EOL> return True <EOL> self . site_topo_generator = mydsa . dsa_dnstr <EOL> if ro : <EOL> return True <EOL> ssdn = "<STR_LIT>" % self . site_dnstr <EOL> m = ldb . Message ( ) <EOL> m . dn = ldb . Dn ( samdb , ssdn ) <EOL> m [ "<STR_LIT>" ] = ldb . MessageElement ( mydsa . dsa_dnstr , ldb . FLAG_MOD_REPLACE , <EOL> "<STR_LIT>" ) <EOL> try : <EOL> samdb . modify ( m ) <EOL> except ldb . LdbError , estr : <EOL> raise Exception ( <EOL> "<STR_LIT>" % <EOL> ( ssdn , estr ) ) <EOL> return True <EOL> def is_intrasite_topology_disabled ( self ) : <EOL> '''<STR_LIT>''' <EOL> if ( self . site_options & <EOL> dsdb . DS_NTDSSETTINGS_OPT_IS_AUTO_TOPOLOGY_DISABLED ) != <NUM_LIT:0> : <EOL> return True <EOL> return False <EOL> def is_intersite_topology_disabled ( self ) : <EOL> '''<STR_LIT>''' <EOL> if ( self . site_options & <EOL> dsdb . DS_NTDSSETTINGS_OPT_IS_INTER_SITE_AUTO_TOPOLOGY_DISABLED ) != <NUM_LIT:0> : <EOL> return True <EOL> return False <EOL> def is_random_bridgehead_disabled ( self ) : <EOL> '''<STR_LIT>''' <EOL> if ( self . site_options & <EOL> dsdb . DS_NTDSSETTINGS_OPT_IS_RAND_BH_SELECTION_DISABLED ) != <NUM_LIT:0> : <EOL> return True <EOL> return False <EOL> def is_detect_stale_disabled ( self ) : <EOL> '''<STR_LIT>''' <EOL> if ( self . site_options & <EOL> dsdb . DS_NTDSSETTINGS_OPT_IS_TOPL_DETECT_STALE_DISABLED ) != <NUM_LIT:0> : <EOL> return True <EOL> return False <EOL> def is_cleanup_ntdsconn_disabled ( self ) : <EOL> '''<STR_LIT>''' <EOL> if ( self . site_options & <EOL> dsdb . DS_NTDSSETTINGS_OPT_IS_TOPL_CLEANUP_DISABLED ) != <NUM_LIT:0> : <EOL> return True <EOL> return False <EOL> def same_site ( self , dsa ) : <EOL> '''<STR_LIT>''' <EOL> if self . get_dsa ( dsa . dsa_dnstr ) : <EOL> return True <EOL> return False <EOL> def __str__ ( self ) : <EOL> '''<STR_LIT>''' <EOL> text = "<STR_LIT>" % self . __class__ . __name__ <EOL> text = text + "<STR_LIT>" % self . site_dnstr <EOL> text = text + "<STR_LIT>" % self . site_options <EOL> text = text + "<STR_LIT>" % self . site_topo_generator <EOL> text = text + "<STR_LIT>" % self . site_topo_failover <EOL> for key , dsa in self . dsa_table . items ( ) : <EOL> text = text + "<STR_LIT>" % dsa <EOL> return text <EOL> class GraphNode ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , dsa_dnstr , max_node_edges ) : <EOL> """<STR_LIT>""" <EOL> self . max_edges = max_node_edges <EOL> self . dsa_dnstr = dsa_dnstr <EOL> self . edge_from = [ ] <EOL> def __str__ ( self ) : <EOL> text = "<STR_LIT>" % self . __class__ . __name__ <EOL> text = text + "<STR_LIT>" % self . dsa_dnstr <EOL> text = text + "<STR_LIT>" % self . max_edges <EOL> for i , edge in enumerate ( self . edge_from ) : <EOL> text = text + "<STR_LIT>" % ( i , edge ) <EOL> return text <EOL> def add_edge_from ( self , from_dsa_dnstr ) : <EOL> """<STR_LIT>""" <EOL> assert from_dsa_dnstr is not None <EOL> if from_dsa_dnstr == self . dsa_dnstr : <EOL> return False <EOL> if from_dsa_dnstr in self . edge_from : <EOL> return False <EOL> if len ( self . edge_from ) >= self . max_edges : <EOL> return False <EOL> self . edge_from . append ( from_dsa_dnstr ) <EOL> return True <EOL> def add_edges_from_connections ( self , dsa ) : <EOL> """<STR_LIT>""" <EOL> for dnstr , connect in dsa . connect_table . items ( ) : <EOL> self . add_edge_from ( connect . from_dnstr ) <EOL> def add_connections_from_edges ( self , dsa ) : <EOL> """<STR_LIT>""" <EOL> for edge_dnstr in self . edge_from : <EOL> connect = dsa . get_connection_by_from_dnstr ( edge_dnstr ) <EOL> if connect and not connect . is_rodc_topology ( ) : <EOL> exists = True <EOL> else : <EOL> exists = False <EOL> if exists : <EOL> return <EOL> opt = dsdb . NTDSCONN_OPT_IS_GENERATED <EOL> flags = dsdb . SYSTEM_FLAG_CONFIG_ALLOW_RENAME + dsdb . SYSTEM_FLAG_CONFIG_ALLOW_MOVE <EOL> dsa . create_connection ( opt , flags , None , edge_dnstr , None ) <EOL> def has_sufficient_edges ( self ) : <EOL> '''<STR_LIT>''' <EOL> if len ( self . edge_from ) >= self . max_edges : <EOL> return True <EOL> return False <EOL> class Transport ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , dnstr ) : <EOL> self . dnstr = dnstr <EOL> self . options = <NUM_LIT:0> <EOL> self . guid = None <EOL> self . name = None <EOL> self . address_attr = None <EOL> self . bridgehead_list = [ ] <EOL> def __str__ ( self ) : <EOL> '''<STR_LIT>''' <EOL> text = "<STR_LIT>" % ( self . __class__ . __name__ , self . dnstr ) <EOL> text = text + "<STR_LIT>" % str ( self . guid ) <EOL> text = text + "<STR_LIT>" % self . options <EOL> text = text + "<STR_LIT>" % self . address_attr <EOL> text = text + "<STR_LIT>" % self . name <EOL> for dnstr in self . bridgehead_list : <EOL> text = text + "<STR_LIT>" % dnstr <EOL> return text <EOL> def load_transport ( self , samdb ) : <EOL> """<STR_LIT>""" <EOL> attrs = [ "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT:name>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" ] <EOL> try : <EOL> res = samdb . search ( base = self . dnstr , scope = ldb . SCOPE_BASE , <EOL> attrs = attrs ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . dnstr , estr ) ) <EOL> msg = res [ <NUM_LIT:0> ] <EOL> self . guid = misc . GUID ( samdb . schema_format_value ( "<STR_LIT>" , <EOL> msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) ) <EOL> if "<STR_LIT>" in msg : <EOL> self . options = int ( msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT>" in msg : <EOL> self . address_attr = str ( msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT:name>" in msg : <EOL> self . name = str ( msg [ "<STR_LIT:name>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT>" in msg : <EOL> for value in msg [ "<STR_LIT>" ] : <EOL> dsdn = dsdb_Dn ( samdb , value ) <EOL> dnstr = str ( dsdn . dn ) <EOL> if dnstr not in self . bridgehead_list : <EOL> self . bridgehead_list . append ( dnstr ) <EOL> class RepsFromTo ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , nc_dnstr = None , ndr_blob = None ) : <EOL> self . __dict__ [ '<STR_LIT>' ] = False <EOL> self . __dict__ [ '<STR_LIT>' ] = nc_dnstr <EOL> self . __dict__ [ '<STR_LIT>' ] = <NUM_LIT> <EOL> if ndr_blob is None : <EOL> self . __dict__ [ '<STR_LIT>' ] = drsblobs . repsFromToBlob ( ) <EOL> self . __dict__ [ '<STR_LIT>' ] . version = <NUM_LIT> <EOL> self . __dict__ [ '<STR_LIT>' ] = None <EOL> self . __dict__ [ '<STR_LIT>' ] = None <EOL> self . __dict__ [ '<STR_LIT>' ] . ctr . other_info = self . __dict__ [ '<STR_LIT>' ] = drsblobs . repsFromTo1OtherInfo ( ) <EOL> else : <EOL> self . __dict__ [ '<STR_LIT>' ] = ndr_blob <EOL> self . __dict__ [ '<STR_LIT>' ] = ndr_blob . ctr . other_info <EOL> if ndr_blob . version == <NUM_LIT> : <EOL> self . __dict__ [ '<STR_LIT>' ] = ndr_blob . ctr . other_info . dns_name <EOL> self . __dict__ [ '<STR_LIT>' ] = None <EOL> else : <EOL> self . __dict__ [ '<STR_LIT>' ] = ndr_blob . ctr . other_info . dns_name1 <EOL> self . __dict__ [ '<STR_LIT>' ] = ndr_blob . ctr . other_info . dns_name2 <EOL> def __str__ ( self ) : <EOL> '''<STR_LIT>''' <EOL> text = "<STR_LIT>" % self . __class__ . __name__ <EOL> text = text + "<STR_LIT>" % self . nc_dnstr <EOL> text = text + "<STR_LIT>" % self . update_flags <EOL> text = text + "<STR_LIT>" % self . version <EOL> text = text + "<STR_LIT>" % str ( self . source_dsa_obj_guid ) <EOL> text = text + "<STR_LIT>" % str ( self . source_dsa_invocation_id ) <EOL> text = text + "<STR_LIT>" % str ( self . transport_guid ) <EOL> text = text + "<STR_LIT>" % self . replica_flags <EOL> text = text + "<STR_LIT>" % self . consecutive_sync_failures <EOL> text = text + "<STR_LIT>" % self . last_success <EOL> text = text + "<STR_LIT>" % self . last_attempt <EOL> text = text + "<STR_LIT>" % str ( self . dns_name1 ) <EOL> text = text + "<STR_LIT>" % str ( self . dns_name2 ) <EOL> text = text + "<STR_LIT>" <EOL> for slot in self . schedule : <EOL> text = text + "<STR_LIT>" % slot <EOL> text = text + "<STR_LIT:]>" <EOL> return text <EOL> def __setattr__ ( self , item , value ) : <EOL> if item in [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' ] : <EOL> if item in [ '<STR_LIT>' ] : <EOL> self . __dict__ [ '<STR_LIT>' ] |= drsuapi . DRSUAPI_DRS_UPDATE_FLAGS <EOL> elif item in [ '<STR_LIT>' ] : <EOL> self . __dict__ [ '<STR_LIT>' ] |= drsuapi . DRSUAPI_DRS_UPDATE_SCHEDULE <EOL> setattr ( self . __dict__ [ '<STR_LIT>' ] . ctr , item , value ) <EOL> elif item in [ '<STR_LIT>' ] : <EOL> self . __dict__ [ '<STR_LIT>' ] = value <EOL> if self . __dict__ [ '<STR_LIT>' ] . version == <NUM_LIT> : <EOL> self . __dict__ [ '<STR_LIT>' ] . ctr . other_info . dns_name = self . __dict__ [ '<STR_LIT>' ] <EOL> else : <EOL> self . __dict__ [ '<STR_LIT>' ] . ctr . other_info . dns_name1 = self . __dict__ [ '<STR_LIT>' ] <EOL> elif item in [ '<STR_LIT>' ] : <EOL> self . __dict__ [ '<STR_LIT>' ] = value <EOL> if self . __dict__ [ '<STR_LIT>' ] . version == <NUM_LIT> : <EOL> raise AttributeError ( item ) <EOL> else : <EOL> self . __dict__ [ '<STR_LIT>' ] . ctr . other_info . dns_name2 = self . __dict__ [ '<STR_LIT>' ] <EOL> elif item in [ '<STR_LIT>' ] : <EOL> self . __dict__ [ '<STR_LIT>' ] = value <EOL> elif item in [ '<STR_LIT>' ] : <EOL> self . __dict__ [ '<STR_LIT>' ] = value <EOL> elif item in [ '<STR_LIT:version>' ] : <EOL> raise AttributeError , "<STR_LIT>" % item <EOL> else : <EOL> raise AttributeError , "<STR_LIT>" % item <EOL> self . __dict__ [ '<STR_LIT>' ] |= drsuapi . DRSUAPI_DRS_UPDATE_ADDRESS <EOL> def __getattr__ ( self , item ) : <EOL> """<STR_LIT>""" <EOL> if item in [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' ] : <EOL> return getattr ( self . __dict__ [ '<STR_LIT>' ] . ctr , item ) <EOL> elif item in [ '<STR_LIT:version>' ] : <EOL> return self . __dict__ [ '<STR_LIT>' ] . version <EOL> elif item in [ '<STR_LIT>' ] : <EOL> if self . __dict__ [ '<STR_LIT>' ] . version == <NUM_LIT> : <EOL> return self . __dict__ [ '<STR_LIT>' ] . ctr . other_info . dns_name <EOL> else : <EOL> return self . __dict__ [ '<STR_LIT>' ] . ctr . other_info . dns_name1 <EOL> elif item in [ '<STR_LIT>' ] : <EOL> if self . __dict__ [ '<STR_LIT>' ] . version == <NUM_LIT> : <EOL> raise AttributeError ( item ) <EOL> else : <EOL> return self . __dict__ [ '<STR_LIT>' ] . ctr . other_info . dns_name2 <EOL> elif item in [ '<STR_LIT>' ] : <EOL> return self . __dict__ [ '<STR_LIT>' ] <EOL> elif item in [ '<STR_LIT>' ] : <EOL> return self . __dict__ [ '<STR_LIT>' ] <EOL> elif item in [ '<STR_LIT>' ] : <EOL> return self . __dict__ [ '<STR_LIT>' ] <EOL> raise AttributeError , "<STR_LIT>" % item <EOL> def is_modified ( self ) : <EOL> return ( self . update_flags != <NUM_LIT> ) <EOL> def set_unmodified ( self ) : <EOL> self . __dict__ [ '<STR_LIT>' ] = <NUM_LIT> <EOL> class SiteLink ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , dnstr ) : <EOL> self . dnstr = dnstr <EOL> self . options = <NUM_LIT:0> <EOL> self . system_flags = <NUM_LIT:0> <EOL> self . cost = <NUM_LIT:0> <EOL> self . schedule = None <EOL> self . interval = None <EOL> self . site_list = [ ] <EOL> def __str__ ( self ) : <EOL> '''<STR_LIT>''' <EOL> text = "<STR_LIT>" % ( self . __class__ . __name__ , self . dnstr ) <EOL> text = text + "<STR_LIT>" % self . options <EOL> text = text + "<STR_LIT>" % self . system_flags <EOL> text = text + "<STR_LIT>" % self . cost <EOL> text = text + "<STR_LIT>" % self . interval <EOL> if self . schedule is not None : <EOL> text = text + "<STR_LIT>" % self . schedule . size <EOL> text = text + "<STR_LIT>" % self . schedule . bandwidth <EOL> text = text + "<STR_LIT>" % self . schedule . numberOfSchedules <EOL> for i , header in enumerate ( self . schedule . headerArray ) : <EOL> text = text + "<STR_LIT>" % ( i , header . type ) <EOL> text = text + "<STR_LIT>" % ( i , header . offset ) <EOL> text = text + "<STR_LIT>" % i <EOL> for slot in self . schedule . dataArray [ i ] . slots : <EOL> text = text + "<STR_LIT>" % slot <EOL> text = text + "<STR_LIT:]>" <EOL> for dnstr in self . site_list : <EOL> text = text + "<STR_LIT>" % dnstr <EOL> return text <EOL> def load_sitelink ( self , samdb ) : <EOL> """<STR_LIT>""" <EOL> attrs = [ "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" ] <EOL> try : <EOL> res = samdb . search ( base = self . dnstr , scope = ldb . SCOPE_BASE , <EOL> attrs = attrs ) <EOL> except ldb . LdbError , ( enum , estr ) : <EOL> raise Exception ( "<STR_LIT>" % <EOL> ( self . dnstr , estr ) ) <EOL> msg = res [ <NUM_LIT:0> ] <EOL> if "<STR_LIT>" in msg : <EOL> self . options = int ( msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT>" in msg : <EOL> self . system_flags = int ( msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT>" in msg : <EOL> self . cost = int ( msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT>" in msg : <EOL> self . interval = int ( msg [ "<STR_LIT>" ] [ <NUM_LIT:0> ] ) <EOL> if "<STR_LIT>" in msg : <EOL> for value in msg [ "<STR_LIT>" ] : <EOL> dsdn = dsdb_Dn ( samdb , value ) <EOL> dnstr = str ( dsdn . dn ) <EOL> if dnstr not in self . site_list : <EOL> self . site_list . append ( dnstr ) <EOL> def is_sitelink ( self , site1_dnstr , site2_dnstr ) : <EOL> """<STR_LIT>""" <EOL> if site1_dnstr in self . site_list and site2_dnstr in self . site_list : <EOL> return True <EOL> return False <EOL> class VertexColor ( object ) : <EOL> ( unknown , white , black , red ) = range ( <NUM_LIT:0> , <NUM_LIT:4> ) <EOL> class Vertex ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , site , part ) : <EOL> self . site = site <EOL> self . part = part <EOL> self . color = VertexColor . unknown <EOL> def color_vertex ( self ) : <EOL> """<STR_LIT>""" <EOL> self . color = VertexColor . white <EOL> for dnstr , dsa in self . site . dsa_table . items ( ) : <EOL> rep = dsa . get_current_replica ( self . part . nc_dnstr ) <EOL> if rep is None : <EOL> continue <EOL> if not rep . is_partial ( ) : <EOL> self . color = VertexColor . red <EOL> break <EOL> else : <EOL> self . color = VertexColor . black <EOL> def is_red ( self ) : <EOL> assert ( self . color != VertexColor . unknown ) <EOL> return ( self . color == VertexColor . red ) <EOL> def is_black ( self ) : <EOL> assert ( self . color != VertexColor . unknown ) <EOL> return ( self . color == VertexColor . black ) <EOL> def is_white ( self ) : <EOL> assert ( self . color != VertexColor . unknown ) <EOL> return ( self . color == VertexColor . white ) <EOL> def sort_dsa_by_guid ( dsa1 , dsa2 ) : <EOL> return cmp ( dsa1 . dsa_guid , dsa2 . dsa_guid ) </s>
