mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
pytdb: Check if the database is closed before we touch it
If .close() has already been called, we have to play dead - the self->ctx is just not valid any more, as we have been shut down to allow some other part of Samba to open the tdb. Andrew Bartlett Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> Autobuild-Date(master): Mon Jul 16 13:51:52 CEST 2012 on sn-devel-104
This commit is contained in:
parent
a8e88332a3
commit
c92a5670e3
@ -75,6 +75,20 @@ static PyObject *PyString_FromTDB_DATA(TDB_DATA data)
|
|||||||
return NULL; \
|
return NULL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PyErr_TDB_RAISE_IF_CLOSED(self) \
|
||||||
|
if (self->closed) { \
|
||||||
|
PyErr_SetObject(PyExc_RuntimeError, \
|
||||||
|
Py_BuildValue("(i,s)", TDB_ERR_IO, "Database is already closed")); \
|
||||||
|
return NULL; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self) \
|
||||||
|
if (self->closed) { \
|
||||||
|
PyErr_SetObject(PyExc_RuntimeError, \
|
||||||
|
Py_BuildValue("(i,s)", TDB_ERR_IO, "Database is already closed")); \
|
||||||
|
return -1; \
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *py_tdb_open(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
static PyObject *py_tdb_open(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
@ -109,56 +123,74 @@ static PyObject *py_tdb_open(PyTypeObject *type, PyObject *args, PyObject *kwarg
|
|||||||
|
|
||||||
static PyObject *obj_transaction_cancel(PyTdbObject *self)
|
static PyObject *obj_transaction_cancel(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
int ret = tdb_transaction_cancel(self->ctx);
|
int ret;
|
||||||
|
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
|
||||||
|
ret = tdb_transaction_cancel(self->ctx);
|
||||||
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_transaction_commit(PyTdbObject *self)
|
static PyObject *obj_transaction_commit(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
int ret = tdb_transaction_commit(self->ctx);
|
int ret;
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
ret = tdb_transaction_commit(self->ctx);
|
||||||
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_transaction_prepare_commit(PyTdbObject *self)
|
static PyObject *obj_transaction_prepare_commit(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
int ret = tdb_transaction_prepare_commit(self->ctx);
|
int ret;
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
ret = tdb_transaction_prepare_commit(self->ctx);
|
||||||
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_transaction_start(PyTdbObject *self)
|
static PyObject *obj_transaction_start(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
int ret = tdb_transaction_start(self->ctx);
|
int ret;
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
ret = tdb_transaction_start(self->ctx);
|
||||||
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_reopen(PyTdbObject *self)
|
static PyObject *obj_reopen(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
int ret = tdb_reopen(self->ctx);
|
int ret;
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
ret = tdb_reopen(self->ctx);
|
||||||
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_lockall(PyTdbObject *self)
|
static PyObject *obj_lockall(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
int ret = tdb_lockall(self->ctx);
|
int ret;
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
ret = tdb_lockall(self->ctx);
|
||||||
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_unlockall(PyTdbObject *self)
|
static PyObject *obj_unlockall(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
int ret = tdb_unlockall(self->ctx);
|
int ret;
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
ret = tdb_unlockall(self->ctx);
|
||||||
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_lockall_read(PyTdbObject *self)
|
static PyObject *obj_lockall_read(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
int ret = tdb_lockall_read(self->ctx);
|
int ret;
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
ret = tdb_lockall_read(self->ctx);
|
||||||
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
@ -185,6 +217,9 @@ static PyObject *obj_get(PyTdbObject *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
TDB_DATA key;
|
TDB_DATA key;
|
||||||
PyObject *py_key;
|
PyObject *py_key;
|
||||||
|
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O", &py_key))
|
if (!PyArg_ParseTuple(args, "O", &py_key))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -200,6 +235,9 @@ static PyObject *obj_append(PyTdbObject *self, PyObject *args)
|
|||||||
TDB_DATA key, data;
|
TDB_DATA key, data;
|
||||||
PyObject *py_key, *py_data;
|
PyObject *py_key, *py_data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "OO", &py_key, &py_data))
|
if (!PyArg_ParseTuple(args, "OO", &py_key, &py_data))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -217,6 +255,8 @@ static PyObject *obj_append(PyTdbObject *self, PyObject *args)
|
|||||||
|
|
||||||
static PyObject *obj_firstkey(PyTdbObject *self)
|
static PyObject *obj_firstkey(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
|
||||||
return PyString_FromTDB_DATA(tdb_firstkey(self->ctx));
|
return PyString_FromTDB_DATA(tdb_firstkey(self->ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,6 +264,8 @@ static PyObject *obj_nextkey(PyTdbObject *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
TDB_DATA key;
|
TDB_DATA key;
|
||||||
PyObject *py_key;
|
PyObject *py_key;
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O", &py_key))
|
if (!PyArg_ParseTuple(args, "O", &py_key))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -239,6 +281,8 @@ static PyObject *obj_delete(PyTdbObject *self, PyObject *args)
|
|||||||
TDB_DATA key;
|
TDB_DATA key;
|
||||||
PyObject *py_key;
|
PyObject *py_key;
|
||||||
int ret;
|
int ret;
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O", &py_key))
|
if (!PyArg_ParseTuple(args, "O", &py_key))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -255,6 +299,8 @@ static PyObject *obj_has_key(PyTdbObject *self, PyObject *args)
|
|||||||
TDB_DATA key;
|
TDB_DATA key;
|
||||||
int ret;
|
int ret;
|
||||||
PyObject *py_key;
|
PyObject *py_key;
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O", &py_key))
|
if (!PyArg_ParseTuple(args, "O", &py_key))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -276,6 +322,8 @@ static PyObject *obj_store(PyTdbObject *self, PyObject *args)
|
|||||||
int flag = TDB_REPLACE;
|
int flag = TDB_REPLACE;
|
||||||
PyObject *py_key, *py_value;
|
PyObject *py_key, *py_value;
|
||||||
|
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "OO|i", &py_key, &py_value, &flag))
|
if (!PyArg_ParseTuple(args, "OO|i", &py_key, &py_value, &flag))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -295,6 +343,8 @@ static PyObject *obj_add_flags(PyTdbObject *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
|
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "I", &flags))
|
if (!PyArg_ParseTuple(args, "I", &flags))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -306,6 +356,8 @@ static PyObject *obj_remove_flags(PyTdbObject *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
|
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "I", &flags))
|
if (!PyArg_ParseTuple(args, "I", &flags))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -350,6 +402,8 @@ static PyObject *tdb_object_iter(PyTdbObject *self)
|
|||||||
{
|
{
|
||||||
PyTdbIteratorObject *ret;
|
PyTdbIteratorObject *ret;
|
||||||
|
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
|
||||||
ret = PyObject_New(PyTdbIteratorObject, &PyTdbIterator);
|
ret = PyObject_New(PyTdbIteratorObject, &PyTdbIterator);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -361,26 +415,32 @@ static PyObject *tdb_object_iter(PyTdbObject *self)
|
|||||||
|
|
||||||
static PyObject *obj_clear(PyTdbObject *self)
|
static PyObject *obj_clear(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
int ret = tdb_wipe_all(self->ctx);
|
int ret;
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
ret = tdb_wipe_all(self->ctx);
|
||||||
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_repack(PyTdbObject *self)
|
static PyObject *obj_repack(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
int ret = tdb_repack(self->ctx);
|
int ret;
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
|
ret = tdb_repack(self->ctx);
|
||||||
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_enable_seqnum(PyTdbObject *self)
|
static PyObject *obj_enable_seqnum(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
tdb_enable_seqnum(self->ctx);
|
tdb_enable_seqnum(self->ctx);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_increment_seqnum_nonblock(PyTdbObject *self)
|
static PyObject *obj_increment_seqnum_nonblock(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
tdb_increment_seqnum_nonblock(self->ctx);
|
tdb_increment_seqnum_nonblock(self->ctx);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
@ -434,11 +494,13 @@ static PyMethodDef tdb_object_methods[] = {
|
|||||||
|
|
||||||
static PyObject *obj_get_hash_size(PyTdbObject *self, void *closure)
|
static PyObject *obj_get_hash_size(PyTdbObject *self, void *closure)
|
||||||
{
|
{
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
return PyInt_FromLong(tdb_hash_size(self->ctx));
|
return PyInt_FromLong(tdb_hash_size(self->ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int obj_set_max_dead(PyTdbObject *self, PyObject *max_dead, void *closure)
|
static int obj_set_max_dead(PyTdbObject *self, PyObject *max_dead, void *closure)
|
||||||
{
|
{
|
||||||
|
PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self);
|
||||||
if (!PyInt_Check(max_dead))
|
if (!PyInt_Check(max_dead))
|
||||||
return -1;
|
return -1;
|
||||||
tdb_set_max_dead(self->ctx, PyInt_AsLong(max_dead));
|
tdb_set_max_dead(self->ctx, PyInt_AsLong(max_dead));
|
||||||
@ -447,26 +509,31 @@ static int obj_set_max_dead(PyTdbObject *self, PyObject *max_dead, void *closure
|
|||||||
|
|
||||||
static PyObject *obj_get_map_size(PyTdbObject *self, void *closure)
|
static PyObject *obj_get_map_size(PyTdbObject *self, void *closure)
|
||||||
{
|
{
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
return PyInt_FromLong(tdb_map_size(self->ctx));
|
return PyInt_FromLong(tdb_map_size(self->ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_get_freelist_size(PyTdbObject *self, void *closure)
|
static PyObject *obj_get_freelist_size(PyTdbObject *self, void *closure)
|
||||||
{
|
{
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
return PyInt_FromLong(tdb_freelist_size(self->ctx));
|
return PyInt_FromLong(tdb_freelist_size(self->ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_get_flags(PyTdbObject *self, void *closure)
|
static PyObject *obj_get_flags(PyTdbObject *self, void *closure)
|
||||||
{
|
{
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
return PyInt_FromLong(tdb_get_flags(self->ctx));
|
return PyInt_FromLong(tdb_get_flags(self->ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_get_filename(PyTdbObject *self, void *closure)
|
static PyObject *obj_get_filename(PyTdbObject *self, void *closure)
|
||||||
{
|
{
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
return PyString_FromString(tdb_name(self->ctx));
|
return PyString_FromString(tdb_name(self->ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *obj_get_seqnum(PyTdbObject *self, void *closure)
|
static PyObject *obj_get_seqnum(PyTdbObject *self, void *closure)
|
||||||
{
|
{
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
return PyInt_FromLong(tdb_get_seqnum(self->ctx));
|
return PyInt_FromLong(tdb_get_seqnum(self->ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,6 +551,7 @@ static PyGetSetDef tdb_object_getsetters[] = {
|
|||||||
|
|
||||||
static PyObject *tdb_object_repr(PyTdbObject *self)
|
static PyObject *tdb_object_repr(PyTdbObject *self)
|
||||||
{
|
{
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
if (tdb_get_flags(self->ctx) & TDB_INTERNAL) {
|
if (tdb_get_flags(self->ctx) & TDB_INTERNAL) {
|
||||||
return PyString_FromString("Tdb(<internal>)");
|
return PyString_FromString("Tdb(<internal>)");
|
||||||
} else {
|
} else {
|
||||||
@ -501,6 +569,7 @@ static void tdb_object_dealloc(PyTdbObject *self)
|
|||||||
static PyObject *obj_getitem(PyTdbObject *self, PyObject *key)
|
static PyObject *obj_getitem(PyTdbObject *self, PyObject *key)
|
||||||
{
|
{
|
||||||
TDB_DATA tkey, val;
|
TDB_DATA tkey, val;
|
||||||
|
PyErr_TDB_RAISE_IF_CLOSED(self);
|
||||||
if (!PyString_Check(key)) {
|
if (!PyString_Check(key)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "Expected string as key");
|
PyErr_SetString(PyExc_TypeError, "Expected string as key");
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -522,6 +591,7 @@ static int obj_setitem(PyTdbObject *self, PyObject *key, PyObject *value)
|
|||||||
{
|
{
|
||||||
TDB_DATA tkey, tval;
|
TDB_DATA tkey, tval;
|
||||||
int ret;
|
int ret;
|
||||||
|
PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self);
|
||||||
if (!PyString_Check(key)) {
|
if (!PyString_Check(key)) {
|
||||||
PyErr_SetString(PyExc_TypeError, "Expected string as key");
|
PyErr_SetString(PyExc_TypeError, "Expected string as key");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -33,6 +33,11 @@ class CloseTdbTests(TestCase):
|
|||||||
self.tdb.close()
|
self.tdb.close()
|
||||||
self.tdb.close()
|
self.tdb.close()
|
||||||
|
|
||||||
|
# Check that further operations do not crash python
|
||||||
|
self.assertRaises(RuntimeError, lambda: self.tdb.transaction_start())
|
||||||
|
|
||||||
|
self.assertRaises(RuntimeError, lambda: self.tdb["bar"])
|
||||||
|
|
||||||
|
|
||||||
class InternalTdbTests(TestCase):
|
class InternalTdbTests(TestCase):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user