diff options
-rw-r--r-- | source4/lib/ldb/pyldb.c | 63 | ||||
-rwxr-xr-x | source4/lib/ldb/tests/python/api.py | 8 |
2 files changed, 67 insertions, 4 deletions
diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c index b4f03dc538..1ba5109f2f 100644 --- a/source4/lib/ldb/pyldb.c +++ b/source4/lib/ldb/pyldb.c @@ -663,21 +663,32 @@ static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args) Py_ssize_t dict_pos, msg_pos; struct ldb_message_element *msgel; struct ldb_message *msg; + struct ldb_context *ldb_ctx; + struct ldb_request *req; PyObject *key, *value; + PyObject *py_controls = Py_None; TALLOC_CTX *mem_ctx; + struct ldb_control **parsed_controls; - if (!PyArg_ParseTuple(args, "O", &py_msg)) + if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls )) return NULL; + ldb_ctx = PyLdb_AsLdbContext(self); mem_ctx = talloc_new(NULL); - + if (py_controls == Py_None) { + parsed_controls = NULL; + } else { + const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls"); + parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls); + talloc_free(controls); + } if (PyDict_Check(py_msg)) { PyObject *dn_value = PyDict_GetItemString(py_msg, "dn"); msg = ldb_msg_new(mem_ctx); msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg)); msg_pos = dict_pos = 0; if (dn_value) { - if (!PyObject_AsDn(msg, dn_value, PyLdb_AsLdbContext(self), &msg->dn)) { + if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) { PyErr_SetString(PyExc_TypeError, "unable to import dn object"); talloc_free(mem_ctx); return NULL; @@ -713,8 +724,52 @@ static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args) } else { msg = PyLdbMessage_AsMessage(py_msg); } + + ret = ldb_msg_sanity_check(ldb_ctx, msg); + if (ret != LDB_SUCCESS) { + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self)); + talloc_free(mem_ctx); + return NULL; + } + + ret = ldb_build_add_req(&req, ldb_ctx, ldb_ctx, + msg, + parsed_controls, + NULL, + ldb_op_default_callback, + NULL); + + if (ret != LDB_SUCCESS) { + PyErr_SetString(PyExc_TypeError, "failed to build request"); + talloc_free(mem_ctx); + return NULL; + } + + /* do request and autostart a transaction */ + /* Then let's LDB handle the message error in case of pb as they are meaningful */ - ret = ldb_add(PyLdb_AsLdbContext(self), msg); + ret = ldb_transaction_start(ldb_ctx); + if (ret != LDB_SUCCESS) { + talloc_free(req); + talloc_free(mem_ctx); + PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self)); + } + + ret = ldb_request(ldb_ctx, req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + + if (ret == LDB_SUCCESS) { + ret = ldb_transaction_commit(ldb_ctx); + } else { + ldb_transaction_cancel(ldb_ctx); + if (ldb_ctx->err_string == NULL) { + /* no error string was setup by the backend */ + ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret); + } + } + talloc_free(req); talloc_free(mem_ctx); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self)); diff --git a/source4/lib/ldb/tests/python/api.py b/source4/lib/ldb/tests/python/api.py index 133bd180c1..956908d7d6 100755 --- a/source4/lib/ldb/tests/python/api.py +++ b/source4/lib/ldb/tests/python/api.py @@ -136,6 +136,14 @@ class SimpleLdb(unittest.TestCase): finally: l.delete(ldb.Dn(l, "dc=foo4")) + def test_add_w_unhandled_ctrl(self): + l = ldb.Ldb(filename()) + m = ldb.Message() + m.dn = ldb.Dn(l, "dc=foo4") + m["bla"] = "bla" + self.assertEquals(len(l.search()), 1) + self.assertRaises(ldb.LdbError, lambda: l.add(m,["search_options:1:2"])) + def test_add_dict(self): l = ldb.Ldb(filename()) m = {"dn": ldb.Dn(l, "dc=foo5"), |