summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2007-12-26 20:55:05 -0600
committerStefan Metzmacher <metze@samba.org>2007-12-26 15:03:02 -0600
commitc4d3666ac2821518be57ca89d963f77bbddaedf4 (patch)
treedc7cdeb6ff096808c98688541abdbaa33c344abf
parente0132b560257fd9b8562fbe378604e446d3153f3 (diff)
downloadsamba-c4d3666ac2821518be57ca89d963f77bbddaedf4.tar.gz
samba-c4d3666ac2821518be57ca89d963f77bbddaedf4.tar.bz2
samba-c4d3666ac2821518be57ca89d963f77bbddaedf4.zip
r26607: Fix reading of values and subkeys in Samba 3 registry files.
(This used to be commit e3d7454ef70d6fe9a1ce34eaf57268bd5b713ccf)
-rwxr-xr-xsource4/scripting/bin/samba3dump11
-rw-r--r--source4/scripting/python/samba/samba3.py28
-rw-r--r--source4/scripting/python/samba/tests/samba3.py8
-rw-r--r--source4/scripting/python/samba/upgrade.py188
4 files changed, 108 insertions, 127 deletions
diff --git a/source4/scripting/bin/samba3dump b/source4/scripting/bin/samba3dump
index f8d10cbc71..8f56d423d8 100755
--- a/source4/scripting/bin/samba3dump
+++ b/source4/scripting/bin/samba3dump
@@ -80,7 +80,7 @@ def print_samba3_secrets(secrets):
for domain in secrets.domains():
print "\t--- %s ---" % 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)
if 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):
print_header("Registry")
+ from registry import str_regtype
for k in regdb.keys():
- print "%s" % k
- for v in regdb.values(k):
- print "\t%s: type %d, length %d" % (v.name, v.type, v.data.length)
+ print "[%s]" % k
+ for (value_name, (type, value)) in regdb.values(k).items():
+ print "\"%s\"=%s:%s" % (value_name, str_regtype(type), value)
def print_samba3_winsdb(winsdb):
print_header("WINS Database")
@@ -151,7 +152,7 @@ def print_samba3_summary(samba3):
libdir = args[0]
if len(args) > 1:
- smbconf = args[2]
+ smbconf = args[1]
else:
smbconf = os.path.join(libdir, "smb.conf")
diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py
index b4261f7c74..df94f3503c 100644
--- a/source4/scripting/python/samba/samba3.py
+++ b/source4/scripting/python/samba/samba3.py
@@ -45,16 +45,36 @@ class Registry:
data = self.tdb.get("%s\x00" % key)
if data is None:
return []
- # FIXME: Parse data
- return []
+ import struct
+ (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):
"""Return a dictionary with the values set for a specific key."""
data = self.tdb.get("%s/%s\x00" % (REGISTRY_VALUE_PREFIX, key))
if data is None:
return {}
- # FIXME: Parse data
- return {}
+ ret = {}
+ 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:
diff --git a/source4/scripting/python/samba/tests/samba3.py b/source4/scripting/python/samba/tests/samba3.py
index 580bcfa3c2..e25562929a 100644
--- a/source4/scripting/python/samba/tests/samba3.py
+++ b/source4/scripting/python/samba/tests/samba3.py
@@ -38,6 +38,14 @@ class RegistryTestCase(unittest.TestCase):
def test_keys(self):
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):
def setUp(self):
diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py
index 05a63d9326..a6bd07df58 100644
--- a/source4/scripting/python/samba/upgrade.py
+++ b/source4/scripting/python/samba/upgrade.py
@@ -11,21 +11,7 @@ from provision import findnss, provision
import grp
import pwd
import uuid
-
-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
+import registry
# Where prefix is any of:
# - HKLM
@@ -35,39 +21,6 @@ def regkey_to_dn(name):
# 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):
ldif = """
dn: %s
@@ -177,82 +130,72 @@ group.comment, group.nt_name, group.sid, group.unixname, group.sid_name_use)
return ldif
-def upgrade_winbind(samba3,domaindn):
- ldif = """
-
-dn: dc=none
-userHwm: %d
-groupHwm: %d
-
-""" % (samba3.idmap.user_hwm, samba3.idmap.group_hwm)
-
- for m in samba3.idmap.mappings:
- ldif += """
-dn: SID=%s,%s
-SID: %s
-type: %d
-unixID: %d""" % (m.sid, domaindn, m.sid, m.type, m.unix_id)
-
- return ldif
+def import_idmap(samba4_idmap,samba3_idmap,domaindn):
+ samba4_idmap.add({
+ "dn": domaindn,
+ "userHwm": str(samba3_idmap.get_user_hwm()),
+ "groupHwm": str(samba3_idmap.get_group_hwm())})
-def upgrade_wins(samba3):
- """Upgrade the WINS database."""
- ldif = ""
- version_id = 0
+ 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 e in samba3.winsentries:
- now = sys.nttime()
- ttl = sys.unix2nttime(e.ttl)
+ for gid in samba3_idmap.uids():
+ samba4_idmap.add({"dn": "SID=%s,%s" % (samba3_idmap.get_group_sid(gid), domaindn),
+ "SID": samba3_idmap.get_group_sid(gid),
+ "type": "group",
+ "unixID": str(gid)})
+
+def import_wins(samba4_winsdb, samba3_winsdb):
+ """Import settings from a Samba3 WINS database."""
+ version_id = 0
+ import time
+
+ for (name, (ttl, ips, nb_flags)) in samba3_winsdb.items():
version_id+=1
numIPs = len(e.ips)
- if e.type == 0x1C:
+ type = int(name.split("#", 1)[1], 16)
+
+ if type == 0x1C:
rType = 0x2
- elif e.type & 0x80:
- if numIPs > 1:
+ elif type & 0x80:
+ if len(ips) > 1:
rType = 0x2
else:
rType = 0x1
else:
- if numIPs > 1:
+ if len(ips) > 1:
rType = 0x3
else:
rType = 0x0
- if ttl > now:
+ if ttl > time.time():
rState = 0x0 # active
else:
rState = 0x1 # released
- nType = ((e.nb_flags & 0x60)>>5)
-
- ldif += """
-dn: name=%s,type=0x%02X
-type: 0x%02X
-name: %s
-objectClass: winsRecord
-recordType: %u
-recordState: %u
-nodeType: %u
-isStatic: 0
-expireTime: %s
-versionID: %llu
-""" % (e.name, e.type, e.type, e.name,
- rType, rState, nType,
- ldaptime(ttl), version_id)
-
- for ip in e.ips:
- ldif += "address: %s\n" % ip
-
- ldif += """
-dn: CN=VERSION
-objectClass: winsMaxVersion
-maxVersion: %llu
-""" % version_id
+ nType = ((nb_flags & 0x60)>>5)
- return ldif
+ samba4_winsdb.add({"dn": "name=%s,type=0x%s" % name.split("#"),
+ "type": name.split("#")[1],
+ "name": name.split("#")[0],
+ "objectClass": "winsRecord",
+ "recordType": str(rType),
+ "recordState": str(rState),
+ "nodeType": str(nType),
+ "expireTime": ldb.ldaptime(ttl),
+ "isStatic": "0",
+ "versionID": str(version_id),
+ "address": ips})
+
+ samba4_winsdb.add({"dn": "CN=VERSION",
+ "objectClass": "winsMaxVersion",
+ "maxVersion": str(version_id)})
def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp, paths):
oldconf = samba3.get_conf()
@@ -417,6 +360,30 @@ def upgrade_smbconf(oldconf,mark):
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):
ret = 0
samdb = Ldb(paths.samdb, session_info=session_info, credentials=credentials)
@@ -462,21 +429,6 @@ data: %d
ret += 1
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")
winsdb = Ldb(paths.winsdb)
ldb_erase(winsdb)