#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
+from __future__ import print_function
+import sys
import ldb
import uuid
drsblobs,
drsuapi,
misc,
- )
+)
from samba.common import dsdb_Dn
from samba.ndr import ndr_unpack, ndr_pack
from collections import Counter
class NCType(object):
(unknown, schema, domain, config, application) = range(0, 5)
+
# map the NCType enum to strings for debugging
nctype_lut = dict((v, k) for k, v in NCType.__dict__.items() if k[:2] != '__')
# Possibly no repsFrom if this is a singleton DC
if "repsFrom" in msg:
for value in msg["repsFrom"]:
- rep = RepsFromTo(self.nc_dnstr,
- ndr_unpack(drsblobs.repsFromToBlob, value))
+ try:
+ unpacked = ndr_unpack(drsblobs.repsFromToBlob, value)
+ except RuntimeError as e:
+ print("bad repsFrom NDR: %r" % (value),
+ file=sys.stderr)
+ continue
+ rep = RepsFromTo(self.nc_dnstr, unpacked)
self.rep_repsFrom.append(rep)
def commit_repsFrom(self, samdb, ro=False):
# Possibly no repsTo if this is a singleton DC
if "repsTo" in msg:
for value in msg["repsTo"]:
- rep = RepsFromTo(self.nc_dnstr,
- ndr_unpack(drsblobs.repsFromToBlob, value))
+ try:
+ unpacked = ndr_unpack(drsblobs.repsFromToBlob, value)
+ except RuntimeError as e:
+ print("bad repsTo NDR: %r" % (value),
+ file=sys.stderr)
+ continue
+ rep = RepsFromTo(self.nc_dnstr, unpacked)
self.rep_repsTo.append(rep)
def commit_repsTo(self, samdb, ro=False):
if "options" in msg:
self.options = int(msg["options"][0])
- if "msDS-isRODC" in msg and msg["msDS-isRODC"][0] == "TRUE":
+ if "msDS-isRODC" in msg and str(msg["msDS-isRODC"][0]) == "TRUE":
self.dsa_is_ro = True
else:
self.dsa_is_ro = False
for value in res[0][k]:
# Turn dn into a dsdb_Dn so we can use
# its methods to parse a binary DN
- dsdn = dsdb_Dn(samdb, value)
+ dsdn = dsdb_Dn(samdb, value.decode('utf8'))
flags = dsdn.get_binary_integer()
dnstr = str(dsdn.dn)
- if not dnstr in tmp_table:
+ if dnstr not in tmp_table:
rep = NCReplica(self, dnstr)
tmp_table[dnstr] = rep
else:
self.options = int(msg["options"][0])
if "enabledConnection" in msg:
- if msg["enabledConnection"][0].upper().lstrip().rstrip() == "TRUE":
+ if str(msg["enabledConnection"][0]).upper().lstrip().rstrip() == "TRUE":
self.enabled = True
if "systemFlags" in msg:
"for (%s)" % (self.dnstr))
if "transportType" in msg:
- dsdn = dsdb_Dn(samdb, msg["transportType"][0])
+ dsdn = dsdb_Dn(samdb, msg["transportType"][0].decode('utf8'))
self.load_connection_transport(samdb, str(dsdn.dn))
if "schedule" in msg:
self.schedule = ndr_unpack(drsblobs.schedule, msg["schedule"][0])
if "whenCreated" in msg:
- self.whenCreated = ldb.string_to_time(msg["whenCreated"][0])
+ self.whenCreated = ldb.string_to_time(str(msg["whenCreated"][0]))
if "fromServer" in msg:
- dsdn = dsdb_Dn(samdb, msg["fromServer"][0])
+ dsdn = dsdb_Dn(samdb, msg["fromServer"][0].decode('utf8'))
self.from_dnstr = str(dsdn.dn)
assert self.from_dnstr is not None
continue
if k == "Enabled":
- if msg[k][0].upper().lstrip().rstrip() == "TRUE":
+ if str(msg[k][0]).upper().lstrip().rstrip() == "TRUE":
self.enabled = True
else:
self.enabled = False
continue
for value in msg[k]:
- dsdn = dsdb_Dn(samdb, value)
+ dsdn = dsdb_Dn(samdb, value.decode('utf8'))
dnstr = str(dsdn.dn)
if k == "nCName":
# Which is a fancy way of saying "sort all the nTDSDSA objects
# in the site by guid in ascending order". Place sorted list
# in D_sort[]
- D_sort = sorted(self.rw_dsa_table.values(), cmp=sort_dsa_by_guid)
+ D_sort = sorted(
+ self.rw_dsa_table.values(),
+ key=lambda dsa: ndr_pack(dsa.dsa_guid))
# double word number of 100 nanosecond intervals since 1600s
i_idx = j_idx
t_time = 0
- #XXX doc says current time < c.timeLastSyncSuccess - f
+ # XXX doc says current time < c.timeLastSyncSuccess - f
# which is true only if f is negative or clocks are wrong.
# f is not negative in the default case (2 hours).
elif self.nt_now - cursor.last_sync_success > f:
if "bridgeheadServerListBL" in msg:
for value in msg["bridgeheadServerListBL"]:
- dsdn = dsdb_Dn(samdb, value)
+ dsdn = dsdb_Dn(samdb, value.decode('utf8'))
dnstr = str(dsdn.dn)
if dnstr not in self.bridgehead_list:
self.bridgehead_list.append(dnstr)
text = text + "0x%X " % slot
text = text + "]"
- for dnstr in self.site_list:
- text = text + "\n\tsite_list=%s" % dnstr
+ for guid, dn in self.site_list:
+ text = text + "\n\tsite_list=%s (%s)" % (guid, dn)
return text
def load_sitelink(self, samdb):
if "siteList" in msg:
for value in msg["siteList"]:
- dsdn = dsdb_Dn(samdb, value)
+ dsdn = dsdb_Dn(samdb, value.decode('utf8'))
guid = misc.GUID(dsdn.dn.get_extended_component('GUID'))
- if guid not in self.site_list:
- self.site_list.append(guid)
+ dnstr = str(dsdn.dn)
+ if (guid, dnstr) not in self.site_list:
+ self.site_list.append((guid, dnstr))
if "schedule" in msg:
self.schedule = ndr_unpack(drsblobs.schedule, value)
dsa.dsa_dnstr)
-def sort_dsa_by_guid(dsa1, dsa2):
- "use ndr_pack for GUID comparison, as appears correct in some places"""
- return cmp(ndr_pack(dsa1.dsa_guid), ndr_pack(dsa2.dsa_guid))
-
-
def new_connection_schedule():
"""Create a default schedule for an NTDSConnection or Sitelink. This
is packed differently from the repltimes schedule used elsewhere