summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/ldap_server/ldap_backend.c2
-rw-r--r--source4/lib/ldb/common/ldb.c17
-rw-r--r--source4/lib/ldb/include/ldb.h18
-rw-r--r--source4/lib/ldb/pyldb.c61
-rw-r--r--source4/scripting/python/pyglue.c6
-rw-r--r--source4/scripting/python/samba/__init__.py12
6 files changed, 106 insertions, 10 deletions
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index 8c6b8f9fd6..5eabda972e 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -546,7 +546,7 @@ reply:
NT_STATUS_HAVE_NO_MEMORY(modify_reply);
if (result == LDAP_SUCCESS) {
- ldb_ret = ldb_modify(samdb, msg);
+ ldb_ret = ldb_modify_ctrl(samdb, msg, call->request->controls);
result = map_ldb_error(local_ctx, ldb_ret, &errstr);
}
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
@@ -1217,6 +1217,24 @@ int ldb_add(struct ldb_context *ldb,
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
+
+ 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.
+
\return result code (LDB_SUCCESS if the record was modified as
requested, otherwise a failure code)
*/
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;
diff --git a/source4/scripting/python/pyglue.c b/source4/scripting/python/pyglue.c
index b138e3eeec..9f01102316 100644
--- a/source4/scripting/python/pyglue.c
+++ b/source4/scripting/python/pyglue.c
@@ -566,6 +566,12 @@ void initglue(void)
PyModule_AddObject(m, "DS_DC_FUNCTION_2008", PyInt_FromLong(DS_DC_FUNCTION_2008));
PyModule_AddObject(m, "DS_DC_FUNCTION_2008_R2", PyInt_FromLong(DS_DC_FUNCTION_2008_R2));
+ /* "LDAP_SERVER_SD_FLAGS_OID" */
+ PyModule_AddObject(m, "SECINFO_OWNER", PyInt_FromLong(SECINFO_OWNER));
+ PyModule_AddObject(m, "SECINFO_GROUP", PyInt_FromLong(SECINFO_GROUP));
+ PyModule_AddObject(m, "SECINFO_DACL", PyInt_FromLong(SECINFO_DACL));
+ PyModule_AddObject(m, "SECINFO_SACL", PyInt_FromLong(SECINFO_SACL));
+
/* one of the most annoying things about python scripts is
that they don't die when you hit control-C. This fixes that
sillyness. As we do all database operations using
diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py
index 06e276c2d0..f74304c01c 100644
--- a/source4/scripting/python/samba/__init__.py
+++ b/source4/scripting/python/samba/__init__.py
@@ -241,7 +241,7 @@ class Ldb(ldb.Ldb):
"""
self.add_ldif(open(ldif_path, 'r').read())
- def add_ldif(self, ldif,controls=None):
+ def add_ldif(self, ldif, controls=None):
"""Add data based on a LDIF string.
:param ldif: LDIF text.
@@ -250,13 +250,13 @@ class Ldb(ldb.Ldb):
assert changetype == ldb.CHANGETYPE_NONE
self.add(msg,controls)
- def modify_ldif(self, ldif):
+ def modify_ldif(self, ldif, controls=None):
"""Modify database based on a LDIF string.
:param ldif: LDIF text.
"""
for changetype, msg in self.parse_ldif(ldif):
- self.modify(msg)
+ self.modify(msg, controls)
def set_domain_sid(self, sid):
"""Change the domain SID used by this LDB.
@@ -423,3 +423,9 @@ DS_DC_FUNCTION_2003 = glue.DS_DC_FUNCTION_2003
DS_DC_FUNCTION_2008 = glue.DS_DC_FUNCTION_2008
DS_DC_FUNCTION_2008_R2 = glue.DS_DC_FUNCTION_2008_R2
+#LDAP_SERVER_SD_FLAGS_OID flags
+SECINFO_OWNER = glue.SECINFO_OWNER
+SECINFO_GROUP = glue.SECINFO_GROUP
+SECINFO_DACL = glue.SECINFO_DACL
+SECINFO_SACL = glue.SECINFO_SACL
+