diff options
-rwxr-xr-x | source4/scripting/bin/samba3dump | 11 | ||||
-rw-r--r-- | source4/scripting/python/samba/samba3.py | 28 | ||||
-rw-r--r-- | source4/scripting/python/samba/tests/samba3.py | 8 | ||||
-rw-r--r-- | source4/scripting/python/samba/upgrade.py | 188 |
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) |