diff options
-rw-r--r-- | source4/lib/tdb/tdb.i | 32 | ||||
-rw-r--r-- | source4/lib/tdb/tdb.py | 14 | ||||
-rw-r--r-- | source4/lib/tdb/tdb_wrap.c | 87 | ||||
-rw-r--r-- | source4/samba4-skip | 1 | ||||
-rw-r--r-- | source4/scripting/python/samba/samba3.py | 42 | ||||
-rw-r--r-- | source4/scripting/python/samba/tests/samba3.py | 10 |
6 files changed, 128 insertions, 58 deletions
diff --git a/source4/lib/tdb/tdb.i b/source4/lib/tdb/tdb.i index 41eaf77202..933bfc7bb7 100644 --- a/source4/lib/tdb/tdb.i +++ b/source4/lib/tdb/tdb.i @@ -60,12 +60,16 @@ typedef TDB_CONTEXT tdb; data.. */ %typemap(in,noblock=1) TDB_DATA { - if (!PyString_Check($input)) { + if ($input == Py_None) { + $1.dsize = 0; + $1.dptr = NULL; + } else if (!PyString_Check($input)) { PyErr_SetString(PyExc_TypeError, "string arg expected"); return NULL; - } - $1.dsize = PyString_Size($input); - $1.dptr = (uint8_t *)PyString_AsString($input); + } else { + $1.dsize = PyString_Size($input); + $1.dptr = (uint8_t *)PyString_AsString($input); + } } %typemap(out,noblock=1) TDB_DATA { @@ -74,7 +78,7 @@ typedef TDB_CONTEXT tdb; } else { $result = PyString_FromStringAndSize((const char *)$1.dptr, $1.dsize); free($1.dptr); - } + } } /* Treat a mode_t as an unsigned integer */ @@ -146,8 +150,8 @@ enum TDB_ERROR { typedef struct tdb_context { %extend { - tdb(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode) { - return tdb_open(name, hash_size, tdb_flags, open_flags, mode); + tdb(const char *name, int hash_size, int tdb_flags, int flags, mode_t mode) { + return tdb_open(name, hash_size, tdb_flags, flags, mode); } enum TDB_ERROR error(); ~tdb() { tdb_close($self); } @@ -202,6 +206,20 @@ typedef struct tdb_context { def has_key(self, key): return self.exists(key) != 0 + def fetch_uint32(self, key): + data = self.fetch(key) + if data is None: + return None + import struct + return struct.unpack("<L", data)[0] + + def fetch_int32(self, key): + data = self.fetch(key) + if data is None: + return None + import struct + return struct.unpack("<l", data)[0] + # Tdb iterator class TdbIterator: def __init__(self, tdb): diff --git a/source4/lib/tdb/tdb.py b/source4/lib/tdb/tdb.py index d4cf9f5c6f..8566397ed3 100644 --- a/source4/lib/tdb/tdb.py +++ b/source4/lib/tdb/tdb.py @@ -108,6 +108,20 @@ class tdb(object): def has_key(self, key): return self.exists(key) != 0 + def fetch_uint32(self, key): + data = self.fetch(key) + if data is None: + return None + import struct + return struct.unpack("<L", data)[0] + + def fetch_int32(self, key): + data = self.fetch(key) + if data is None: + return None + import struct + return struct.unpack("<l", data)[0] + class TdbIterator: def __init__(self, tdb): diff --git a/source4/lib/tdb/tdb_wrap.c b/source4/lib/tdb/tdb_wrap.c index a58442b521..c6dc337f63 100644 --- a/source4/lib/tdb/tdb_wrap.c +++ b/source4/lib/tdb/tdb_wrap.c @@ -2747,8 +2747,8 @@ SWIG_AsVal_int (PyObject * obj, int *val) return res; } -SWIGINTERN tdb *new_tdb(char const *name,int hash_size,int tdb_flags,int open_flags,mode_t mode){ - return tdb_open(name, hash_size, tdb_flags, open_flags, mode); +SWIGINTERN tdb *new_tdb(char const *name,int hash_size,int tdb_flags,int flags,mode_t mode){ + return tdb_open(name, hash_size, tdb_flags, flags, mode); } SWIGINTERN void delete_tdb(tdb *self){ tdb_close(self); } @@ -2818,12 +2818,11 @@ SWIGINTERN PyObject *_wrap_new_Tdb(PyObject *SWIGUNUSEDPARM(self), PyObject *arg PyObject * obj3 = 0 ; PyObject * obj4 = 0 ; char * kwnames[] = { - (char *) "name",(char *) "hash_size",(char *) "tdb_flags",(char *) "open_flags",(char *) "mode", NULL + (char *) "name",(char *) "hash_size",(char *) "tdb_flags",(char *) "flags",(char *) "mode", NULL }; arg2 = 0; arg3 = TDB_DEFAULT; - arg4 = O_RDWR; arg5 = 0600; if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"O|OOOO:new_Tdb",kwnames,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); @@ -2964,18 +2963,26 @@ SWIGINTERN PyObject *_wrap_tdb_append(PyObject *SWIGUNUSEDPARM(self), PyObject * SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "tdb_append" "', argument " "1"" of type '" "tdb *""'"); } arg1 = (tdb *)(argp1); - if (!PyString_Check(obj1)) { + if (obj1 == Py_None) { + (&arg2)->dsize = 0; + (&arg2)->dptr = NULL; + } else if (!PyString_Check(obj1)) { PyErr_SetString(PyExc_TypeError, "string arg expected"); return NULL; + } else { + (&arg2)->dsize = PyString_Size(obj1); + (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); } - (&arg2)->dsize = PyString_Size(obj1); - (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); - if (!PyString_Check(obj2)) { + if (obj2 == Py_None) { + (&arg3)->dsize = 0; + (&arg3)->dptr = NULL; + } else if (!PyString_Check(obj2)) { PyErr_SetString(PyExc_TypeError, "string arg expected"); return NULL; + } else { + (&arg3)->dsize = PyString_Size(obj2); + (&arg3)->dptr = (uint8_t *)PyString_AsString(obj2); } - (&arg3)->dsize = PyString_Size(obj2); - (&arg3)->dptr = (uint8_t *)PyString_AsString(obj2); result = (int)tdb_append(arg1,arg2,arg3); resultobj = SWIG_From_int((int)(result)); return resultobj; @@ -3026,12 +3033,16 @@ SWIGINTERN PyObject *_wrap_tdb_fetch(PyObject *SWIGUNUSEDPARM(self), PyObject *a SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "tdb_fetch" "', argument " "1"" of type '" "tdb *""'"); } arg1 = (tdb *)(argp1); - if (!PyString_Check(obj1)) { + if (obj1 == Py_None) { + (&arg2)->dsize = 0; + (&arg2)->dptr = NULL; + } else if (!PyString_Check(obj1)) { PyErr_SetString(PyExc_TypeError, "string arg expected"); return NULL; + } else { + (&arg2)->dsize = PyString_Size(obj1); + (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); } - (&arg2)->dsize = PyString_Size(obj1); - (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); result = tdb_fetch(arg1,arg2); if ((&result)->dptr == NULL && (&result)->dsize == 0) { resultobj = Py_None; @@ -3064,12 +3075,16 @@ SWIGINTERN PyObject *_wrap_tdb_delete(PyObject *SWIGUNUSEDPARM(self), PyObject * SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "tdb_delete" "', argument " "1"" of type '" "tdb *""'"); } arg1 = (tdb *)(argp1); - if (!PyString_Check(obj1)) { + if (obj1 == Py_None) { + (&arg2)->dsize = 0; + (&arg2)->dptr = NULL; + } else if (!PyString_Check(obj1)) { PyErr_SetString(PyExc_TypeError, "string arg expected"); return NULL; + } else { + (&arg2)->dsize = PyString_Size(obj1); + (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); } - (&arg2)->dsize = PyString_Size(obj1); - (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); result = (int)tdb_delete(arg1,arg2); resultobj = SWIG_From_int((int)(result)); return resultobj; @@ -3104,18 +3119,26 @@ SWIGINTERN PyObject *_wrap_tdb_store(PyObject *SWIGUNUSEDPARM(self), PyObject *a SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "tdb_store" "', argument " "1"" of type '" "tdb *""'"); } arg1 = (tdb *)(argp1); - if (!PyString_Check(obj1)) { + if (obj1 == Py_None) { + (&arg2)->dsize = 0; + (&arg2)->dptr = NULL; + } else if (!PyString_Check(obj1)) { PyErr_SetString(PyExc_TypeError, "string arg expected"); return NULL; + } else { + (&arg2)->dsize = PyString_Size(obj1); + (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); } - (&arg2)->dsize = PyString_Size(obj1); - (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); - if (!PyString_Check(obj2)) { + if (obj2 == Py_None) { + (&arg3)->dsize = 0; + (&arg3)->dptr = NULL; + } else if (!PyString_Check(obj2)) { PyErr_SetString(PyExc_TypeError, "string arg expected"); return NULL; + } else { + (&arg3)->dsize = PyString_Size(obj2); + (&arg3)->dptr = (uint8_t *)PyString_AsString(obj2); } - (&arg3)->dsize = PyString_Size(obj2); - (&arg3)->dptr = (uint8_t *)PyString_AsString(obj2); if (obj3) { ecode4 = SWIG_AsVal_int(obj3, &val4); if (!SWIG_IsOK(ecode4)) { @@ -3150,12 +3173,16 @@ SWIGINTERN PyObject *_wrap_tdb_exists(PyObject *SWIGUNUSEDPARM(self), PyObject * SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "tdb_exists" "', argument " "1"" of type '" "tdb *""'"); } arg1 = (tdb *)(argp1); - if (!PyString_Check(obj1)) { + if (obj1 == Py_None) { + (&arg2)->dsize = 0; + (&arg2)->dptr = NULL; + } else if (!PyString_Check(obj1)) { PyErr_SetString(PyExc_TypeError, "string arg expected"); return NULL; + } else { + (&arg2)->dsize = PyString_Size(obj1); + (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); } - (&arg2)->dsize = PyString_Size(obj1); - (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); result = (int)tdb_exists(arg1,arg2); resultobj = SWIG_From_int((int)(result)); return resultobj; @@ -3211,12 +3238,16 @@ SWIGINTERN PyObject *_wrap_tdb_nextkey(PyObject *SWIGUNUSEDPARM(self), PyObject SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "tdb_nextkey" "', argument " "1"" of type '" "tdb *""'"); } arg1 = (tdb *)(argp1); - if (!PyString_Check(obj1)) { + if (obj1 == Py_None) { + (&arg2)->dsize = 0; + (&arg2)->dptr = NULL; + } else if (!PyString_Check(obj1)) { PyErr_SetString(PyExc_TypeError, "string arg expected"); return NULL; + } else { + (&arg2)->dsize = PyString_Size(obj1); + (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); } - (&arg2)->dsize = PyString_Size(obj1); - (&arg2)->dptr = (uint8_t *)PyString_AsString(obj1); result = tdb_nextkey(arg1,arg2); if ((&result)->dptr == NULL && (&result)->dsize == 0) { resultobj = Py_None; diff --git a/source4/samba4-skip b/source4/samba4-skip index 9ca63f4568..6115b28ec8 100644 --- a/source4/samba4-skip +++ b/source4/samba4-skip @@ -50,4 +50,3 @@ RPC-FRSAPI # Not provided by Samba 4 WINBIND # FIXME: This should not be skipped NSS-TEST # Fails samba4.ldap.python # Conversion from EJS not yet finished -samba4.samba3.python # Conversion from EJS not yet finished diff --git a/source4/scripting/python/samba/samba3.py b/source4/scripting/python/samba/samba3.py index d8289ae756..8225eacd58 100644 --- a/source4/scripting/python/samba/samba3.py +++ b/source4/scripting/python/samba/samba3.py @@ -22,12 +22,16 @@ REGISTRY_VALUE_PREFIX = "SAMBA_REGVAL" REGISTRY_DB_VERSION = 1 +import os import tdb class Registry: """Simple read-only support for reading the Samba3 registry.""" def __init__(self, file): - self.tdb = tdb.Tdb(file) + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) + + def close(self): + self.tdb.close() def __len__(self): """Return the number of keys.""" @@ -38,7 +42,7 @@ class Registry: return [k.rstrip("\x00") for k in self.tdb.keys() if not k.startswith(REGISTRY_VALUE_PREFIX)] def subkeys(self, key): - data = self.tdb.get(key) + data = self.tdb.get("%s\x00" % key) if data is None: return [] # FIXME: Parse data @@ -46,7 +50,7 @@ class Registry: def values(self, key): """Return a dictionary with the values set for a specific key.""" - data = self.tdb.get("%s/%s" % (REGISTRY_VALUE_PREFIX, key)) + data = self.tdb.get("%s/%s\x00" % (REGISTRY_VALUE_PREFIX, key)) if data is None: return {} # FIXME: Parse data @@ -55,17 +59,17 @@ class Registry: class PolicyDatabase: def __init__(self, file): - self.tdb = tdb.Tdb(file) - self.min_password_length = tdb.fetch_uint32("min password length") - self.user_must_logon_to_change_password = tdb.fetch_uint32("password history") - self.user_must_logon_to_change_password = tdb.fetch_uint32("user must logon to change pasword") - self.maximum_password_age = tdb.fetch_uint32("maximum password age") - self.minimum_password_age = tdb.fetch_uint32("minimum password age") - self.lockout_duration = tdb.fetch_uint32("lockout duration") - self.reset_count_minutes = tdb.fetch_uint32("reset count minutes") - self.bad_lockout_minutes = tdb.fetch_uint32("bad lockout minutes") - self.disconnect_time = tdb.fetch_uint32("disconnect time") - self.refuse_machine_password_change = tdb.fetch_uint32("refuse machine password change") + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) + self.min_password_length = self.tdb.fetch_uint32("min password length\x00") + self.password_history = self.tdb.fetch_uint32("password history\x00") + self.user_must_logon_to_change_password = self.tdb.fetch_uint32("user must logon to change pasword\x00") + self.maximum_password_age = self.tdb.fetch_uint32("maximum password age\x00") + self.minimum_password_age = self.tdb.fetch_uint32("minimum password age\x00") + self.lockout_duration = self.tdb.fetch_uint32("lockout duration\x00") + self.reset_count_minutes = self.tdb.fetch_uint32("reset count minutes\x00") + self.bad_lockout_minutes = self.tdb.fetch_uint32("bad lockout minutes\x00") + self.disconnect_time = self.tdb.fetch_int32("disconnect time\x00") + self.refuse_machine_password_change = self.tdb.fetch_uint32("refuse machine password change\x00") # FIXME: Read privileges as well @@ -83,7 +87,7 @@ MEMBEROF_PREFIX = "MEMBEROF/" class GroupMappingDatabase: def __init__(self, file): - self.tdb = tdb.Tdb(file) + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) # High water mark keys @@ -95,13 +99,13 @@ IDMAP_VERSION = 2 class IdmapDatabase: def __init__(self, file): - self.tdb = tdb.Tdb(file) + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) assert self.tdb.fetch_int32("IDMAP_VERSION") == IDMAP_VERSION class SecretsDatabase: def __init__(self, file): - self.tdb = tdb.Tdb(file) + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) self.domains = {} for k, v in self.tdb.items(): if k == "SECRETS/AUTH_PASSWORD": @@ -138,7 +142,7 @@ SHARE_DATABASE_VERSION_V2 = 2 class ShareInfoDatabase: def __init__(self, file): - self.tdb = tdb.Tdb(file) + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) assert self.tdb.fetch_int32("INFO/version") in (SHARE_DATABASE_VERSION_V1, SHARE_DATABASE_VERSION_V2) def get_secdesc(self, name): @@ -189,7 +193,7 @@ class Smbpasswd: class TdbSam: def __init__(self, file): - self.tdb = tdb.Tdb(file) + self.tdb = tdb.Tdb(file, flags=os.O_RDONLY) class WinsDatabase: diff --git a/source4/scripting/python/samba/tests/samba3.py b/source4/scripting/python/samba/tests/samba3.py index c6b6281c60..0d56ca9117 100644 --- a/source4/scripting/python/samba/tests/samba3.py +++ b/source4/scripting/python/samba/tests/samba3.py @@ -22,16 +22,20 @@ from samba.samba3 import GroupMappingDatabase, Registry, PolicyDatabase import os DATADIR=os.path.join(os.path.dirname(__file__), "../../../../../testdata/samba3") +print "Samba 3 data dir: %s" % DATADIR class RegistryTestCase(unittest.TestCase): def setUp(self): self.registry = Registry(os.path.join(DATADIR, "registry.tdb")) + def tearDown(self): + self.registry.close() + def test_length(self): self.assertEquals(28, len(self.registry)) def test_keys(self): - self.assertEquals([], self.registry.keys()) + self.assertTrue("HKLM" in self.registry.keys()) class PolicyTestCase(unittest.TestCase): @@ -45,10 +49,10 @@ class PolicyTestCase(unittest.TestCase): self.assertEquals(self.policy.refuse_machine_password_change, 0) self.assertEquals(self.policy.reset_count_minutes, 0) self.assertEquals(self.policy.disconnect_time, -1) - self.assertEquals(self.policy.user_must_logon_to_change_password, 0) + self.assertEquals(self.policy.user_must_logon_to_change_password, None) self.assertEquals(self.policy.password_history, 0) self.assertEquals(self.policy.lockout_duration, 0) - self.assertEquals(self.policy.bad_lockout_minutes, 0) + self.assertEquals(self.policy.bad_lockout_minutes, None) class GroupsTestCase(unittest.TestCase): |