2 Unix SMB/CIFS implementation.
4 Python interface to ldb.
6 Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7 Copyright (C) 2006 Simo Sorce <idra@samba.org>
8 Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9 Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10 Copyright (C) 2009-2011 Andrew Tridgell
11 Copyright (C) 2009-2011 Andrew Bartlett
13 ** NOTE! The following LGPL license applies to the ldb
14 ** library. This does NOT imply that all of Samba is released
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public
19 License as published by the Free Software Foundation; either
20 version 3 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 #include "ldb_private.h"
33 #include "ldb_handlers.h"
35 #include "dlinklist.h"
37 struct py_ldb_search_iterator_reply;
44 struct ldb_request *req;
45 struct py_ldb_search_iterator_reply *next;
46 struct py_ldb_search_iterator_reply *result;
49 } PyLdbSearchIteratorObject;
51 struct py_ldb_search_iterator_reply {
52 struct py_ldb_search_iterator_reply *prev, *next;
53 PyLdbSearchIteratorObject *py_iter;
58 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
59 static PyObject *PyExc_LdbError;
61 static PyTypeObject PyLdbControl;
62 static PyTypeObject PyLdbResult;
63 static PyTypeObject PyLdbSearchIterator;
64 static PyTypeObject PyLdbMessage;
65 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
66 static PyTypeObject PyLdbModule;
67 static PyTypeObject PyLdbDn;
68 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
69 static PyTypeObject PyLdb;
70 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
71 static PyTypeObject PyLdbMessageElement;
72 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
74 static PyTypeObject PyLdbTree;
75 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
76 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
77 static struct ldb_message_element *PyObject_AsMessageElement(
81 const char *attr_name);
82 static PyTypeObject PyLdbBytesType;
84 #if PY_MAJOR_VERSION >= 3
85 #define PyStr_Check PyUnicode_Check
86 #define PyStr_FromString PyUnicode_FromString
87 #define PyStr_FromStringAndSize PyUnicode_FromStringAndSize
88 #define PyStr_FromFormat PyUnicode_FromFormat
89 #define PyStr_FromFormatV PyUnicode_FromFormatV
90 #define PyStr_AsUTF8 PyUnicode_AsUTF8
91 #define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize
92 #define PyInt_FromLong PyLong_FromLong
94 #define PYARG_STR_UNI "es"
96 static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size)
98 PyObject* result = NULL;
99 PyObject* args = NULL;
100 args = Py_BuildValue("(y#)", msg, size);
101 result = PyLdbBytesType.tp_new(&PyLdbBytesType, args, NULL);
106 #define PyStr_Check PyString_Check
107 #define PyStr_FromString PyString_FromString
108 #define PyStr_FromStringAndSize PyString_FromStringAndSize
109 #define PyStr_FromFormat PyString_FromFormat
110 #define PyStr_FromFormatV PyString_FromFormatV
111 #define PyStr_AsUTF8 PyString_AsString
112 #define PyLdbBytes_FromStringAndSize PyString_FromStringAndSize
114 #define PYARG_STR_UNI "et"
116 const char *PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr);
118 PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr)
120 const char * ret = PyString_AsString(pystr);
123 *sizeptr = PyString_Size(pystr);
128 static PyObject *richcmp(int cmp_val, int op)
132 case Py_LT: ret = cmp_val < 0; break;
133 case Py_LE: ret = cmp_val <= 0; break;
134 case Py_EQ: ret = cmp_val == 0; break;
135 case Py_NE: ret = cmp_val != 0; break;
136 case Py_GT: ret = cmp_val > 0; break;
137 case Py_GE: ret = cmp_val >= 0; break;
139 Py_INCREF(Py_NotImplemented);
140 return Py_NotImplemented;
142 return PyBool_FromLong(ret);
146 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
148 if (self->data != NULL) {
149 char* control = ldb_control_to_string(self->mem_ctx, self->data);
150 if (control == NULL) {
154 return PyStr_FromString(control);
156 return PyStr_FromString("ldb control");
160 static void py_ldb_control_dealloc(PyLdbControlObject *self)
162 if (self->mem_ctx != NULL) {
163 talloc_free(self->mem_ctx);
166 Py_TYPE(self)->tp_free(self);
169 /* Create a text (rather than bytes) interface for a LDB result object */
170 static PyObject *wrap_text(const char *type, PyObject *wrapped)
172 PyObject *mod, *cls, *constructor, *inst;
173 mod = PyImport_ImportModule("_ldb_text");
176 cls = PyObject_GetAttrString(mod, type);
182 constructor = PyObject_GetAttrString(cls, "_wrap");
184 if (constructor == NULL) {
187 inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped);
188 Py_DECREF(constructor);
192 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
194 return PyStr_FromString(self->data->oid);
197 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
199 return PyBool_FromLong(self->data->critical);
202 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
204 if (PyObject_IsTrue(value)) {
205 self->data->critical = true;
207 self->data->critical = false;
212 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
215 const char * const kwnames[] = { "ldb", "data", NULL };
216 struct ldb_control *parsed_controls;
217 PyLdbControlObject *ret;
220 struct ldb_context *ldb_ctx;
222 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
223 discard_const_p(char *, kwnames),
224 &PyLdb, &py_ldb, &data))
227 mem_ctx = talloc_new(NULL);
228 if (mem_ctx == NULL) {
233 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
234 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
236 if (!parsed_controls) {
237 talloc_free(mem_ctx);
238 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
242 ret = PyObject_New(PyLdbControlObject, type);
245 talloc_free(mem_ctx);
249 ret->mem_ctx = mem_ctx;
251 ret->data = talloc_move(mem_ctx, &parsed_controls);
252 if (ret->data == NULL) {
255 talloc_free(mem_ctx);
259 return (PyObject *)ret;
262 static PyGetSetDef py_ldb_control_getset[] = {
263 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
264 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
268 static PyTypeObject PyLdbControl = {
269 .tp_name = "ldb.control",
270 .tp_dealloc = (destructor)py_ldb_control_dealloc,
271 .tp_getattro = PyObject_GenericGetAttr,
272 .tp_basicsize = sizeof(PyLdbControlObject),
273 .tp_getset = py_ldb_control_getset,
274 .tp_doc = "LDB control.",
275 .tp_str = (reprfunc)py_ldb_control_str,
276 .tp_new = py_ldb_control_new,
277 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
280 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
282 if (ret == LDB_ERR_PYTHON_EXCEPTION)
283 return; /* Python exception should already be set, just keep that */
285 PyErr_SetObject(error,
286 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
287 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
289 static PyObject *py_ldb_bytes_str(PyBytesObject *self)
294 if (!PyBytes_Check(self)) {
295 PyErr_Format(PyExc_TypeError,"Unexpected type");
298 result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size);
300 PyErr_Format(PyExc_TypeError, "Failed to extract bytes");
303 return PyUnicode_FromStringAndSize(msg, size);
306 static PyTypeObject PyLdbBytesType = {
307 PyVarObject_HEAD_INIT(NULL, 0)
308 .tp_name = "ldb.bytes",
309 .tp_doc = "str/bytes (with custom str)",
310 .tp_str = (reprfunc)py_ldb_bytes_str,
311 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
314 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
316 return PyLdbBytes_FromStringAndSize((const char *)val->data, val->length);
319 static PyObject *PyStr_FromLdbValue(const struct ldb_val *val)
321 return PyStr_FromStringAndSize((const char *)val->data, val->length);
325 * Create a Python object from a ldb_result.
327 * @param result LDB result to convert
328 * @return Python object with converted result (a list object)
330 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
332 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
333 PyLdbControlObject *ctrl;
334 if (ctl_ctx == NULL) {
339 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
341 talloc_free(ctl_ctx);
345 ctrl->mem_ctx = ctl_ctx;
346 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
347 if (ctrl->data == NULL) {
352 return (PyObject*) ctrl;
356 * Create a Python object from a ldb_result.
358 * @param result LDB result to convert
359 * @return Python object with converted result (a list object)
361 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
363 PyLdbResultObject *ret;
364 PyObject *list, *controls, *referals;
367 if (result == NULL) {
371 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
377 list = PyList_New(result->count);
384 for (i = 0; i < result->count; i++) {
385 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
388 ret->mem_ctx = talloc_new(NULL);
389 if (ret->mem_ctx == NULL) {
398 if (result->controls) {
400 while (result->controls[i]) {
403 controls = PyList_New(i);
404 if (controls == NULL) {
409 for (i=0; result->controls[i]; i++) {
410 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
417 PyList_SetItem(controls, i, ctrl);
421 * No controls so we keep an empty list
423 controls = PyList_New(0);
424 if (controls == NULL) {
431 ret->controls = controls;
435 while (result->refs && result->refs[i]) {
439 referals = PyList_New(i);
440 if (referals == NULL) {
446 for (i = 0;result->refs && result->refs[i]; i++) {
447 PyList_SetItem(referals, i, PyStr_FromString(result->refs[i]));
449 ret->referals = referals;
450 return (PyObject *)ret;
454 * Create a LDB Result from a Python object.
455 * If conversion fails, NULL will be returned and a Python exception set.
457 * Note: the result object only includes the messages at the moment; extended
458 * result, controls and referrals are ignored.
460 * @param mem_ctx Memory context in which to allocate the LDB Result
461 * @param obj Python object to convert
462 * @return a ldb_result, or NULL if the conversion failed
464 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
467 struct ldb_result *res;
473 res = talloc_zero(mem_ctx, struct ldb_result);
474 res->count = PyList_Size(obj);
475 res->msgs = talloc_array(res, struct ldb_message *, res->count);
476 for (i = 0; i < res->count; i++) {
477 PyObject *item = PyList_GetItem(obj, i);
478 res->msgs[i] = pyldb_Message_AsMessage(item);
483 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
485 return PyBool_FromLong(ldb_dn_validate(self->dn));
488 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
490 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
493 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
495 return PyBool_FromLong(ldb_dn_is_special(self->dn));
498 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
500 return PyBool_FromLong(ldb_dn_is_null(self->dn));
503 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
505 return PyStr_FromString(ldb_dn_get_casefold(self->dn));
508 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
510 return PyStr_FromString(ldb_dn_get_linearized(self->dn));
513 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
515 return PyStr_FromString(ldb_dn_canonical_string(self->dn, self->dn));
518 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
520 return PyStr_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
523 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
525 const char * const kwnames[] = { "mode", NULL };
527 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
528 discard_const_p(char *, kwnames),
531 return PyStr_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
534 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
537 const struct ldb_val *val;
539 if (!PyArg_ParseTuple(args, "s", &name))
541 val = ldb_dn_get_extended_component(self->dn, name);
546 return PyBytes_FromStringAndSize((const char *)val->data, val->length);
549 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
553 uint8_t *value = NULL;
556 if (!PyArg_ParseTuple(args, "sz#", &name, (char **)&value, &size))
560 err = ldb_dn_set_extended_component(self->dn, name, NULL);
563 val.data = (uint8_t *)value;
565 err = ldb_dn_set_extended_component(self->dn, name, &val);
568 if (err != LDB_SUCCESS) {
569 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
576 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
578 PyObject *str = PyStr_FromString(ldb_dn_get_linearized(self->dn));
579 PyObject *repr, *result;
582 repr = PyObject_Repr(str);
587 result = PyStr_FromFormat("Dn(%s)", PyStr_AsUTF8(repr));
593 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
597 if (!PyArg_ParseTuple(args, "s", &name))
600 return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
603 static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
606 if (!pyldb_Dn_Check(dn2)) {
607 Py_INCREF(Py_NotImplemented);
608 return Py_NotImplemented;
610 ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2));
611 return richcmp(ret, op);
614 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
616 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
617 struct ldb_dn *parent;
618 PyLdbDnObject *py_ret;
619 TALLOC_CTX *mem_ctx = talloc_new(NULL);
621 parent = ldb_dn_get_parent(mem_ctx, dn);
622 if (parent == NULL) {
623 talloc_free(mem_ctx);
627 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
628 if (py_ret == NULL) {
630 talloc_free(mem_ctx);
633 py_ret->mem_ctx = mem_ctx;
635 return (PyObject *)py_ret;
638 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
641 struct ldb_dn *dn, *other;
642 if (!PyArg_ParseTuple(args, "O", &py_other))
645 dn = pyldb_Dn_AsDn((PyObject *)self);
647 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
650 return PyBool_FromLong(ldb_dn_add_child(dn, other));
653 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
656 struct ldb_dn *other, *dn;
657 if (!PyArg_ParseTuple(args, "O", &py_other))
660 dn = pyldb_Dn_AsDn((PyObject *)self);
662 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
665 return PyBool_FromLong(ldb_dn_add_base(dn, other));
668 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
672 if (!PyArg_ParseTuple(args, "i", &i))
675 dn = pyldb_Dn_AsDn((PyObject *)self);
677 return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
680 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
683 struct ldb_dn *dn, *base;
684 if (!PyArg_ParseTuple(args, "O", &py_base))
687 dn = pyldb_Dn_AsDn((PyObject *)self);
689 if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
692 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
695 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
699 unsigned int num = 0;
701 if (!PyArg_ParseTuple(args, "I", &num))
704 dn = pyldb_Dn_AsDn((PyObject *)self);
706 name = ldb_dn_get_component_name(dn, num);
711 return PyStr_FromString(name);
714 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
717 const struct ldb_val *val;
718 unsigned int num = 0;
720 if (!PyArg_ParseTuple(args, "I", &num))
723 dn = pyldb_Dn_AsDn((PyObject *)self);
725 val = ldb_dn_get_component_val(dn, num);
730 return PyStr_FromLdbValue(val);
733 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
735 unsigned int num = 0;
736 char *name = NULL, *value = NULL;
737 struct ldb_val val = { NULL, };
741 if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size))
744 val.data = (unsigned char*) value;
747 err = ldb_dn_set_component(self->dn, num, name, val);
748 if (err != LDB_SUCCESS) {
749 PyErr_SetString(PyExc_TypeError, "Failed to set component");
756 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
761 dn = pyldb_Dn_AsDn((PyObject *)self);
763 name = ldb_dn_get_rdn_name(dn);
768 return PyStr_FromString(name);
771 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
774 const struct ldb_val *val;
776 dn = pyldb_Dn_AsDn((PyObject *)self);
778 val = ldb_dn_get_rdn_val(dn);
783 return PyStr_FromLdbValue(val);
786 static PyMethodDef py_ldb_dn_methods[] = {
787 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
788 "S.validate() -> bool\n"
789 "Validate DN is correct." },
790 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
791 "S.is_valid() -> bool\n" },
792 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
793 "S.is_special() -> bool\n"
794 "Check whether this is a special LDB DN." },
795 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
796 "Check whether this is a null DN." },
797 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
799 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
801 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
802 "S.canonical_str() -> string\n"
803 "Canonical version of this DN (like a posix path)." },
804 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
805 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
806 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
807 "S.canonical_ex_str() -> string\n"
808 "Canonical version of this DN (like a posix path, with terminating newline)." },
809 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
810 "S.extended_str(mode=1) -> string\n"
811 "Extended version of this DN" },
812 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
814 "Get the parent for this DN." },
815 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
816 "S.add_child(dn) -> None\n"
817 "Add a child DN to this DN." },
818 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
819 "S.add_base(dn) -> None\n"
820 "Add a base DN to this DN." },
821 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
822 "S.remove_base_components(int) -> bool\n"
823 "Remove a number of DN components from the base of this DN." },
824 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
825 "S.check_special(name) -> bool\n\n"
826 "Check if name is a special DN name"},
827 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
828 "S.get_extended_component(name) -> string\n\n"
829 "returns a DN extended component as a binary string"},
830 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
831 "S.set_extended_component(name, value) -> None\n\n"
832 "set a DN extended component as a binary string"},
833 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
834 "S.get_component_name(num) -> string\n"
835 "get the attribute name of the specified component" },
836 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
837 "S.get_component_value(num) -> string\n"
838 "get the attribute value of the specified component as a binary string" },
839 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
840 "S.get_component_value(num, name, value) -> None\n"
841 "set the attribute name and value of the specified component" },
842 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
843 "S.get_rdn_name() -> string\n"
844 "get the RDN attribute name" },
845 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
846 "S.get_rdn_value() -> string\n"
847 "get the RDN attribute value as a binary string" },
851 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
853 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
857 copy a DN as a python object
859 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
861 PyLdbDnObject *py_ret;
863 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
864 if (py_ret == NULL) {
868 py_ret->mem_ctx = talloc_new(NULL);
869 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
870 return (PyObject *)py_ret;
873 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
875 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
877 PyLdbDnObject *py_ret;
879 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
882 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
883 if (py_ret == NULL) {
887 py_ret->mem_ctx = talloc_new(NULL);
888 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
889 ldb_dn_add_base(py_ret->dn, other);
890 return (PyObject *)py_ret;
893 static PySequenceMethods py_ldb_dn_seq = {
894 .sq_length = (lenfunc)py_ldb_dn_len,
895 .sq_concat = (binaryfunc)py_ldb_dn_concat,
898 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
900 struct ldb_dn *ret = NULL;
902 PyObject *py_ldb = NULL;
903 struct ldb_context *ldb_ctx = NULL;
904 TALLOC_CTX *mem_ctx = NULL;
905 PyLdbDnObject *py_ret = NULL;
906 const char * const kwnames[] = { "ldb", "dn", NULL };
908 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O"PYARG_STR_UNI,
909 discard_const_p(char *, kwnames),
910 &py_ldb, "utf8", &str))
913 if (!PyLdb_Check(py_ldb)) {
914 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
918 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
920 mem_ctx = talloc_new(NULL);
921 if (mem_ctx == NULL) {
926 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
927 if (!ldb_dn_validate(ret)) {
928 talloc_free(mem_ctx);
929 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
933 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
934 if (py_ret == NULL) {
935 talloc_free(mem_ctx);
939 py_ret->mem_ctx = mem_ctx;
943 PyMem_Free(discard_const_p(char, str));
945 return (PyObject *)py_ret;
948 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
950 talloc_free(self->mem_ctx);
954 static PyTypeObject PyLdbDn = {
956 .tp_methods = py_ldb_dn_methods,
957 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
958 .tp_repr = (reprfunc)py_ldb_dn_repr,
959 .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp,
960 .tp_as_sequence = &py_ldb_dn_seq,
961 .tp_doc = "A LDB distinguished name.",
962 .tp_new = py_ldb_dn_new,
963 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
964 .tp_basicsize = sizeof(PyLdbDnObject),
965 .tp_flags = Py_TPFLAGS_DEFAULT,
969 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
970 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
972 PyObject *fn = (PyObject *)context;
973 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyStr_FromFormatV(fmt, ap));
976 static PyObject *py_ldb_debug_func;
978 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
981 struct ldb_context *ldb_ctx;
983 if (!PyArg_ParseTuple(args, "O", &cb))
986 if (py_ldb_debug_func != NULL) {
987 Py_DECREF(py_ldb_debug_func);
991 /* FIXME: DECREF cb when exiting program */
992 py_ldb_debug_func = cb;
993 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
994 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
995 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
1001 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
1004 if (!PyArg_ParseTuple(args, "I", &perms))
1007 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
1012 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
1015 if (!PyArg_ParseTuple(args, "s", &modules_dir))
1018 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
1023 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
1025 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1027 ldb_err = ldb_transaction_start(ldb_ctx);
1028 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1032 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
1034 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1036 ldb_err = ldb_transaction_commit(ldb_ctx);
1037 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1041 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
1043 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1045 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
1046 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1050 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
1052 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1054 ldb_err = ldb_transaction_cancel(ldb_ctx);
1055 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1059 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
1061 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1063 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
1064 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1068 static PyObject *py_ldb_repr(PyLdbObject *self)
1070 return PyStr_FromString("<ldb connection>");
1073 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
1075 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
1078 return py_ldb_dn_copy(dn);
1082 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
1084 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
1087 return py_ldb_dn_copy(dn);
1090 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
1092 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
1095 return py_ldb_dn_copy(dn);
1098 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
1100 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
1103 return py_ldb_dn_copy(dn);
1106 static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
1107 const char *paramname)
1111 if (!PyList_Check(list)) {
1112 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
1115 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1121 for (i = 0; i < PyList_Size(list); i++) {
1122 const char *str = NULL;
1124 PyObject *item = PyList_GetItem(list, i);
1125 if (!(PyStr_Check(item) || PyUnicode_Check(item))) {
1126 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
1130 str = PyStr_AsUTF8AndSize(item, &size);
1135 ret[i] = talloc_strndup(ret, str, size);
1141 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1143 const char * const kwnames[] = { "url", "flags", "options", NULL };
1145 PyObject *py_options = Py_None;
1146 const char **options;
1147 unsigned int flags = 0;
1149 struct ldb_context *ldb;
1151 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1152 discard_const_p(char *, kwnames),
1153 &url, &flags, &py_options))
1156 ldb = pyldb_Ldb_AsLdbContext(self);
1158 if (py_options == Py_None) {
1161 options = PyList_AsStrList(ldb, py_options, "options");
1162 if (options == NULL)
1167 ret = ldb_connect(ldb, url, flags, options);
1168 if (ret != LDB_SUCCESS) {
1169 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1174 talloc_free(options);
1178 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1181 struct ldb_context *ldb;
1182 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1187 ret->mem_ctx = talloc_new(NULL);
1188 ldb = ldb_init(ret->mem_ctx, NULL);
1196 return (PyObject *)ret;
1199 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1202 unsigned int flags = 0;
1203 PyObject *py_options = Py_None;
1205 const char **options;
1206 const char * const kwnames[] = { "url", "flags", "options", NULL };
1207 struct ldb_context *ldb_ctx;
1209 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
1210 discard_const_p(char *, kwnames),
1211 &url, &flags, &py_options))
1214 if (py_options == Py_None) {
1217 options = PyList_AsStrList(NULL, py_options, "options");
1218 if (options == NULL)
1222 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1223 ret = ldb_connect(ldb_ctx, url, flags, options);
1224 talloc_free(options);
1226 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1231 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1234 PyObject *py_controls = Py_None;
1235 struct ldb_context *ldb_ctx;
1236 struct ldb_request *req;
1237 struct ldb_control **parsed_controls;
1238 struct ldb_message *msg;
1240 TALLOC_CTX *mem_ctx;
1242 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1244 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1245 discard_const_p(char *, kwnames),
1246 &py_msg, &py_controls, &validate))
1249 mem_ctx = talloc_new(NULL);
1250 if (mem_ctx == NULL) {
1254 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1256 if (py_controls == Py_None) {
1257 parsed_controls = NULL;
1259 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1260 if (controls == NULL) {
1261 talloc_free(mem_ctx);
1264 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1265 talloc_free(controls);
1268 if (!PyLdbMessage_Check(py_msg)) {
1269 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1270 talloc_free(mem_ctx);
1273 msg = pyldb_Message_AsMessage(py_msg);
1276 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1277 if (ret != LDB_SUCCESS) {
1278 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1279 talloc_free(mem_ctx);
1284 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1285 NULL, ldb_op_default_callback, NULL);
1286 if (ret != LDB_SUCCESS) {
1287 PyErr_SetString(PyExc_TypeError, "failed to build request");
1288 talloc_free(mem_ctx);
1292 /* do request and autostart a transaction */
1293 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1295 ret = ldb_transaction_start(ldb_ctx);
1296 if (ret != LDB_SUCCESS) {
1297 talloc_free(mem_ctx);
1298 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1302 ret = ldb_request(ldb_ctx, req);
1303 if (ret == LDB_SUCCESS) {
1304 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1307 if (ret == LDB_SUCCESS) {
1308 ret = ldb_transaction_commit(ldb_ctx);
1310 ldb_transaction_cancel(ldb_ctx);
1313 talloc_free(mem_ctx);
1314 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1321 * Obtain a ldb message from a Python Dictionary object.
1323 * @param mem_ctx Memory context
1324 * @param py_obj Python Dictionary object
1325 * @param ldb_ctx LDB context
1326 * @param mod_flags Flags to be set on every message element
1327 * @return ldb_message on success or NULL on failure
1329 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1331 struct ldb_context *ldb_ctx,
1332 unsigned int mod_flags)
1334 struct ldb_message *msg;
1335 unsigned int msg_pos = 0;
1336 Py_ssize_t dict_pos = 0;
1337 PyObject *key, *value;
1338 struct ldb_message_element *msg_el;
1339 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1341 msg = ldb_msg_new(mem_ctx);
1346 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1349 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1350 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1353 if (msg->dn == NULL) {
1354 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1358 PyErr_SetString(PyExc_TypeError, "no dn set");
1362 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1363 const char *key_str = PyStr_AsUTF8(key);
1364 if (ldb_attr_cmp(key_str, "dn") != 0) {
1365 msg_el = PyObject_AsMessageElement(msg->elements, value,
1366 mod_flags, key_str);
1367 if (msg_el == NULL) {
1368 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1371 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1376 msg->num_elements = msg_pos;
1381 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1385 struct ldb_context *ldb_ctx;
1386 struct ldb_request *req;
1387 struct ldb_message *msg = NULL;
1388 PyObject *py_controls = Py_None;
1389 TALLOC_CTX *mem_ctx;
1390 struct ldb_control **parsed_controls;
1391 const char * const kwnames[] = { "message", "controls", NULL };
1393 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1394 discard_const_p(char *, kwnames),
1395 &py_obj, &py_controls))
1398 mem_ctx = talloc_new(NULL);
1399 if (mem_ctx == NULL) {
1403 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1405 if (py_controls == Py_None) {
1406 parsed_controls = NULL;
1408 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1409 if (controls == NULL) {
1410 talloc_free(mem_ctx);
1413 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1414 talloc_free(controls);
1417 if (PyLdbMessage_Check(py_obj)) {
1418 msg = pyldb_Message_AsMessage(py_obj);
1419 } else if (PyDict_Check(py_obj)) {
1420 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1422 PyErr_SetString(PyExc_TypeError,
1423 "Dictionary or LdbMessage object expected!");
1427 /* we should have a PyErr already set */
1428 talloc_free(mem_ctx);
1432 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1433 if (ret != LDB_SUCCESS) {
1434 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1435 talloc_free(mem_ctx);
1439 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1440 NULL, ldb_op_default_callback, NULL);
1441 if (ret != LDB_SUCCESS) {
1442 PyErr_SetString(PyExc_TypeError, "failed to build request");
1443 talloc_free(mem_ctx);
1447 /* do request and autostart a transaction */
1448 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1450 ret = ldb_transaction_start(ldb_ctx);
1451 if (ret != LDB_SUCCESS) {
1452 talloc_free(mem_ctx);
1453 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1457 ret = ldb_request(ldb_ctx, req);
1458 if (ret == LDB_SUCCESS) {
1459 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1462 if (ret == LDB_SUCCESS) {
1463 ret = ldb_transaction_commit(ldb_ctx);
1465 ldb_transaction_cancel(ldb_ctx);
1468 talloc_free(mem_ctx);
1469 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1474 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1479 struct ldb_context *ldb_ctx;
1480 struct ldb_request *req;
1481 PyObject *py_controls = Py_None;
1482 TALLOC_CTX *mem_ctx;
1483 struct ldb_control **parsed_controls;
1484 const char * const kwnames[] = { "dn", "controls", NULL };
1486 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1487 discard_const_p(char *, kwnames),
1488 &py_dn, &py_controls))
1491 mem_ctx = talloc_new(NULL);
1492 if (mem_ctx == NULL) {
1496 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1498 if (py_controls == Py_None) {
1499 parsed_controls = NULL;
1501 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1502 if (controls == NULL) {
1503 talloc_free(mem_ctx);
1506 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1507 talloc_free(controls);
1510 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1511 talloc_free(mem_ctx);
1515 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1516 NULL, ldb_op_default_callback, NULL);
1517 if (ret != LDB_SUCCESS) {
1518 PyErr_SetString(PyExc_TypeError, "failed to build request");
1519 talloc_free(mem_ctx);
1523 /* do request and autostart a transaction */
1524 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1526 ret = ldb_transaction_start(ldb_ctx);
1527 if (ret != LDB_SUCCESS) {
1528 talloc_free(mem_ctx);
1529 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1533 ret = ldb_request(ldb_ctx, req);
1534 if (ret == LDB_SUCCESS) {
1535 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1538 if (ret == LDB_SUCCESS) {
1539 ret = ldb_transaction_commit(ldb_ctx);
1541 ldb_transaction_cancel(ldb_ctx);
1544 talloc_free(mem_ctx);
1545 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1550 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1552 PyObject *py_dn1, *py_dn2;
1553 struct ldb_dn *dn1, *dn2;
1555 TALLOC_CTX *mem_ctx;
1556 PyObject *py_controls = Py_None;
1557 struct ldb_control **parsed_controls;
1558 struct ldb_context *ldb_ctx;
1559 struct ldb_request *req;
1560 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1562 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1564 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1565 discard_const_p(char *, kwnames),
1566 &py_dn1, &py_dn2, &py_controls))
1570 mem_ctx = talloc_new(NULL);
1571 if (mem_ctx == NULL) {
1576 if (py_controls == Py_None) {
1577 parsed_controls = NULL;
1579 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1580 if (controls == NULL) {
1581 talloc_free(mem_ctx);
1584 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1585 talloc_free(controls);
1589 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1590 talloc_free(mem_ctx);
1594 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1595 talloc_free(mem_ctx);
1599 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1600 NULL, ldb_op_default_callback, NULL);
1601 if (ret != LDB_SUCCESS) {
1602 PyErr_SetString(PyExc_TypeError, "failed to build request");
1603 talloc_free(mem_ctx);
1607 /* do request and autostart a transaction */
1608 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1610 ret = ldb_transaction_start(ldb_ctx);
1611 if (ret != LDB_SUCCESS) {
1612 talloc_free(mem_ctx);
1613 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1617 ret = ldb_request(ldb_ctx, req);
1618 if (ret == LDB_SUCCESS) {
1619 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1622 if (ret == LDB_SUCCESS) {
1623 ret = ldb_transaction_commit(ldb_ctx);
1625 ldb_transaction_cancel(ldb_ctx);
1628 talloc_free(mem_ctx);
1629 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1634 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1637 if (!PyArg_ParseTuple(args, "s", &name))
1640 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1645 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1647 char *attribute, *syntax;
1650 struct ldb_context *ldb_ctx;
1652 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1655 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1656 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1658 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1663 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1668 /* We don't want this attached to the 'ldb' any more */
1669 return Py_BuildValue(discard_const_p(char, "(iO)"),
1671 PyLdbMessage_FromMessage(ldif->msg));
1676 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1680 struct ldb_ldif ldif;
1683 TALLOC_CTX *mem_ctx;
1685 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1688 if (!PyLdbMessage_Check(py_msg)) {
1689 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1693 ldif.msg = pyldb_Message_AsMessage(py_msg);
1694 ldif.changetype = changetype;
1696 mem_ctx = talloc_new(NULL);
1698 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1700 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1704 ret = PyStr_FromString(string);
1706 talloc_free(mem_ctx);
1711 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1713 PyObject *list, *ret;
1714 struct ldb_ldif *ldif;
1716 struct ldb_dn *last_dn = NULL;
1718 TALLOC_CTX *mem_ctx;
1720 if (!PyArg_ParseTuple(args, "s", &s))
1723 mem_ctx = talloc_new(NULL);
1728 list = PyList_New(0);
1729 while (s && *s != '\0') {
1730 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1731 talloc_steal(mem_ctx, ldif);
1733 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1734 last_dn = ldif->msg->dn;
1736 const char *last_dn_str = NULL;
1737 const char *err_string = NULL;
1738 if (last_dn == NULL) {
1739 PyErr_SetString(PyExc_ValueError,
1740 "unable to parse LDIF "
1741 "string at first chunk");
1742 talloc_free(mem_ctx);
1747 = ldb_dn_get_linearized(last_dn);
1750 = talloc_asprintf(mem_ctx,
1751 "unable to parse ldif "
1755 PyErr_SetString(PyExc_ValueError,
1757 talloc_free(mem_ctx);
1761 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1762 ret = PyObject_GetIter(list);
1767 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1770 PyObject *py_msg_old;
1771 PyObject *py_msg_new;
1772 struct ldb_message *diff;
1773 struct ldb_context *ldb;
1776 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1779 if (!PyLdbMessage_Check(py_msg_old)) {
1780 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1784 if (!PyLdbMessage_Check(py_msg_new)) {
1785 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1789 ldb = pyldb_Ldb_AsLdbContext(self);
1790 ldb_ret = ldb_msg_difference(ldb, ldb,
1791 pyldb_Message_AsMessage(py_msg_old),
1792 pyldb_Message_AsMessage(py_msg_new),
1794 if (ldb_ret != LDB_SUCCESS) {
1795 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1799 py_ret = PyLdbMessage_FromMessage(diff);
1801 talloc_unlink(ldb, diff);
1806 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1808 const struct ldb_schema_attribute *a;
1809 struct ldb_val old_val;
1810 struct ldb_val new_val;
1811 TALLOC_CTX *mem_ctx;
1818 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1821 result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1822 old_val.length = size;
1825 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1829 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1835 mem_ctx = talloc_new(NULL);
1836 if (mem_ctx == NULL) {
1841 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1842 talloc_free(mem_ctx);
1846 ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1848 talloc_free(mem_ctx);
1853 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1855 PyObject *py_base = Py_None;
1856 int scope = LDB_SCOPE_DEFAULT;
1858 PyObject *py_attrs = Py_None;
1859 PyObject *py_controls = Py_None;
1860 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1862 struct ldb_result *res;
1863 struct ldb_request *req;
1865 struct ldb_context *ldb_ctx;
1866 struct ldb_control **parsed_controls;
1867 struct ldb_dn *base;
1869 TALLOC_CTX *mem_ctx;
1871 /* type "int" rather than "enum" for "scope" is intentional */
1872 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1873 discard_const_p(char *, kwnames),
1874 &py_base, &scope, &expr, &py_attrs, &py_controls))
1878 mem_ctx = talloc_new(NULL);
1879 if (mem_ctx == NULL) {
1883 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1885 if (py_attrs == Py_None) {
1888 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1889 if (attrs == NULL) {
1890 talloc_free(mem_ctx);
1895 if (py_base == Py_None) {
1896 base = ldb_get_default_basedn(ldb_ctx);
1898 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1899 talloc_free(mem_ctx);
1904 if (py_controls == Py_None) {
1905 parsed_controls = NULL;
1907 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1908 if (controls == NULL) {
1909 talloc_free(mem_ctx);
1912 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1913 talloc_free(controls);
1916 res = talloc_zero(mem_ctx, struct ldb_result);
1919 talloc_free(mem_ctx);
1923 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1930 ldb_search_default_callback,
1933 if (ret != LDB_SUCCESS) {
1934 talloc_free(mem_ctx);
1935 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1939 talloc_steal(req, attrs);
1941 ret = ldb_request(ldb_ctx, req);
1943 if (ret == LDB_SUCCESS) {
1944 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1947 if (ret != LDB_SUCCESS) {
1948 talloc_free(mem_ctx);
1949 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1953 py_ret = PyLdbResult_FromResult(res);
1955 talloc_free(mem_ctx);
1960 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
1962 if (reply->py_iter != NULL) {
1963 DLIST_REMOVE(reply->py_iter->state.next, reply);
1964 if (reply->py_iter->state.result == reply) {
1965 reply->py_iter->state.result = NULL;
1967 reply->py_iter = NULL;
1970 if (reply->obj != NULL) {
1971 Py_DECREF(reply->obj);
1978 static int py_ldb_search_iterator_callback(struct ldb_request *req,
1979 struct ldb_reply *ares)
1981 PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
1982 struct ldb_result result = { .msgs = NULL };
1983 struct py_ldb_search_iterator_reply *reply = NULL;
1986 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1989 if (ares->error != LDB_SUCCESS) {
1990 int ret = ares->error;
1992 return ldb_request_done(req, ret);
1995 reply = talloc_zero(py_iter->mem_ctx,
1996 struct py_ldb_search_iterator_reply);
1997 if (reply == NULL) {
1999 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2001 reply->py_iter = py_iter;
2002 talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
2004 switch (ares->type) {
2005 case LDB_REPLY_ENTRY:
2006 reply->obj = PyLdbMessage_FromMessage(ares->message);
2007 if (reply->obj == NULL) {
2009 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2011 DLIST_ADD_END(py_iter->state.next, reply);
2015 case LDB_REPLY_REFERRAL:
2016 reply->obj = PyStr_FromString(ares->referral);
2017 if (reply->obj == NULL) {
2019 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2021 DLIST_ADD_END(py_iter->state.next, reply);
2025 case LDB_REPLY_DONE:
2026 result = (struct ldb_result) { .controls = ares->controls };
2027 reply->obj = PyLdbResult_FromResult(&result);
2028 if (reply->obj == NULL) {
2030 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2032 py_iter->state.result = reply;
2034 return ldb_request_done(req, LDB_SUCCESS);
2038 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2041 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2043 PyObject *py_base = Py_None;
2044 int scope = LDB_SCOPE_DEFAULT;
2047 PyObject *py_attrs = Py_None;
2048 PyObject *py_controls = Py_None;
2049 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
2052 struct ldb_context *ldb_ctx;
2053 struct ldb_control **parsed_controls;
2054 struct ldb_dn *base;
2055 PyLdbSearchIteratorObject *py_iter;
2057 /* type "int" rather than "enum" for "scope" is intentional */
2058 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
2059 discard_const_p(char *, kwnames),
2060 &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
2063 py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
2064 if (py_iter == NULL) {
2068 py_iter->ldb = self;
2070 ZERO_STRUCT(py_iter->state);
2071 py_iter->mem_ctx = talloc_new(NULL);
2072 if (py_iter->mem_ctx == NULL) {
2078 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2080 if (py_attrs == Py_None) {
2083 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2084 if (attrs == NULL) {
2091 if (py_base == Py_None) {
2092 base = ldb_get_default_basedn(ldb_ctx);
2094 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2101 if (py_controls == Py_None) {
2102 parsed_controls = NULL;
2104 const char **controls = NULL;
2106 controls = PyList_AsStrList(py_iter->mem_ctx,
2107 py_controls, "controls");
2108 if (controls == NULL) {
2114 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2117 if (controls[0] != NULL && parsed_controls == NULL) {
2122 talloc_free(controls);
2125 ret = ldb_build_search_req(&py_iter->state.req,
2134 py_ldb_search_iterator_callback,
2136 if (ret != LDB_SUCCESS) {
2138 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2142 ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2144 ret = ldb_request(ldb_ctx, py_iter->state.req);
2145 if (ret != LDB_SUCCESS) {
2147 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2151 return (PyObject *)py_iter;
2154 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2159 if (!PyArg_ParseTuple(args, "s", &name))
2162 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
2167 /* FIXME: More interpretation */
2172 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2177 if (!PyArg_ParseTuple(args, "sO", &name, &data))
2180 /* FIXME: More interpretation */
2182 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
2187 static PyObject *py_ldb_modules(PyLdbObject *self)
2189 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2190 PyObject *ret = PyList_New(0);
2191 struct ldb_module *mod;
2193 for (mod = ldb->modules; mod; mod = mod->next) {
2194 PyList_Append(ret, PyLdbModule_FromModule(mod));
2200 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2202 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2206 if (!PyArg_ParseTuple(args, "i", &type))
2209 /* FIXME: More interpretation */
2211 ret = ldb_sequence_number(ldb, type, &value);
2213 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2215 return PyLong_FromLongLong(value);
2219 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2221 .read_fn = ldb_handler_copy,
2222 .write_clear_fn = ldb_handler_copy,
2223 .write_hex_fn = ldb_handler_copy,
2226 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self)
2228 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2231 ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2233 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2239 static PyMethodDef py_ldb_methods[] = {
2240 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
2241 "S.set_debug(callback) -> None\n"
2242 "Set callback for LDB debug messages.\n"
2243 "The callback should accept a debug level and debug text." },
2244 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
2245 "S.set_create_perms(mode) -> None\n"
2246 "Set mode to use when creating new LDB files." },
2247 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2248 "S.set_modules_dir(path) -> None\n"
2249 "Set path LDB should search for modules" },
2250 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
2251 "S.transaction_start() -> None\n"
2252 "Start a new transaction." },
2253 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2254 "S.transaction_prepare_commit() -> None\n"
2255 "prepare to commit a new transaction (2-stage commit)." },
2256 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
2257 "S.transaction_commit() -> None\n"
2258 "commit a new transaction." },
2259 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
2260 "S.transaction_cancel() -> None\n"
2261 "cancel a new transaction." },
2262 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
2264 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2266 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2268 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2270 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2272 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
2273 "S.connect(url, flags=0, options=None) -> None\n"
2274 "Connect to a LDB URL." },
2275 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
2276 "S.modify(message, controls=None, validate=False) -> None\n"
2277 "Modify an entry." },
2278 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
2279 "S.add(message, controls=None) -> None\n"
2281 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
2282 "S.delete(dn, controls=None) -> None\n"
2283 "Remove an entry." },
2284 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
2285 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2286 "Rename an entry." },
2287 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
2288 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2289 "Search in a database.\n"
2291 ":param base: Optional base DN to search\n"
2292 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2293 ":param expression: Optional search expression\n"
2294 ":param attrs: Attributes to return (defaults to all)\n"
2295 ":param controls: Optional list of controls\n"
2296 ":return: ldb.Result object\n"
2298 { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS,
2299 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2300 "Search in a database.\n"
2302 ":param base: Optional base DN to search\n"
2303 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2304 ":param expression: Optional search expression\n"
2305 ":param attrs: Attributes to return (defaults to all)\n"
2306 ":param controls: Optional list of controls\n"
2307 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2308 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2310 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2312 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2314 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2316 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2317 "S.parse_ldif(ldif) -> iter(messages)\n"
2318 "Parse a string formatted using LDIF." },
2319 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2320 "S.write_ldif(message, changetype) -> ldif\n"
2321 "Print the message as a string formatted using LDIF." },
2322 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2323 "S.msg_diff(Message) -> Message\n"
2324 "Return an LDB Message of the difference between two Message objects." },
2325 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2326 "S.get_opaque(name) -> value\n"
2327 "Get an opaque value set on this LDB connection. \n"
2328 ":note: The returned value may not be useful in Python."
2330 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2331 "S.set_opaque(name, value) -> None\n"
2332 "Set an opaque value on this LDB connection. \n"
2333 ":note: Passing incorrect values may cause crashes." },
2334 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2335 "S.modules() -> list\n"
2336 "Return the list of modules on this LDB connection " },
2337 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2338 "S.sequence_number(type) -> value\n"
2339 "Return the value of the sequence according to the requested type" },
2340 { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2341 "S._register_test_extensions() -> None\n"
2342 "Register internal extensions used in testing" },
2346 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2348 PyLdbModuleObject *ret;
2350 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2355 ret->mem_ctx = talloc_new(NULL);
2356 ret->mod = talloc_reference(ret->mem_ctx, mod);
2357 return (PyObject *)ret;
2360 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2362 struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2366 return PyLdbModule_FromModule(mod);
2369 static PyGetSetDef py_ldb_getset[] = {
2370 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
2374 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2376 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2378 struct ldb_result *result;
2382 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2386 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2388 if (ret != LDB_SUCCESS) {
2389 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2393 count = result->count;
2395 talloc_free(result);
2398 PyErr_Format(PyExc_RuntimeError,
2399 "Searching for [%s] dn gave %u results!",
2400 ldb_dn_get_linearized(dn),
2408 static PySequenceMethods py_ldb_seq = {
2409 .sq_contains = (objobjproc)py_ldb_contains,
2412 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2416 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2421 ret->mem_ctx = talloc_new(NULL);
2422 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2423 return (PyObject *)ret;
2426 static void py_ldb_dealloc(PyLdbObject *self)
2428 talloc_free(self->mem_ctx);
2429 Py_TYPE(self)->tp_free(self);
2432 static PyTypeObject PyLdb = {
2433 .tp_name = "ldb.Ldb",
2434 .tp_methods = py_ldb_methods,
2435 .tp_repr = (reprfunc)py_ldb_repr,
2436 .tp_new = py_ldb_new,
2437 .tp_init = (initproc)py_ldb_init,
2438 .tp_dealloc = (destructor)py_ldb_dealloc,
2439 .tp_getset = py_ldb_getset,
2440 .tp_getattro = PyObject_GenericGetAttr,
2441 .tp_basicsize = sizeof(PyLdbObject),
2442 .tp_doc = "Connection to a LDB database.",
2443 .tp_as_sequence = &py_ldb_seq,
2444 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2447 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2449 talloc_free(self->mem_ctx);
2450 Py_DECREF(self->msgs);
2451 Py_DECREF(self->referals);
2452 Py_DECREF(self->controls);
2453 Py_TYPE(self)->tp_free(self);
2456 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2458 Py_INCREF(self->msgs);
2462 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2464 Py_INCREF(self->controls);
2465 return self->controls;
2468 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2470 Py_INCREF(self->referals);
2471 return self->referals;
2474 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2477 if (self->msgs == NULL) {
2478 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2481 size = PyList_Size(self->msgs);
2482 return PyInt_FromLong(size);
2485 static PyGetSetDef py_ldb_result_getset[] = {
2486 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2487 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2488 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2489 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2493 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2495 return PyObject_GetIter(self->msgs);
2498 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2500 return PySequence_Size(self->msgs);
2503 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2505 return PySequence_GetItem(self->msgs, idx);
2508 static PySequenceMethods py_ldb_result_seq = {
2509 .sq_length = (lenfunc)py_ldb_result_len,
2510 .sq_item = (ssizeargfunc)py_ldb_result_find,
2513 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2515 return PyStr_FromString("<ldb result>");
2519 static PyTypeObject PyLdbResult = {
2520 .tp_name = "ldb.Result",
2521 .tp_repr = (reprfunc)py_ldb_result_repr,
2522 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2523 .tp_iter = (getiterfunc)py_ldb_result_iter,
2524 .tp_getset = py_ldb_result_getset,
2525 .tp_getattro = PyObject_GenericGetAttr,
2526 .tp_basicsize = sizeof(PyLdbResultObject),
2527 .tp_as_sequence = &py_ldb_result_seq,
2528 .tp_doc = "LDB result.",
2529 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2532 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2534 Py_XDECREF(self->state.exception);
2535 TALLOC_FREE(self->mem_ctx);
2536 ZERO_STRUCT(self->state);
2537 Py_DECREF(self->ldb);
2538 Py_TYPE(self)->tp_free(self);
2541 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2543 PyObject *py_ret = NULL;
2545 if (self->state.req == NULL) {
2546 PyErr_SetString(PyExc_RuntimeError,
2547 "ldb.SearchIterator request already finished");
2552 * TODO: do we want a non-blocking mode?
2553 * In future we may add an optional 'nonblocking'
2554 * argument to search_iterator().
2556 * For now we keep it simple and wait for at
2560 while (self->state.next == NULL) {
2563 if (self->state.result != NULL) {
2565 * We (already) got a final result from the server.
2567 * We stop the iteration and let
2568 * py_ldb_search_iterator_result() will deliver
2569 * the result details.
2571 TALLOC_FREE(self->state.req);
2572 PyErr_SetNone(PyExc_StopIteration);
2576 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2577 if (ret != LDB_SUCCESS) {
2578 struct ldb_context *ldb_ctx;
2579 TALLOC_FREE(self->state.req);
2580 ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb);
2582 * We stop the iteration and let
2583 * py_ldb_search_iterator_result() will deliver
2586 self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2587 ret, ldb_errstring(ldb_ctx));
2588 PyErr_SetNone(PyExc_StopIteration);
2593 py_ret = self->state.next->obj;
2594 self->state.next->obj = NULL;
2595 /* no TALLOC_FREE() as self->state.next is a list */
2596 talloc_free(self->state.next);
2600 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self)
2602 PyObject *py_ret = NULL;
2604 if (self->state.req != NULL) {
2605 PyErr_SetString(PyExc_RuntimeError,
2606 "ldb.SearchIterator request running");
2610 if (self->state.next != NULL) {
2611 PyErr_SetString(PyExc_RuntimeError,
2612 "ldb.SearchIterator not fully consumed.");
2616 if (self->state.exception != NULL) {
2617 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2618 self->state.exception = NULL;
2622 if (self->state.result == NULL) {
2623 PyErr_SetString(PyExc_RuntimeError,
2624 "ldb.SearchIterator result already consumed");
2628 py_ret = self->state.result->obj;
2629 self->state.result->obj = NULL;
2630 TALLOC_FREE(self->state.result);
2634 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self)
2636 if (self->state.req == NULL) {
2637 PyErr_SetString(PyExc_RuntimeError,
2638 "ldb.SearchIterator request already finished");
2642 Py_XDECREF(self->state.exception);
2643 TALLOC_FREE(self->mem_ctx);
2644 ZERO_STRUCT(self->state);
2648 static PyMethodDef py_ldb_search_iterator_methods[] = {
2649 { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2650 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2651 { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2656 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2658 return PyStr_FromString("<ldb search iterator>");
2661 static PyTypeObject PyLdbSearchIterator = {
2662 .tp_name = "ldb.SearchIterator",
2663 .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2664 .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2665 .tp_iter = PyObject_SelfIter,
2666 .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2667 .tp_methods = py_ldb_search_iterator_methods,
2668 .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2669 .tp_doc = "LDB search_iterator.",
2670 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2673 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2675 return PyStr_FromFormat("<ldb module '%s'>",
2676 pyldb_Module_AsModule(self)->ops->name);
2679 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2681 return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
2684 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2686 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2690 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2692 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2696 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2698 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2702 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2704 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2706 struct ldb_request *req;
2707 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2708 struct ldb_module *mod;
2709 const char * const*attrs;
2711 /* type "int" rather than "enum" for "scope" is intentional */
2712 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2713 discard_const_p(char *, kwnames),
2714 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2719 if (py_attrs == Py_None) {
2722 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2727 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2728 scope, NULL /* expr */, attrs,
2729 NULL /* controls */, NULL, NULL, NULL);
2731 talloc_steal(req, attrs);
2733 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2735 req->op.search.res = NULL;
2737 ret = mod->ops->search(mod, req);
2739 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2741 py_ret = PyLdbResult_FromResult(req->op.search.res);
2749 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2751 struct ldb_request *req;
2752 PyObject *py_message;
2754 struct ldb_module *mod;
2756 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2759 req = talloc_zero(NULL, struct ldb_request);
2760 req->operation = LDB_ADD;
2761 req->op.add.message = pyldb_Message_AsMessage(py_message);
2763 mod = pyldb_Module_AsModule(self);
2764 ret = mod->ops->add(mod, req);
2766 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2771 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2774 struct ldb_request *req;
2775 PyObject *py_message;
2776 struct ldb_module *mod;
2778 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2781 req = talloc_zero(NULL, struct ldb_request);
2782 req->operation = LDB_MODIFY;
2783 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2785 mod = pyldb_Module_AsModule(self);
2786 ret = mod->ops->modify(mod, req);
2788 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2793 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2796 struct ldb_request *req;
2799 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2802 req = talloc_zero(NULL, struct ldb_request);
2803 req->operation = LDB_DELETE;
2804 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2806 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2808 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2813 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2816 struct ldb_request *req;
2817 PyObject *py_dn1, *py_dn2;
2819 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2822 req = talloc_zero(NULL, struct ldb_request);
2824 req->operation = LDB_RENAME;
2825 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2826 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2828 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2830 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2835 static PyMethodDef py_ldb_module_methods[] = {
2836 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2837 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2838 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2839 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2840 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2841 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2842 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2843 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2847 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2849 talloc_free(self->mem_ctx);
2853 static PyTypeObject PyLdbModule = {
2854 .tp_name = "ldb.LdbModule",
2855 .tp_methods = py_ldb_module_methods,
2856 .tp_repr = (reprfunc)py_ldb_module_repr,
2857 .tp_str = (reprfunc)py_ldb_module_str,
2858 .tp_basicsize = sizeof(PyLdbModuleObject),
2859 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2860 .tp_flags = Py_TPFLAGS_DEFAULT,
2861 .tp_doc = "LDB module (extension)",
2866 * Create a ldb_message_element from a Python object.
2868 * This will accept any sequence objects that contains strings, or
2871 * A reference to set_obj will be borrowed.
2873 * @param mem_ctx Memory context
2874 * @param set_obj Python object to convert
2875 * @param flags ldb_message_element flags to set
2876 * @param attr_name Name of the attribute
2877 * @return New ldb_message_element, allocated as child of mem_ctx
2879 static struct ldb_message_element *PyObject_AsMessageElement(
2880 TALLOC_CTX *mem_ctx,
2883 const char *attr_name)
2885 struct ldb_message_element *me;
2886 const char *msg = NULL;
2890 if (pyldb_MessageElement_Check(set_obj)) {
2891 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2892 /* We have to talloc_reference() the memory context, not the pointer
2893 * which may not actually be it's own context */
2894 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2895 return pyldb_MessageElement_AsMessageElement(set_obj);
2900 me = talloc(mem_ctx, struct ldb_message_element);
2906 me->name = talloc_strdup(me, attr_name);
2908 if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) {
2910 me->values = talloc_array(me, struct ldb_val, me->num_values);
2911 if (PyBytes_Check(set_obj)) {
2913 result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
2920 msg = PyStr_AsUTF8AndSize(set_obj, &size);
2926 me->values[0].data = talloc_memdup(me,
2927 (const uint8_t *)msg,
2929 me->values[0].length = size;
2930 } else if (PySequence_Check(set_obj)) {
2932 me->num_values = PySequence_Size(set_obj);
2933 me->values = talloc_array(me, struct ldb_val, me->num_values);
2934 for (i = 0; i < me->num_values; i++) {
2935 PyObject *obj = PySequence_GetItem(set_obj, i);
2936 if (PyBytes_Check(obj)) {
2938 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
2944 } else if (PyUnicode_Check(obj)) {
2945 msg = PyStr_AsUTF8AndSize(obj, &size);
2951 PyErr_Format(PyExc_TypeError,
2952 "Expected string as element %zd in list", i);
2956 me->values[i].data = talloc_memdup(me,
2957 (const uint8_t *)msg,
2959 me->values[i].length = size;
2962 PyErr_Format(PyExc_TypeError,
2963 "String or List type expected for '%s' attribute", attr_name);
2972 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2973 struct ldb_message_element *me)
2978 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2979 result = PyList_New(me->num_values);
2981 for (i = 0; i < me->num_values; i++) {
2982 PyList_SetItem(result, i,
2983 PyObject_FromLdbValue(&me->values[i]));
2989 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2992 if (!PyArg_ParseTuple(args, "I", &i))
2994 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2997 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
3000 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
3002 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3003 return PyInt_FromLong(el->flags);
3006 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
3009 struct ldb_message_element *el;
3010 if (!PyArg_ParseTuple(args, "I", &flags))
3013 el = pyldb_MessageElement_AsMessageElement(self);
3018 static PyMethodDef py_ldb_msg_element_methods[] = {
3019 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
3020 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
3021 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
3025 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
3027 return pyldb_MessageElement_AsMessageElement(self)->num_values;
3030 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
3032 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3033 if (idx < 0 || idx >= el->num_values) {
3034 PyErr_SetString(PyExc_IndexError, "Out of range");
3037 return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
3040 static PySequenceMethods py_ldb_msg_element_seq = {
3041 .sq_length = (lenfunc)py_ldb_msg_element_len,
3042 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
3045 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3048 if (!pyldb_MessageElement_Check(other)) {
3049 Py_INCREF(Py_NotImplemented);
3050 return Py_NotImplemented;
3052 ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3053 pyldb_MessageElement_AsMessageElement(other));
3054 return richcmp(ret, op);
3057 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3059 PyObject *el = ldb_msg_element_to_set(NULL,
3060 pyldb_MessageElement_AsMessageElement(self));
3061 PyObject *ret = PyObject_GetIter(el);
3066 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3068 PyLdbMessageElementObject *ret;
3069 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3074 ret->mem_ctx = talloc_new(NULL);
3075 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
3080 return (PyObject *)ret;
3083 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3085 PyObject *py_elements = NULL;
3086 struct ldb_message_element *el;
3087 unsigned int flags = 0;
3089 const char * const kwnames[] = { "elements", "flags", "name", NULL };
3090 PyLdbMessageElementObject *ret;
3091 TALLOC_CTX *mem_ctx;
3092 const char *msg = NULL;
3096 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3097 discard_const_p(char *, kwnames),
3098 &py_elements, &flags, &name))
3101 mem_ctx = talloc_new(NULL);
3102 if (mem_ctx == NULL) {
3107 el = talloc_zero(mem_ctx, struct ldb_message_element);
3110 talloc_free(mem_ctx);
3114 if (py_elements != NULL) {
3116 if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) {
3119 el->values = talloc_array(el, struct ldb_val, 1);
3120 if (el->values == NULL) {
3121 talloc_free(mem_ctx);
3125 if (PyBytes_Check(py_elements)) {
3126 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3129 msg = PyStr_AsUTF8AndSize(py_elements, &size);
3130 result = (msg == NULL) ? -1 : 0;
3133 talloc_free(mem_ctx);
3136 el->values[0].data = talloc_memdup(el->values,
3137 (const uint8_t *)msg, size + 1);
3138 el->values[0].length = size;
3139 } else if (PySequence_Check(py_elements)) {
3140 el->num_values = PySequence_Size(py_elements);
3141 el->values = talloc_array(el, struct ldb_val, el->num_values);
3142 if (el->values == NULL) {
3143 talloc_free(mem_ctx);
3147 for (i = 0; i < el->num_values; i++) {
3148 PyObject *item = PySequence_GetItem(py_elements, i);
3150 talloc_free(mem_ctx);
3153 if (PyBytes_Check(item)) {
3155 result = PyBytes_AsStringAndSize(item, &_msg, &size);
3157 } else if (PyUnicode_Check(item)) {
3158 msg = PyStr_AsUTF8AndSize(item, &size);
3159 result = (msg == NULL) ? -1 : 0;
3161 PyErr_Format(PyExc_TypeError,
3162 "Expected string as element %zd in list", i);
3166 talloc_free(mem_ctx);
3169 el->values[i].data = talloc_memdup(el,
3170 (const uint8_t *)msg, size+1);
3171 el->values[i].length = size;
3174 PyErr_SetString(PyExc_TypeError,
3175 "Expected string or list");
3176 talloc_free(mem_ctx);
3182 el->name = talloc_strdup(el, name);
3184 ret = PyObject_New(PyLdbMessageElementObject, type);
3186 talloc_free(mem_ctx);
3190 ret->mem_ctx = mem_ctx;
3192 return (PyObject *)ret;
3195 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3197 char *element_str = NULL;
3199 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3200 PyObject *ret, *repr;
3202 for (i = 0; i < el->num_values; i++) {
3203 PyObject *o = py_ldb_msg_element_find(self, i);
3204 repr = PyObject_Repr(o);
3205 if (element_str == NULL)
3206 element_str = talloc_strdup(NULL, PyStr_AsUTF8(repr));
3208 element_str = talloc_asprintf_append(element_str, ",%s", PyStr_AsUTF8(repr));
3212 if (element_str != NULL) {
3213 ret = PyStr_FromFormat("MessageElement([%s])", element_str);
3214 talloc_free(element_str);
3216 ret = PyStr_FromString("MessageElement([])");
3222 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3224 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3226 if (el->num_values == 1)
3227 return PyStr_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3232 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3234 talloc_free(self->mem_ctx);
3238 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3240 return wrap_text("MessageElementTextWrapper", self);
3243 static PyGetSetDef py_ldb_msg_element_getset[] = {
3244 { discard_const_p(char, "text"), (getter)py_ldb_msg_element_get_text, NULL, NULL },
3248 static PyTypeObject PyLdbMessageElement = {
3249 .tp_name = "ldb.MessageElement",
3250 .tp_basicsize = sizeof(PyLdbMessageElementObject),
3251 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3252 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3253 .tp_str = (reprfunc)py_ldb_msg_element_str,
3254 .tp_methods = py_ldb_msg_element_methods,
3255 .tp_getset = py_ldb_msg_element_getset,
3256 .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3257 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3258 .tp_as_sequence = &py_ldb_msg_element_seq,
3259 .tp_new = py_ldb_msg_element_new,
3260 .tp_flags = Py_TPFLAGS_DEFAULT,
3261 .tp_doc = "An element of a Message",
3265 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3270 struct ldb_message *msg;
3271 struct ldb_context *ldb_ctx;
3272 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3274 if (!PyArg_ParseTuple(args, "O!O!|I",
3275 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3280 if (!PyLdb_Check(py_ldb)) {
3281 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
3285 /* mask only flags we are going to use */
3286 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3288 PyErr_SetString(PyExc_ValueError,
3289 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3290 " expected as mod_flag value");
3294 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
3296 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3301 py_ret = PyLdbMessage_FromMessage(msg);
3303 talloc_unlink(ldb_ctx, msg);
3308 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3311 if (!PyArg_ParseTuple(args, "s", &name))
3314 ldb_msg_remove_attr(self->msg, name);
3319 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
3321 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3322 Py_ssize_t i, j = 0;
3323 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3324 if (msg->dn != NULL) {
3325 PyList_SetItem(obj, j, PyStr_FromString("dn"));
3328 for (i = 0; i < msg->num_elements; i++) {
3329 PyList_SetItem(obj, j, PyStr_FromString(msg->elements[i].name));
3335 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
3337 struct ldb_message_element *el;
3339 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3340 name = PyStr_AsUTF8(py_name);
3342 PyErr_SetNone(PyExc_TypeError);
3345 if (!ldb_attr_cmp(name, "dn"))
3346 return pyldb_Dn_FromDn(msg->dn);
3347 el = ldb_msg_find_element(msg, name);
3351 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3354 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3356 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
3358 PyErr_SetString(PyExc_KeyError, "No such element");
3364 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3366 PyObject *def = NULL;
3367 const char *kwnames[] = { "name", "default", "idx", NULL };
3368 const char *name = NULL;
3370 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3371 struct ldb_message_element *el;
3373 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3374 discard_const_p(char *, kwnames), &name, &def, &idx)) {
3378 if (strcasecmp(name, "dn") == 0) {
3379 return pyldb_Dn_FromDn(msg->dn);
3382 el = ldb_msg_find_element(msg, name);
3384 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3393 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3396 return PyObject_FromLdbValue(&el->values[idx]);
3399 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
3401 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3402 Py_ssize_t i, j = 0;
3403 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3404 if (msg->dn != NULL) {
3405 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
3408 for (i = 0; i < msg->num_elements; i++, j++) {
3409 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3410 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3411 PyList_SetItem(l, j, value);
3416 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
3418 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3420 PyObject *l = PyList_New(msg->num_elements);
3421 for (i = 0; i < msg->num_elements; i++) {
3422 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
3427 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3429 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3430 PyLdbMessageElementObject *py_element;
3432 struct ldb_message_element *el;
3433 struct ldb_message_element *el_new;
3435 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
3438 el = py_element->el;
3440 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3444 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3445 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3447 /* now deep copy all attribute values */
3448 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3449 if (el_new->values == NULL) {
3453 el_new->num_values = el->num_values;
3455 for (i = 0; i < el->num_values; i++) {
3456 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
3457 if (el_new->values[i].data == NULL
3458 && el->values[i].length != 0) {
3467 static PyMethodDef py_ldb_msg_methods[] = {
3468 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
3469 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3470 "Class method to create ldb.Message object from Dictionary.\n"
3471 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3472 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
3473 "S.keys() -> list\n\n"
3474 "Return sequence of all attribute names." },
3475 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
3476 "S.remove(name)\n\n"
3477 "Remove all entries for attributes with the specified name."},
3478 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
3479 "msg.get(name,default=None,idx=None) -> string\n"
3480 "idx is the index into the values array\n"
3481 "if idx is None, then a list is returned\n"
3482 "if idx is not None, then the element with that index is returned\n"
3483 "if you pass the special name 'dn' then the DN object is returned\n"},
3484 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
3485 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
3486 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
3487 "S.add(element)\n\n"
3488 "Add an element to this message." },
3492 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
3494 PyObject *list, *iter;
3496 list = py_ldb_msg_keys(self);
3497 iter = PyObject_GetIter(list);
3502 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
3504 const char *attr_name;
3506 attr_name = PyStr_AsUTF8(name);
3507 if (attr_name == NULL) {
3508 PyErr_SetNone(PyExc_TypeError);
3512 if (value == NULL) {
3514 ldb_msg_remove_attr(self->msg, attr_name);
3517 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
3518 value, 0, attr_name);
3522 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
3523 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
3524 if (ret != LDB_SUCCESS) {
3525 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
3532 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
3534 return pyldb_Message_AsMessage(self)->num_elements;
3537 static PyMappingMethods py_ldb_msg_mapping = {
3538 .mp_length = (lenfunc)py_ldb_msg_length,
3539 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
3540 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
3543 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3545 const char * const kwnames[] = { "dn", NULL };
3546 struct ldb_message *ret;
3547 TALLOC_CTX *mem_ctx;
3548 PyObject *pydn = NULL;
3549 PyLdbMessageObject *py_ret;
3551 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
3552 discard_const_p(char *, kwnames),
3556 mem_ctx = talloc_new(NULL);
3557 if (mem_ctx == NULL) {
3562 ret = ldb_msg_new(mem_ctx);
3564 talloc_free(mem_ctx);
3571 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
3572 talloc_free(mem_ctx);
3575 ret->dn = talloc_reference(ret, dn);
3578 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
3579 if (py_ret == NULL) {
3581 talloc_free(mem_ctx);
3585 py_ret->mem_ctx = mem_ctx;
3587 return (PyObject *)py_ret;
3590 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
3592 PyLdbMessageObject *ret;
3594 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3599 ret->mem_ctx = talloc_new(NULL);
3600 ret->msg = talloc_reference(ret->mem_ctx, msg);
3601 return (PyObject *)ret;
3604 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3606 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3607 return pyldb_Dn_FromDn(msg->dn);
3610 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3612 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3613 if (!pyldb_Dn_Check(value)) {
3614 PyErr_SetString(PyExc_TypeError, "expected dn");
3618 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3622 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
3624 return wrap_text("MessageTextWrapper", self);
3627 static PyGetSetDef py_ldb_msg_getset[] = {
3628 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
3629 { discard_const_p(char, "text"), (getter)py_ldb_msg_get_text, NULL, NULL },
3633 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3635 PyObject *dict = PyDict_New(), *ret, *repr;
3636 if (PyDict_Update(dict, (PyObject *)self) != 0)
3638 repr = PyObject_Repr(dict);
3643 ret = PyStr_FromFormat("Message(%s)", PyStr_AsUTF8(repr));
3649 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3651 talloc_free(self->mem_ctx);
3655 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3656 PyLdbMessageObject *py_msg2, int op)
3658 struct ldb_message *msg1, *msg2;
3662 if (!PyLdbMessage_Check(py_msg2)) {
3663 Py_INCREF(Py_NotImplemented);
3664 return Py_NotImplemented;
3667 msg1 = pyldb_Message_AsMessage(py_msg1),
3668 msg2 = pyldb_Message_AsMessage(py_msg2);
3670 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3671 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3673 return richcmp(ret, op);
3677 ret = msg1->num_elements - msg2->num_elements;
3679 return richcmp(ret, op);
3682 for (i = 0; i < msg1->num_elements; i++) {
3683 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3684 &msg2->elements[i]);
3686 return richcmp(ret, op);
3689 ret = ldb_msg_element_compare(&msg1->elements[i],
3690 &msg2->elements[i]);
3692 return richcmp(ret, op);
3696 return richcmp(0, op);
3699 static PyTypeObject PyLdbMessage = {
3700 .tp_name = "ldb.Message",
3701 .tp_methods = py_ldb_msg_methods,
3702 .tp_getset = py_ldb_msg_getset,
3703 .tp_as_mapping = &py_ldb_msg_mapping,
3704 .tp_basicsize = sizeof(PyLdbMessageObject),
3705 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3706 .tp_new = py_ldb_msg_new,
3707 .tp_repr = (reprfunc)py_ldb_msg_repr,
3708 .tp_flags = Py_TPFLAGS_DEFAULT,
3709 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3710 .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3711 .tp_doc = "A LDB Message",
3714 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3716 PyLdbTreeObject *ret;
3718 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3724 ret->mem_ctx = talloc_new(NULL);
3725 ret->tree = talloc_reference(ret->mem_ctx, tree);
3726 return (PyObject *)ret;
3729 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3731 talloc_free(self->mem_ctx);
3735 static PyTypeObject PyLdbTree = {
3736 .tp_name = "ldb.Tree",
3737 .tp_basicsize = sizeof(PyLdbTreeObject),
3738 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3739 .tp_flags = Py_TPFLAGS_DEFAULT,
3740 .tp_doc = "A search tree",
3744 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3746 PyObject *py_ldb = (PyObject *)mod->private_data;
3747 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3749 py_base = pyldb_Dn_FromDn(req->op.search.base);
3751 if (py_base == NULL)
3752 return LDB_ERR_OPERATIONS_ERROR;
3754 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3756 if (py_tree == NULL)
3757 return LDB_ERR_OPERATIONS_ERROR;
3759 if (req->op.search.attrs == NULL) {
3763 for (len = 0; req->op.search.attrs[len]; len++);
3764 py_attrs = PyList_New(len);
3765 for (i = 0; i < len; i++)
3766 PyList_SetItem(py_attrs, i, PyStr_FromString(req->op.search.attrs[i]));
3769 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3770 discard_const_p(char, "OiOO"),
3771 py_base, req->op.search.scope, py_tree, py_attrs);
3773 Py_DECREF(py_attrs);
3777 if (py_result == NULL) {
3778 return LDB_ERR_PYTHON_EXCEPTION;
3781 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3782 if (req->op.search.res == NULL) {
3783 return LDB_ERR_PYTHON_EXCEPTION;
3786 Py_DECREF(py_result);
3791 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3793 PyObject *py_ldb = (PyObject *)mod->private_data;
3794 PyObject *py_result, *py_msg;
3796 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3798 if (py_msg == NULL) {
3799 return LDB_ERR_OPERATIONS_ERROR;
3802 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3803 discard_const_p(char, "O"),
3808 if (py_result == NULL) {
3809 return LDB_ERR_PYTHON_EXCEPTION;
3812 Py_DECREF(py_result);
3817 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3819 PyObject *py_ldb = (PyObject *)mod->private_data;
3820 PyObject *py_result, *py_msg;
3822 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3824 if (py_msg == NULL) {
3825 return LDB_ERR_OPERATIONS_ERROR;
3828 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3829 discard_const_p(char, "O"),
3834 if (py_result == NULL) {
3835 return LDB_ERR_PYTHON_EXCEPTION;
3838 Py_DECREF(py_result);
3843 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3845 PyObject *py_ldb = (PyObject *)mod->private_data;
3846 PyObject *py_result, *py_dn;
3848 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3851 return LDB_ERR_OPERATIONS_ERROR;
3853 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3854 discard_const_p(char, "O"),
3857 if (py_result == NULL) {
3858 return LDB_ERR_PYTHON_EXCEPTION;
3861 Py_DECREF(py_result);
3866 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3868 PyObject *py_ldb = (PyObject *)mod->private_data;
3869 PyObject *py_result, *py_olddn, *py_newdn;
3871 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3873 if (py_olddn == NULL)
3874 return LDB_ERR_OPERATIONS_ERROR;
3876 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3878 if (py_newdn == NULL)
3879 return LDB_ERR_OPERATIONS_ERROR;
3881 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3882 discard_const_p(char, "OO"),
3883 py_olddn, py_newdn);
3885 Py_DECREF(py_olddn);
3886 Py_DECREF(py_newdn);
3888 if (py_result == NULL) {
3889 return LDB_ERR_PYTHON_EXCEPTION;
3892 Py_DECREF(py_result);
3897 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3899 PyObject *py_ldb = (PyObject *)mod->private_data;
3900 PyObject *py_result;
3902 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3903 discard_const_p(char, ""));
3905 Py_XDECREF(py_result);
3907 return LDB_ERR_OPERATIONS_ERROR;
3910 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3912 PyObject *py_ldb = (PyObject *)mod->private_data;
3913 PyObject *py_result;
3915 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3916 discard_const_p(char, ""));
3918 Py_XDECREF(py_result);
3920 return LDB_ERR_OPERATIONS_ERROR;
3923 static int py_module_start_transaction(struct ldb_module *mod)
3925 PyObject *py_ldb = (PyObject *)mod->private_data;
3926 PyObject *py_result;
3928 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3929 discard_const_p(char, ""));
3931 if (py_result == NULL) {
3932 return LDB_ERR_PYTHON_EXCEPTION;
3935 Py_DECREF(py_result);
3940 static int py_module_end_transaction(struct ldb_module *mod)
3942 PyObject *py_ldb = (PyObject *)mod->private_data;
3943 PyObject *py_result;
3945 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3946 discard_const_p(char, ""));
3948 if (py_result == NULL) {
3949 return LDB_ERR_PYTHON_EXCEPTION;
3952 Py_DECREF(py_result);
3957 static int py_module_del_transaction(struct ldb_module *mod)
3959 PyObject *py_ldb = (PyObject *)mod->private_data;
3960 PyObject *py_result;
3962 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3963 discard_const_p(char, ""));
3965 if (py_result == NULL) {
3966 return LDB_ERR_PYTHON_EXCEPTION;
3969 Py_DECREF(py_result);
3974 static int py_module_destructor(struct ldb_module *mod)
3976 Py_DECREF((PyObject *)mod->private_data);
3980 static int py_module_init(struct ldb_module *mod)
3982 PyObject *py_class = (PyObject *)mod->ops->private_data;
3983 PyObject *py_result, *py_next, *py_ldb;
3985 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3988 return LDB_ERR_OPERATIONS_ERROR;
3990 py_next = PyLdbModule_FromModule(mod->next);
3992 if (py_next == NULL)
3993 return LDB_ERR_OPERATIONS_ERROR;
3995 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3998 if (py_result == NULL) {
3999 return LDB_ERR_PYTHON_EXCEPTION;
4002 mod->private_data = py_result;
4004 talloc_set_destructor(mod, py_module_destructor);
4006 return ldb_next_init(mod);
4009 static PyObject *py_register_module(PyObject *module, PyObject *args)
4012 struct ldb_module_ops *ops;
4015 if (!PyArg_ParseTuple(args, "O", &input))
4018 ops = talloc_zero(NULL, struct ldb_module_ops);
4024 ops->name = talloc_strdup(ops, PyStr_AsUTF8(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
4027 ops->private_data = input;
4028 ops->init_context = py_module_init;
4029 ops->search = py_module_search;
4030 ops->add = py_module_add;
4031 ops->modify = py_module_modify;
4032 ops->del = py_module_del;
4033 ops->rename = py_module_rename;
4034 ops->request = py_module_request;
4035 ops->extended = py_module_extended;
4036 ops->start_transaction = py_module_start_transaction;
4037 ops->end_transaction = py_module_end_transaction;
4038 ops->del_transaction = py_module_del_transaction;
4040 ret = ldb_register_module(ops);
4041 if (ret != LDB_SUCCESS) {
4045 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
4050 static PyObject *py_timestring(PyObject *module, PyObject *args)
4052 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4053 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4057 if (!PyArg_ParseTuple(args, "l", &t_val))
4059 tresult = ldb_timestring(NULL, (time_t) t_val);
4060 ret = PyStr_FromString(tresult);
4061 talloc_free(tresult);
4065 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
4068 if (!PyArg_ParseTuple(args, "s", &str))
4071 return PyInt_FromLong(ldb_string_to_time(str));
4074 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4077 if (!PyArg_ParseTuple(args, "s", &name))
4079 return PyBool_FromLong(ldb_valid_attr_name(name));
4083 encode a string using RFC2254 rules
4085 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4087 char *str, *encoded;
4088 Py_ssize_t size = 0;
4092 if (!PyArg_ParseTuple(args, "s#", &str, &size))
4094 val.data = (uint8_t *)str;
4097 encoded = ldb_binary_encode(NULL, val);
4098 if (encoded == NULL) {
4099 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4102 ret = PyStr_FromString(encoded);
4103 talloc_free(encoded);
4108 decode a string using RFC2254 rules
4110 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4116 if (!PyArg_ParseTuple(args, "s", &str))
4119 val = ldb_binary_decode(NULL, str);
4120 if (val.data == NULL) {
4121 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4124 ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4125 talloc_free(val.data);
4129 static PyMethodDef py_ldb_global_methods[] = {
4130 { "register_module", py_register_module, METH_VARARGS,
4131 "S.register_module(module) -> None\n\n"
4132 "Register a LDB module."},
4133 { "timestring", py_timestring, METH_VARARGS,
4134 "S.timestring(int) -> string\n\n"
4135 "Generate a LDAP time string from a UNIX timestamp" },
4136 { "string_to_time", py_string_to_time, METH_VARARGS,
4137 "S.string_to_time(string) -> int\n\n"
4138 "Parse a LDAP time string into a UNIX timestamp." },
4139 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4140 "S.valid_attr_name(name) -> bool\n\nn"
4141 "Check whether the supplied name is a valid attribute name." },
4142 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
4143 "S.open() -> Ldb\n\n"
4144 "Open a new LDB context." },
4145 { "binary_encode", py_binary_encode, METH_VARARGS,
4146 "S.binary_encode(string) -> string\n\n"
4147 "Perform a RFC2254 binary encoding on a string" },
4148 { "binary_decode", py_binary_decode, METH_VARARGS,
4149 "S.binary_decode(string) -> string\n\n"
4150 "Perform a RFC2254 binary decode on a string" },
4154 #define MODULE_DOC "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server."
4156 #if PY_MAJOR_VERSION >= 3
4157 static struct PyModuleDef moduledef = {
4158 PyModuleDef_HEAD_INIT,
4160 .m_doc = MODULE_DOC,
4162 .m_methods = py_ldb_global_methods,
4166 static PyObject* module_init(void)
4170 PyLdbBytesType.tp_base = &PyBytes_Type;
4171 if (PyType_Ready(&PyLdbBytesType) < 0) {
4175 if (PyType_Ready(&PyLdbDn) < 0)
4178 if (PyType_Ready(&PyLdbMessage) < 0)
4181 if (PyType_Ready(&PyLdbMessageElement) < 0)
4184 if (PyType_Ready(&PyLdb) < 0)
4187 if (PyType_Ready(&PyLdbModule) < 0)
4190 if (PyType_Ready(&PyLdbTree) < 0)
4193 if (PyType_Ready(&PyLdbResult) < 0)
4196 if (PyType_Ready(&PyLdbSearchIterator) < 0)
4199 if (PyType_Ready(&PyLdbControl) < 0)
4202 #if PY_MAJOR_VERSION >= 3
4203 m = PyModule_Create(&moduledef);
4205 m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC);
4210 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4212 ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4213 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4214 ADD_LDB_INT(SEQ_NEXT);
4215 ADD_LDB_INT(SCOPE_DEFAULT);
4216 ADD_LDB_INT(SCOPE_BASE);
4217 ADD_LDB_INT(SCOPE_ONELEVEL);
4218 ADD_LDB_INT(SCOPE_SUBTREE);
4220 ADD_LDB_INT(CHANGETYPE_NONE);
4221 ADD_LDB_INT(CHANGETYPE_ADD);
4222 ADD_LDB_INT(CHANGETYPE_DELETE);
4223 ADD_LDB_INT(CHANGETYPE_MODIFY);
4225 ADD_LDB_INT(FLAG_MOD_ADD);
4226 ADD_LDB_INT(FLAG_MOD_REPLACE);
4227 ADD_LDB_INT(FLAG_MOD_DELETE);
4229 ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4230 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4231 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4232 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4234 ADD_LDB_INT(SUCCESS);
4235 ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4236 ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4237 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4238 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4239 ADD_LDB_INT(ERR_COMPARE_FALSE);
4240 ADD_LDB_INT(ERR_COMPARE_TRUE);
4241 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4242 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4243 ADD_LDB_INT(ERR_REFERRAL);
4244 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4245 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4246 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4247 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4248 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4249 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4250 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4251 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4252 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4253 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4254 ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4255 ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4256 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4257 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4258 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4259 ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4260 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4261 ADD_LDB_INT(ERR_BUSY);
4262 ADD_LDB_INT(ERR_UNAVAILABLE);
4263 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4264 ADD_LDB_INT(ERR_LOOP_DETECT);
4265 ADD_LDB_INT(ERR_NAMING_VIOLATION);
4266 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4267 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4268 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4269 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4270 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4271 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4272 ADD_LDB_INT(ERR_OTHER);
4274 ADD_LDB_INT(FLG_RDONLY);
4275 ADD_LDB_INT(FLG_NOSYNC);
4276 ADD_LDB_INT(FLG_RECONNECT);
4277 ADD_LDB_INT(FLG_NOMMAP);
4278 ADD_LDB_INT(FLG_SHOW_BINARY);
4279 ADD_LDB_INT(FLG_ENABLE_TRACING);
4280 ADD_LDB_INT(FLG_DONT_CREATE_DB);
4283 /* Historical misspelling */
4284 PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
4286 PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
4288 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
4289 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
4292 Py_INCREF(&PyLdbDn);
4293 Py_INCREF(&PyLdbModule);
4294 Py_INCREF(&PyLdbMessage);
4295 Py_INCREF(&PyLdbMessageElement);
4296 Py_INCREF(&PyLdbTree);
4297 Py_INCREF(&PyLdbResult);
4298 Py_INCREF(&PyLdbControl);
4300 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
4301 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
4302 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
4303 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
4304 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
4305 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
4306 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
4308 PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
4310 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4312 ADD_LDB_STRING(SYNTAX_DN);
4313 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
4314 ADD_LDB_STRING(SYNTAX_INTEGER);
4315 ADD_LDB_STRING(SYNTAX_BOOLEAN);
4316 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
4317 ADD_LDB_STRING(SYNTAX_UTC_TIME);
4318 ADD_LDB_STRING(OID_COMPARATOR_AND);
4319 ADD_LDB_STRING(OID_COMPARATOR_OR);
4324 #if PY_MAJOR_VERSION >= 3
4325 PyMODINIT_FUNC PyInit_ldb(void);
4326 PyMODINIT_FUNC PyInit_ldb(void)
4328 return module_init();