mirror of
https://github.com/samba-team/samba.git
synced 2025-07-22 16:59:09 +03:00
A simple python tool to dump smbXsrv TDB databases. Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Günther Deschner <gd@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
88 lines
2.5 KiB
Python
Executable File
88 lines
2.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
|
|
sys.path.insert(0, "bin/python")
|
|
|
|
import os
|
|
import argparse
|
|
import struct
|
|
|
|
from samba.ndr import ndr_unpack, ndr_print
|
|
from samba.dcerpc import smbXsrv
|
|
from samba.dcerpc import server_id
|
|
import tdb
|
|
|
|
def print_watchers(num_watched, blob):
|
|
for i in range(0,num_watched):
|
|
id = ndr_unpack(server_id.server_id, blob[:24])
|
|
print(ndr_print(id))
|
|
blob = blob[24:]
|
|
|
|
def print_record(data, ndr_type, watched, ctdb):
|
|
blob = data
|
|
|
|
if ctdb:
|
|
(rsn, dmaster, reserved1, flags) = struct.unpack('QIII', bytes(blob[:20]))
|
|
blob = blob[24:]
|
|
print(" ctdb record header: rsn=%lu, dmaster=%u, reserved1=0x%x, flags=0x%x len=%u" %
|
|
(rsn, dmaster, reserved1, flags, len(blob)))
|
|
if len(blob) == 0:
|
|
return
|
|
|
|
if watched:
|
|
(num_watched, ) = struct.unpack('I', bytes(blob[:4]))
|
|
blob = blob[4:]
|
|
|
|
deleted_bit = 1<<31
|
|
deleted = num_watched & deleted_bit
|
|
|
|
num_watched = num_watched & ~deleted_bit
|
|
if num_watched > 0:
|
|
if deleted:
|
|
deleted_str = "yes"
|
|
else:
|
|
deleted_str = "no"
|
|
print(" num_watched: %d, deleted: %s" % (num_watched, deleted_str))
|
|
print_watchers(num_watched, blob)
|
|
blob = blob[num_watched*4:]
|
|
|
|
unpacked = ndr_unpack(ndr_type, blob, allow_remaining=True)
|
|
print(ndr_print(unpacked))
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('path', help='Path to the TDB file')
|
|
parser.add_argument('-c', '--ctdb',
|
|
default=False,
|
|
action="store_true",
|
|
help='The TDB database is from a ctdb cluster')
|
|
args = parser.parse_args()
|
|
|
|
watched = False
|
|
if 'smbXsrv_session' in args.path:
|
|
ndr_type = smbXsrv.session_globalB
|
|
watched = True
|
|
elif 'smbXsrv_open' in args.path:
|
|
ndr_type = smbXsrv.open_globalB
|
|
elif 'smbXsrv_client' in args.path:
|
|
ndr_type = smbXsrv.client_globalB
|
|
watched = True
|
|
elif 'smbXsrv_tcon' in args.path:
|
|
ndr_type = smbXsrv.tcon_globalB
|
|
elif 'smbXsrv_version' in args.path:
|
|
ndr_type = smbXsrv.version_globalB
|
|
else:
|
|
raise Exception("Failed to guess NDR type")
|
|
|
|
tdb = tdb.Tdb(args.path, 0, tdb.INCOMPATIBLE_HASH, os.O_RDONLY)
|
|
|
|
i = 1
|
|
for k in tdb.keys():
|
|
data = tdb.get(k)
|
|
print("Record: %d" % i)
|
|
print_record(data, ndr_type, watched, args.ctdb)
|
|
i = i + 1
|
|
|
|
tdb.close()
|