svn commit: samba r26607 - in branches/SAMBA_4_0: . source/scripting/bin source/scripting/python/samba source/scripting/python/samba/tests

jelmer at samba.org jelmer at samba.org
Wed Dec 26 20:55:07 GMT 2007


Author: jelmer
Date: 2007-12-26 20:55:05 +0000 (Wed, 26 Dec 2007)
New Revision: 26607

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=26607

Log:
Fix reading of values and subkeys in Samba 3 registry files.
Modified:
   branches/SAMBA_4_0/
   branches/SAMBA_4_0/source/scripting/bin/samba3dump
   branches/SAMBA_4_0/source/scripting/python/samba/samba3.py
   branches/SAMBA_4_0/source/scripting/python/samba/tests/samba3.py
   branches/SAMBA_4_0/source/scripting/python/samba/upgrade.py


Changeset:

Property changes on: branches/SAMBA_4_0
___________________________________________________________________
Name: bzr:revision-info
...skipped...
Name: bzr:revision-id:v3-trunk0
...skipped...

Modified: branches/SAMBA_4_0/source/scripting/bin/samba3dump
===================================================================
--- branches/SAMBA_4_0/source/scripting/bin/samba3dump	2007-12-26 11:38:49 UTC (rev 26606)
+++ branches/SAMBA_4_0/source/scripting/bin/samba3dump	2007-12-26 20:55:05 UTC (rev 26607)
@@ -80,7 +80,7 @@
     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_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 @@
 
 libdir = args[0]
 if len(args) > 1:
-    smbconf = args[2]
+    smbconf = args[1]
 else:
     smbconf = os.path.join(libdir, "smb.conf")
 

Modified: branches/SAMBA_4_0/source/scripting/python/samba/samba3.py
===================================================================
--- branches/SAMBA_4_0/source/scripting/python/samba/samba3.py	2007-12-26 11:38:49 UTC (rev 26606)
+++ branches/SAMBA_4_0/source/scripting/python/samba/samba3.py	2007-12-26 20:55:05 UTC (rev 26607)
@@ -45,18 +45,38 @@
         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:
     def __init__(self, file):
         self.tdb = tdb.Tdb(file, flags=os.O_RDONLY)

Modified: branches/SAMBA_4_0/source/scripting/python/samba/tests/samba3.py
===================================================================
--- branches/SAMBA_4_0/source/scripting/python/samba/tests/samba3.py	2007-12-26 11:38:49 UTC (rev 26606)
+++ branches/SAMBA_4_0/source/scripting/python/samba/tests/samba3.py	2007-12-26 20:55:05 UTC (rev 26607)
@@ -38,7 +38,15 @@
     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):
         self.policy = PolicyDatabase(os.path.join(DATADIR, "account_policy.tdb"))

Modified: branches/SAMBA_4_0/source/scripting/python/samba/upgrade.py
===================================================================
--- branches/SAMBA_4_0/source/scripting/python/samba/upgrade.py	2007-12-26 11:38:49 UTC (rev 26606)
+++ branches/SAMBA_4_0/source/scripting/python/samba/upgrade.py	2007-12-26 20:55:05 UTC (rev 26607)
@@ -11,22 +11,8 @@
 import grp
 import pwd
 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:
 # - HKLM
 #   HKU
@@ -35,39 +21,6 @@
 #   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,83 +130,73 @@
 
     return ldif
 
-def upgrade_winbind(samba3,domaindn):
-    ldif = """
-        
-dn: dc=none
-userHwm: %d
-groupHwm: %d
+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())})
 
-""" % (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:
-        ldif += """
-dn: SID=%s,%s
-SID: %s
-type: %d
-unixID: %d""" % (m.sid, domaindn, m.sid, m.type, m.unix_id)
-    
-    return ldif
+    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 upgrade_wins(samba3):
-    """Upgrade the WINS database."""
-    ldif = ""
+
+def import_wins(samba4_winsdb, samba3_winsdb):
+    """Import settings from a Samba3 WINS database."""
     version_id = 0
+    import time
 
-    for e in samba3.winsentries:
-        now = sys.nttime()
-        ttl = sys.unix2nttime(e.ttl)
-
+    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)
+        nType = ((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)
+        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})
 
-        for ip in e.ips:
-            ldif += "address: %s\n" % ip
+    samba4_winsdb.add({"dn": "CN=VERSION",
+                       "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):
     oldconf = samba3.get_conf()
 
@@ -417,6 +360,30 @@
 
     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 @@
                 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)



More information about the samba-cvs mailing list