mirror of
https://github.com/samba-team/samba.git
synced 2025-08-04 08:22:08 +03:00
r26607: Fix reading of values and subkeys in Samba 3 registry files.
(This used to be commit e3d7454ef7
)
This commit is contained in:
committed by
Stefan Metzmacher
parent
e0132b5602
commit
c4d3666ac2
@ -80,7 +80,7 @@ def print_samba3_secrets(secrets):
|
|||||||
for domain in secrets.domains():
|
for domain in secrets.domains():
|
||||||
print "\t--- %s ---" % domain
|
print "\t--- %s ---" % domain
|
||||||
print "\tSID: %s" % secrets.get_sid(domain)
|
print "\tSID: %s" % secrets.get_sid(domain)
|
||||||
print "\tGUID: %s" % secrets.get_dom_guid(domain)
|
print "\tGUID: %s" % secrets.get_domain_guid(domain)
|
||||||
print "\tPlaintext pwd: %s" % secrets.get_machine_password(domain)
|
print "\tPlaintext pwd: %s" % secrets.get_machine_password(domain)
|
||||||
if secrets.get_machine_last_change_time(domain):
|
if secrets.get_machine_last_change_time(domain):
|
||||||
print "\tLast Changed: %lu" % secrets.get_machine_last_change_time(domain)
|
print "\tLast Changed: %lu" % secrets.get_machine_last_change_time(domain)
|
||||||
@ -93,11 +93,12 @@ def print_samba3_secrets(secrets):
|
|||||||
|
|
||||||
def print_samba3_regdb(regdb):
|
def print_samba3_regdb(regdb):
|
||||||
print_header("Registry")
|
print_header("Registry")
|
||||||
|
from registry import str_regtype
|
||||||
|
|
||||||
for k in regdb.keys():
|
for k in regdb.keys():
|
||||||
print "%s" % k
|
print "[%s]" % k
|
||||||
for v in regdb.values(k):
|
for (value_name, (type, value)) in regdb.values(k).items():
|
||||||
print "\t%s: type %d, length %d" % (v.name, v.type, v.data.length)
|
print "\"%s\"=%s:%s" % (value_name, str_regtype(type), value)
|
||||||
|
|
||||||
def print_samba3_winsdb(winsdb):
|
def print_samba3_winsdb(winsdb):
|
||||||
print_header("WINS Database")
|
print_header("WINS Database")
|
||||||
@ -151,7 +152,7 @@ def print_samba3_summary(samba3):
|
|||||||
|
|
||||||
libdir = args[0]
|
libdir = args[0]
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
smbconf = args[2]
|
smbconf = args[1]
|
||||||
else:
|
else:
|
||||||
smbconf = os.path.join(libdir, "smb.conf")
|
smbconf = os.path.join(libdir, "smb.conf")
|
||||||
|
|
||||||
|
@ -45,16 +45,36 @@ class Registry:
|
|||||||
data = self.tdb.get("%s\x00" % key)
|
data = self.tdb.get("%s\x00" % key)
|
||||||
if data is None:
|
if data is None:
|
||||||
return []
|
return []
|
||||||
# FIXME: Parse data
|
import struct
|
||||||
return []
|
(num, ) = struct.unpack("<L", data[0:4])
|
||||||
|
keys = data[4:].split("\0")
|
||||||
|
assert keys[-1] == ""
|
||||||
|
keys.pop()
|
||||||
|
assert len(keys) == num
|
||||||
|
return keys
|
||||||
|
|
||||||
def values(self, key):
|
def values(self, key):
|
||||||
"""Return a dictionary with the values set for a specific key."""
|
"""Return a dictionary with the values set for a specific key."""
|
||||||
data = self.tdb.get("%s/%s\x00" % (REGISTRY_VALUE_PREFIX, key))
|
data = self.tdb.get("%s/%s\x00" % (REGISTRY_VALUE_PREFIX, key))
|
||||||
if data is None:
|
if data is None:
|
||||||
return {}
|
return {}
|
||||||
# FIXME: Parse data
|
ret = {}
|
||||||
return {}
|
import struct
|
||||||
|
(num, ) = struct.unpack("<L", data[0:4])
|
||||||
|
data = data[4:]
|
||||||
|
for i in range(num):
|
||||||
|
# Value name
|
||||||
|
(name, data) = data.split("\0", 1)
|
||||||
|
|
||||||
|
(type, ) = struct.unpack("<L", data[0:4])
|
||||||
|
data = data[4:]
|
||||||
|
(value_len, ) = struct.unpack("<L", data[0:4])
|
||||||
|
data = data[4:]
|
||||||
|
|
||||||
|
ret[name] = (type, data[:value_len])
|
||||||
|
data = data[value_len:]
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class PolicyDatabase:
|
class PolicyDatabase:
|
||||||
|
@ -38,6 +38,14 @@ class RegistryTestCase(unittest.TestCase):
|
|||||||
def test_keys(self):
|
def test_keys(self):
|
||||||
self.assertTrue("HKLM" in self.registry.keys())
|
self.assertTrue("HKLM" in self.registry.keys())
|
||||||
|
|
||||||
|
def test_subkeys(self):
|
||||||
|
self.assertEquals(["SOFTWARE", "SYSTEM"], self.registry.subkeys("HKLM"))
|
||||||
|
|
||||||
|
def test_values(self):
|
||||||
|
self.assertEquals({'DisplayName': (1L, 'E\x00v\x00e\x00n\x00t\x00 \x00L\x00o\x00g\x00\x00\x00'),
|
||||||
|
'ErrorControl': (4L, '\x01\x00\x00\x00')},
|
||||||
|
self.registry.values("HKLM/SYSTEM/CURRENTCONTROLSET/SERVICES/EVENTLOG"))
|
||||||
|
|
||||||
|
|
||||||
class PolicyTestCase(unittest.TestCase):
|
class PolicyTestCase(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -11,21 +11,7 @@ from provision import findnss, provision
|
|||||||
import grp
|
import grp
|
||||||
import pwd
|
import pwd
|
||||||
import uuid
|
import uuid
|
||||||
|
import registry
|
||||||
def regkey_to_dn(name):
|
|
||||||
"""Convert a registry key to a DN.
|
|
||||||
|
|
||||||
:name: The registry key name.
|
|
||||||
:return: A matching DN."""
|
|
||||||
dn = "hive=NONE"
|
|
||||||
|
|
||||||
if name == "":
|
|
||||||
return dn
|
|
||||||
|
|
||||||
for el in name.split("/"):
|
|
||||||
dn = "key=%s," % el + dn
|
|
||||||
|
|
||||||
return dn
|
|
||||||
|
|
||||||
# Where prefix is any of:
|
# Where prefix is any of:
|
||||||
# - HKLM
|
# - HKLM
|
||||||
@ -35,39 +21,6 @@ def regkey_to_dn(name):
|
|||||||
# HKPT
|
# HKPT
|
||||||
#
|
#
|
||||||
|
|
||||||
def upgrade_registry(regdb,prefix,ldb):
|
|
||||||
"""Migrate registry contents."""
|
|
||||||
assert regdb is not None
|
|
||||||
prefix_up = prefix.upper()
|
|
||||||
ldif = []
|
|
||||||
|
|
||||||
for rk in regdb.keys:
|
|
||||||
pts = rk.name.split("/")
|
|
||||||
|
|
||||||
# Only handle selected hive
|
|
||||||
if pts[0].upper() != prefix_up:
|
|
||||||
continue
|
|
||||||
|
|
||||||
keydn = regkey_to_dn(rk.name)
|
|
||||||
|
|
||||||
pts = rk.name.split("/")
|
|
||||||
|
|
||||||
# Convert key name to dn
|
|
||||||
ldif[rk.name] = """
|
|
||||||
dn: %s
|
|
||||||
name: %s
|
|
||||||
|
|
||||||
""" % (keydn, pts[0])
|
|
||||||
|
|
||||||
for rv in rk.values:
|
|
||||||
ldif[rk.name + " (" + rv.name + ")"] = """
|
|
||||||
dn: %s,value=%s
|
|
||||||
value: %s
|
|
||||||
type: %d
|
|
||||||
data:: %s""" % (keydn, rv.name, rv.name, rv.type, ldb.encode(rv.data))
|
|
||||||
|
|
||||||
return ldif
|
|
||||||
|
|
||||||
def upgrade_sam_policy(policy,dn):
|
def upgrade_sam_policy(policy,dn):
|
||||||
ldif = """
|
ldif = """
|
||||||
dn: %s
|
dn: %s
|
||||||
@ -177,82 +130,72 @@ group.comment, group.nt_name, group.sid, group.unixname, group.sid_name_use)
|
|||||||
|
|
||||||
return ldif
|
return ldif
|
||||||
|
|
||||||
def upgrade_winbind(samba3,domaindn):
|
def import_idmap(samba4_idmap,samba3_idmap,domaindn):
|
||||||
ldif = """
|
samba4_idmap.add({
|
||||||
|
"dn": domaindn,
|
||||||
dn: dc=none
|
"userHwm": str(samba3_idmap.get_user_hwm()),
|
||||||
userHwm: %d
|
"groupHwm": str(samba3_idmap.get_group_hwm())})
|
||||||
groupHwm: %d
|
|
||||||
|
|
||||||
""" % (samba3.idmap.user_hwm, samba3.idmap.group_hwm)
|
for uid in samba3_idmap.uids():
|
||||||
|
samba4_idmap.add({"dn": "SID=%s,%s" % (samba3_idmap.get_user_sid(uid), domaindn),
|
||||||
|
"SID": samba3_idmap.get_user_sid(uid),
|
||||||
|
"type": "user",
|
||||||
|
"unixID": str(uid)})
|
||||||
|
|
||||||
for m in samba3.idmap.mappings:
|
for gid in samba3_idmap.uids():
|
||||||
ldif += """
|
samba4_idmap.add({"dn": "SID=%s,%s" % (samba3_idmap.get_group_sid(gid), domaindn),
|
||||||
dn: SID=%s,%s
|
"SID": samba3_idmap.get_group_sid(gid),
|
||||||
SID: %s
|
"type": "group",
|
||||||
type: %d
|
"unixID": str(gid)})
|
||||||
unixID: %d""" % (m.sid, domaindn, m.sid, m.type, m.unix_id)
|
|
||||||
|
|
||||||
return ldif
|
|
||||||
|
|
||||||
def upgrade_wins(samba3):
|
|
||||||
"""Upgrade the WINS database."""
|
def import_wins(samba4_winsdb, samba3_winsdb):
|
||||||
ldif = ""
|
"""Import settings from a Samba3 WINS database."""
|
||||||
version_id = 0
|
version_id = 0
|
||||||
|
import time
|
||||||
|
|
||||||
for e in samba3.winsentries:
|
for (name, (ttl, ips, nb_flags)) in samba3_winsdb.items():
|
||||||
now = sys.nttime()
|
|
||||||
ttl = sys.unix2nttime(e.ttl)
|
|
||||||
|
|
||||||
version_id+=1
|
version_id+=1
|
||||||
|
|
||||||
numIPs = len(e.ips)
|
numIPs = len(e.ips)
|
||||||
|
|
||||||
if e.type == 0x1C:
|
type = int(name.split("#", 1)[1], 16)
|
||||||
|
|
||||||
|
if type == 0x1C:
|
||||||
rType = 0x2
|
rType = 0x2
|
||||||
elif e.type & 0x80:
|
elif type & 0x80:
|
||||||
if numIPs > 1:
|
if len(ips) > 1:
|
||||||
rType = 0x2
|
rType = 0x2
|
||||||
else:
|
else:
|
||||||
rType = 0x1
|
rType = 0x1
|
||||||
else:
|
else:
|
||||||
if numIPs > 1:
|
if len(ips) > 1:
|
||||||
rType = 0x3
|
rType = 0x3
|
||||||
else:
|
else:
|
||||||
rType = 0x0
|
rType = 0x0
|
||||||
|
|
||||||
if ttl > now:
|
if ttl > time.time():
|
||||||
rState = 0x0 # active
|
rState = 0x0 # active
|
||||||
else:
|
else:
|
||||||
rState = 0x1 # released
|
rState = 0x1 # released
|
||||||
|
|
||||||
nType = ((e.nb_flags & 0x60)>>5)
|
nType = ((nb_flags & 0x60)>>5)
|
||||||
|
|
||||||
ldif += """
|
samba4_winsdb.add({"dn": "name=%s,type=0x%s" % name.split("#"),
|
||||||
dn: name=%s,type=0x%02X
|
"type": name.split("#")[1],
|
||||||
type: 0x%02X
|
"name": name.split("#")[0],
|
||||||
name: %s
|
"objectClass": "winsRecord",
|
||||||
objectClass: winsRecord
|
"recordType": str(rType),
|
||||||
recordType: %u
|
"recordState": str(rState),
|
||||||
recordState: %u
|
"nodeType": str(nType),
|
||||||
nodeType: %u
|
"expireTime": ldb.ldaptime(ttl),
|
||||||
isStatic: 0
|
"isStatic": "0",
|
||||||
expireTime: %s
|
"versionID": str(version_id),
|
||||||
versionID: %llu
|
"address": ips})
|
||||||
""" % (e.name, e.type, e.type, e.name,
|
|
||||||
rType, rState, nType,
|
|
||||||
ldaptime(ttl), version_id)
|
|
||||||
|
|
||||||
for ip in e.ips:
|
samba4_winsdb.add({"dn": "CN=VERSION",
|
||||||
ldif += "address: %s\n" % ip
|
"objectClass": "winsMaxVersion",
|
||||||
|
"maxVersion": str(version_id)})
|
||||||
ldif += """
|
|
||||||
dn: CN=VERSION
|
|
||||||
objectClass: winsMaxVersion
|
|
||||||
maxVersion: %llu
|
|
||||||
""" % version_id
|
|
||||||
|
|
||||||
return ldif
|
|
||||||
|
|
||||||
def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, paths):
|
def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, paths):
|
||||||
oldconf = samba3.get_conf()
|
oldconf = samba3.get_conf()
|
||||||
@ -417,6 +360,30 @@ def upgrade_smbconf(oldconf,mark):
|
|||||||
|
|
||||||
return newconf
|
return newconf
|
||||||
|
|
||||||
|
SAMBA3_PREDEF_NAMES = {
|
||||||
|
'HKLM': registry.HKEY_LOCAL_MACHINE,
|
||||||
|
}
|
||||||
|
|
||||||
|
def import_registry(samba4_registry, samba3_regdb):
|
||||||
|
"""Import a Samba 3 registry database into the Samba 4 registry.
|
||||||
|
|
||||||
|
:param samba4_registry: Samba 4 registry handle.
|
||||||
|
:param samba3_regdb: Samba 3 registry database handle.
|
||||||
|
"""
|
||||||
|
def ensure_key_exists(keypath):
|
||||||
|
(predef_name, keypath) = keypath.split("/", 1)
|
||||||
|
predef_id = SAMBA3_PREDEF_NAMES[predef_name]
|
||||||
|
keypath = keypath.replace("/", "\\")
|
||||||
|
return samba4_registry.create_key(predef_id, keypath)
|
||||||
|
|
||||||
|
for key in samba3_regdb.keys():
|
||||||
|
key_handle = ensure_key_exists(key)
|
||||||
|
for subkey in samba3_regdb.subkeys(key):
|
||||||
|
ensure_key_exists(subkey)
|
||||||
|
for (value_name, (value_type, value_data)) in samba3_regdb.values(key).items():
|
||||||
|
key_handle.set_value(value_name, value_type, value_data)
|
||||||
|
|
||||||
|
|
||||||
def upgrade(subobj, samba3, message, paths, session_info, credentials):
|
def upgrade(subobj, samba3, message, paths, session_info, credentials):
|
||||||
ret = 0
|
ret = 0
|
||||||
samdb = Ldb(paths.samdb, session_info=session_info, credentials=credentials)
|
samdb = Ldb(paths.samdb, session_info=session_info, credentials=credentials)
|
||||||
@ -462,21 +429,6 @@ data: %d
|
|||||||
ret += 1
|
ret += 1
|
||||||
message(msg)
|
message(msg)
|
||||||
|
|
||||||
message("Importing registry data")
|
|
||||||
for hive in ["hkcr","hkcu","hklm","hkpd","hku","hkpt"]:
|
|
||||||
message("... " + hive)
|
|
||||||
regdb = Ldb(paths[hive])
|
|
||||||
ldif = upgrade_registry(samba3.registry, hive, regdb)
|
|
||||||
for j in ldif:
|
|
||||||
msg = "... ... " + j
|
|
||||||
try:
|
|
||||||
regdb.add(ldif[j])
|
|
||||||
except LdbError, e:
|
|
||||||
# FIXME: Ignore 'Record exists' errors
|
|
||||||
msg += "... error: " + str(e)
|
|
||||||
ret += 1
|
|
||||||
message(msg)
|
|
||||||
|
|
||||||
message("Importing WINS data")
|
message("Importing WINS data")
|
||||||
winsdb = Ldb(paths.winsdb)
|
winsdb = Ldb(paths.winsdb)
|
||||||
ldb_erase(winsdb)
|
ldb_erase(winsdb)
|
||||||
|
Reference in New Issue
Block a user