From a760f169f4936d7e2677db9229181e2c5ac23bcd Mon Sep 17 00:00:00 2001 From: Nadezhda Ivanova Date: Fri, 20 Nov 2009 13:22:38 +0200 Subject: Some changes to allow processing of ldap controls on modify requests. ldap_backend used to filter out ldap controls on modify. Also, modified python binding for ldap_modify to allow writing tests for such controls. --- source4/lib/ldb/common/ldb.c | 17 +++++++++--- source4/lib/ldb/include/ldb.h | 18 +++++++++++++ source4/lib/ldb/pyldb.c | 61 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 90 insertions(+), 6 deletions(-) (limited to 'source4/lib') diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 20e32064ec..3a8023ac93 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -1378,10 +1378,11 @@ int ldb_add(struct ldb_context *ldb, } /* - modify the specified attributes of a record + same as ldb_modify, but accepts controls */ -int ldb_modify(struct ldb_context *ldb, - const struct ldb_message *message) +int ldb_modify_ctrl(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_control **controls) { struct ldb_request *req; int ret; @@ -1393,7 +1394,7 @@ int ldb_modify(struct ldb_context *ldb, ret = ldb_build_mod_req(&req, ldb, ldb, message, - NULL, + controls, NULL, ldb_op_default_callback, NULL); @@ -1406,6 +1407,14 @@ int ldb_modify(struct ldb_context *ldb, talloc_free(req); return ret; } +/* + modify the specified attributes of a record +*/ +int ldb_modify(struct ldb_context *ldb, + const struct ldb_message *message) +{ + return ldb_modify_ctrl(ldb, message, NULL); +} /* diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 1d0b533a33..62cd2b8c64 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -1208,6 +1208,24 @@ int ldb_search(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, int ldb_add(struct ldb_context *ldb, const struct ldb_message *message); +/** + Modify the specified attributes of a record + + This function modifies a record that is in the database. + + \param ldb the context associated with the database (from + ldb_init()) + \param message the message containing the changes required. + + \param controls ldap controls for the request + + \return result code (LDB_SUCCESS if the record was modified as + requested, otherwise a failure code) +*/ +int ldb_modify_ctrl(struct ldb_context *ldb, + const struct ldb_message *message, + struct ldb_control **controls); + /** Modify the specified attributes of a record diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c index 1f1dcf8e31..0d1d2fa966 100644 --- a/source4/lib/ldb/pyldb.c +++ b/source4/lib/ldb/pyldb.c @@ -641,16 +641,73 @@ static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwa static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args) { PyObject *py_msg; + PyObject *py_controls = Py_None; + struct ldb_context *ldb_ctx; + struct ldb_request *req; + struct ldb_control **parsed_controls; + struct ldb_message *msg; int ret; - if (!PyArg_ParseTuple(args, "O", &py_msg)) + if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls)) return NULL; + ldb_ctx = PyLdb_AsLdbContext(self); + + 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 (!PyLdbMessage_Check(py_msg)) { PyErr_SetString(PyExc_TypeError, "Expected Ldb Message"); return NULL; } + 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)); + return NULL; + } - ret = ldb_modify(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg)); + ret = ldb_build_mod_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"); + 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_transaction_start(ldb_ctx); + if (ret != LDB_SUCCESS) { + talloc_free(req); + 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); PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self)); Py_RETURN_NONE; -- cgit