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[] = {
264 .name = discard_const_p(char, "oid"),
265 .get = (getter)py_ldb_control_get_oid,
268 .name = discard_const_p(char, "critical"),
269 .get = (getter)py_ldb_control_get_critical,
270 .set = (setter)py_ldb_control_set_critical,
275 static PyTypeObject PyLdbControl = {
276 .tp_name = "ldb.control",
277 .tp_dealloc = (destructor)py_ldb_control_dealloc,
278 .tp_getattro = PyObject_GenericGetAttr,
279 .tp_basicsize = sizeof(PyLdbControlObject),
280 .tp_getset = py_ldb_control_getset,
281 .tp_doc = "LDB control.",
282 .tp_str = (reprfunc)py_ldb_control_str,
283 .tp_new = py_ldb_control_new,
284 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
287 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
289 if (ret == LDB_ERR_PYTHON_EXCEPTION)
290 return; /* Python exception should already be set, just keep that */
292 PyErr_SetObject(error,
293 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
294 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
296 static PyObject *py_ldb_bytes_str(PyBytesObject *self)
301 if (!PyBytes_Check(self)) {
302 PyErr_Format(PyExc_TypeError,"Unexpected type");
305 result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size);
307 PyErr_Format(PyExc_TypeError, "Failed to extract bytes");
310 return PyUnicode_FromStringAndSize(msg, size);
313 static PyTypeObject PyLdbBytesType = {
314 PyVarObject_HEAD_INIT(NULL, 0)
315 .tp_name = "ldb.bytes",
316 .tp_doc = "str/bytes (with custom str)",
317 .tp_str = (reprfunc)py_ldb_bytes_str,
318 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
321 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
323 return PyLdbBytes_FromStringAndSize((const char *)val->data, val->length);
326 static PyObject *PyStr_FromLdbValue(const struct ldb_val *val)
328 return PyStr_FromStringAndSize((const char *)val->data, val->length);
332 * Create a Python object from a ldb_result.
334 * @param result LDB result to convert
335 * @return Python object with converted result (a list object)
337 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
339 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
340 PyLdbControlObject *ctrl;
341 if (ctl_ctx == NULL) {
346 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
348 talloc_free(ctl_ctx);
352 ctrl->mem_ctx = ctl_ctx;
353 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
354 if (ctrl->data == NULL) {
359 return (PyObject*) ctrl;
363 * Create a Python object from a ldb_result.
365 * @param result LDB result to convert
366 * @return Python object with converted result (a list object)
368 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
370 PyLdbResultObject *ret;
371 PyObject *list, *controls, *referals;
374 if (result == NULL) {
378 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
384 list = PyList_New(result->count);
391 for (i = 0; i < result->count; i++) {
392 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
395 ret->mem_ctx = talloc_new(NULL);
396 if (ret->mem_ctx == NULL) {
405 if (result->controls) {
407 while (result->controls[i]) {
410 controls = PyList_New(i);
411 if (controls == NULL) {
416 for (i=0; result->controls[i]; i++) {
417 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
424 PyList_SetItem(controls, i, ctrl);
428 * No controls so we keep an empty list
430 controls = PyList_New(0);
431 if (controls == NULL) {
438 ret->controls = controls;
442 while (result->refs && result->refs[i]) {
446 referals = PyList_New(i);
447 if (referals == NULL) {
453 for (i = 0;result->refs && result->refs[i]; i++) {
454 PyList_SetItem(referals, i, PyStr_FromString(result->refs[i]));
456 ret->referals = referals;
457 return (PyObject *)ret;
461 * Create a LDB Result from a Python object.
462 * If conversion fails, NULL will be returned and a Python exception set.
464 * Note: the result object only includes the messages at the moment; extended
465 * result, controls and referrals are ignored.
467 * @param mem_ctx Memory context in which to allocate the LDB Result
468 * @param obj Python object to convert
469 * @return a ldb_result, or NULL if the conversion failed
471 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
474 struct ldb_result *res;
480 res = talloc_zero(mem_ctx, struct ldb_result);
481 res->count = PyList_Size(obj);
482 res->msgs = talloc_array(res, struct ldb_message *, res->count);
483 for (i = 0; i < res->count; i++) {
484 PyObject *item = PyList_GetItem(obj, i);
485 res->msgs[i] = pyldb_Message_AsMessage(item);
490 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
492 return PyBool_FromLong(ldb_dn_validate(self->dn));
495 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
497 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
500 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
502 return PyBool_FromLong(ldb_dn_is_special(self->dn));
505 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
507 return PyBool_FromLong(ldb_dn_is_null(self->dn));
510 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
512 return PyStr_FromString(ldb_dn_get_casefold(self->dn));
515 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
517 return PyStr_FromString(ldb_dn_get_linearized(self->dn));
520 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
522 return PyStr_FromString(ldb_dn_canonical_string(self->dn, self->dn));
525 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
527 return PyStr_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
530 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
532 const char * const kwnames[] = { "mode", NULL };
534 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
535 discard_const_p(char *, kwnames),
538 return PyStr_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
541 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
544 const struct ldb_val *val;
546 if (!PyArg_ParseTuple(args, "s", &name))
548 val = ldb_dn_get_extended_component(self->dn, name);
553 return PyBytes_FromStringAndSize((const char *)val->data, val->length);
556 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
560 uint8_t *value = NULL;
563 if (!PyArg_ParseTuple(args, "sz#", &name, (char **)&value, &size))
567 err = ldb_dn_set_extended_component(self->dn, name, NULL);
570 val.data = (uint8_t *)value;
572 err = ldb_dn_set_extended_component(self->dn, name, &val);
575 if (err != LDB_SUCCESS) {
576 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
583 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
585 PyObject *str = PyStr_FromString(ldb_dn_get_linearized(self->dn));
586 PyObject *repr, *result;
589 repr = PyObject_Repr(str);
594 result = PyStr_FromFormat("Dn(%s)", PyStr_AsUTF8(repr));
600 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
604 if (!PyArg_ParseTuple(args, "s", &name))
607 return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
610 static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
613 if (!pyldb_Dn_Check(dn2)) {
614 Py_INCREF(Py_NotImplemented);
615 return Py_NotImplemented;
617 ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2));
618 return richcmp(ret, op);
621 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
623 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
624 struct ldb_dn *parent;
625 PyLdbDnObject *py_ret;
626 TALLOC_CTX *mem_ctx = talloc_new(NULL);
628 parent = ldb_dn_get_parent(mem_ctx, dn);
629 if (parent == NULL) {
630 talloc_free(mem_ctx);
634 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
635 if (py_ret == NULL) {
637 talloc_free(mem_ctx);
640 py_ret->mem_ctx = mem_ctx;
642 return (PyObject *)py_ret;
645 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
648 struct ldb_dn *dn, *other;
649 if (!PyArg_ParseTuple(args, "O", &py_other))
652 dn = pyldb_Dn_AsDn((PyObject *)self);
654 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
657 return PyBool_FromLong(ldb_dn_add_child(dn, other));
660 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
663 struct ldb_dn *other, *dn;
664 if (!PyArg_ParseTuple(args, "O", &py_other))
667 dn = pyldb_Dn_AsDn((PyObject *)self);
669 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
672 return PyBool_FromLong(ldb_dn_add_base(dn, other));
675 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
679 if (!PyArg_ParseTuple(args, "i", &i))
682 dn = pyldb_Dn_AsDn((PyObject *)self);
684 return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
687 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
690 struct ldb_dn *dn, *base;
691 if (!PyArg_ParseTuple(args, "O", &py_base))
694 dn = pyldb_Dn_AsDn((PyObject *)self);
696 if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
699 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
702 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
706 unsigned int num = 0;
708 if (!PyArg_ParseTuple(args, "I", &num))
711 dn = pyldb_Dn_AsDn((PyObject *)self);
713 name = ldb_dn_get_component_name(dn, num);
718 return PyStr_FromString(name);
721 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
724 const struct ldb_val *val;
725 unsigned int num = 0;
727 if (!PyArg_ParseTuple(args, "I", &num))
730 dn = pyldb_Dn_AsDn((PyObject *)self);
732 val = ldb_dn_get_component_val(dn, num);
737 return PyStr_FromLdbValue(val);
740 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
742 unsigned int num = 0;
743 char *name = NULL, *value = NULL;
744 struct ldb_val val = { NULL, };
748 if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size))
751 val.data = (unsigned char*) value;
754 err = ldb_dn_set_component(self->dn, num, name, val);
755 if (err != LDB_SUCCESS) {
756 PyErr_SetString(PyExc_TypeError, "Failed to set component");
763 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
768 dn = pyldb_Dn_AsDn((PyObject *)self);
770 name = ldb_dn_get_rdn_name(dn);
775 return PyStr_FromString(name);
778 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
781 const struct ldb_val *val;
783 dn = pyldb_Dn_AsDn((PyObject *)self);
785 val = ldb_dn_get_rdn_val(dn);
790 return PyStr_FromLdbValue(val);
793 static PyMethodDef py_ldb_dn_methods[] = {
794 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
795 "S.validate() -> bool\n"
796 "Validate DN is correct." },
797 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
798 "S.is_valid() -> bool\n" },
799 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
800 "S.is_special() -> bool\n"
801 "Check whether this is a special LDB DN." },
802 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
803 "Check whether this is a null DN." },
804 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
806 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
808 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
809 "S.canonical_str() -> string\n"
810 "Canonical version of this DN (like a posix path)." },
811 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
812 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
813 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
814 "S.canonical_ex_str() -> string\n"
815 "Canonical version of this DN (like a posix path, with terminating newline)." },
816 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
817 "S.extended_str(mode=1) -> string\n"
818 "Extended version of this DN" },
819 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
821 "Get the parent for this DN." },
822 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
823 "S.add_child(dn) -> None\n"
824 "Add a child DN to this DN." },
825 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
826 "S.add_base(dn) -> None\n"
827 "Add a base DN to this DN." },
828 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
829 "S.remove_base_components(int) -> bool\n"
830 "Remove a number of DN components from the base of this DN." },
831 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
832 "S.check_special(name) -> bool\n\n"
833 "Check if name is a special DN name"},
834 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
835 "S.get_extended_component(name) -> string\n\n"
836 "returns a DN extended component as a binary string"},
837 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
838 "S.set_extended_component(name, value) -> None\n\n"
839 "set a DN extended component as a binary string"},
840 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
841 "S.get_component_name(num) -> string\n"
842 "get the attribute name of the specified component" },
843 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
844 "S.get_component_value(num) -> string\n"
845 "get the attribute value of the specified component as a binary string" },
846 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
847 "S.get_component_value(num, name, value) -> None\n"
848 "set the attribute name and value of the specified component" },
849 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
850 "S.get_rdn_name() -> string\n"
851 "get the RDN attribute name" },
852 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
853 "S.get_rdn_value() -> string\n"
854 "get the RDN attribute value as a binary string" },
858 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
860 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
864 copy a DN as a python object
866 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
868 PyLdbDnObject *py_ret;
870 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
871 if (py_ret == NULL) {
875 py_ret->mem_ctx = talloc_new(NULL);
876 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
877 return (PyObject *)py_ret;
880 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
882 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
884 PyLdbDnObject *py_ret;
886 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
889 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
890 if (py_ret == NULL) {
894 py_ret->mem_ctx = talloc_new(NULL);
895 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
896 ldb_dn_add_base(py_ret->dn, other);
897 return (PyObject *)py_ret;
900 static PySequenceMethods py_ldb_dn_seq = {
901 .sq_length = (lenfunc)py_ldb_dn_len,
902 .sq_concat = (binaryfunc)py_ldb_dn_concat,
905 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
907 struct ldb_dn *ret = NULL;
909 PyObject *py_ldb = NULL;
910 struct ldb_context *ldb_ctx = NULL;
911 TALLOC_CTX *mem_ctx = NULL;
912 PyLdbDnObject *py_ret = NULL;
913 const char * const kwnames[] = { "ldb", "dn", NULL };
915 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O"PYARG_STR_UNI,
916 discard_const_p(char *, kwnames),
917 &py_ldb, "utf8", &str))
920 if (!PyLdb_Check(py_ldb)) {
921 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
925 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
927 mem_ctx = talloc_new(NULL);
928 if (mem_ctx == NULL) {
933 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
934 if (!ldb_dn_validate(ret)) {
935 talloc_free(mem_ctx);
936 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
940 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
941 if (py_ret == NULL) {
942 talloc_free(mem_ctx);
946 py_ret->mem_ctx = mem_ctx;
950 PyMem_Free(discard_const_p(char, str));
952 return (PyObject *)py_ret;
955 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
957 talloc_free(self->mem_ctx);
961 static PyTypeObject PyLdbDn = {
963 .tp_methods = py_ldb_dn_methods,
964 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
965 .tp_repr = (reprfunc)py_ldb_dn_repr,
966 .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp,
967 .tp_as_sequence = &py_ldb_dn_seq,
968 .tp_doc = "A LDB distinguished name.",
969 .tp_new = py_ldb_dn_new,
970 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
971 .tp_basicsize = sizeof(PyLdbDnObject),
972 .tp_flags = Py_TPFLAGS_DEFAULT,
976 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
977 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
979 PyObject *fn = (PyObject *)context;
980 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyStr_FromFormatV(fmt, ap));
983 static PyObject *py_ldb_debug_func;
985 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
988 struct ldb_context *ldb_ctx;
990 if (!PyArg_ParseTuple(args, "O", &cb))
993 if (py_ldb_debug_func != NULL) {
994 Py_DECREF(py_ldb_debug_func);
998 /* FIXME: DECREF cb when exiting program */
999 py_ldb_debug_func = cb;
1000 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1001 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
1002 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
1008 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
1011 if (!PyArg_ParseTuple(args, "I", &perms))
1014 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
1019 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
1022 if (!PyArg_ParseTuple(args, "s", &modules_dir))
1025 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
1030 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
1032 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1034 ldb_err = ldb_transaction_start(ldb_ctx);
1035 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1039 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
1041 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1043 ldb_err = ldb_transaction_commit(ldb_ctx);
1044 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1048 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
1050 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1052 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
1053 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1057 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
1059 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1061 ldb_err = ldb_transaction_cancel(ldb_ctx);
1062 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1066 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
1068 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1070 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
1071 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1075 static PyObject *py_ldb_repr(PyLdbObject *self)
1077 return PyStr_FromString("<ldb connection>");
1080 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
1082 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
1085 return py_ldb_dn_copy(dn);
1089 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
1091 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
1094 return py_ldb_dn_copy(dn);
1097 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
1099 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
1102 return py_ldb_dn_copy(dn);
1105 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
1107 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
1110 return py_ldb_dn_copy(dn);
1113 static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
1114 const char *paramname)
1118 if (!PyList_Check(list)) {
1119 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
1122 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1128 for (i = 0; i < PyList_Size(list); i++) {
1129 const char *str = NULL;
1131 PyObject *item = PyList_GetItem(list, i);
1132 if (!(PyStr_Check(item) || PyUnicode_Check(item))) {
1133 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
1137 str = PyStr_AsUTF8AndSize(item, &size);
1142 ret[i] = talloc_strndup(ret, str, size);
1148 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1150 const char * const kwnames[] = { "url", "flags", "options", NULL };
1152 PyObject *py_options = Py_None;
1153 const char **options;
1154 unsigned int flags = 0;
1156 struct ldb_context *ldb;
1158 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1159 discard_const_p(char *, kwnames),
1160 &url, &flags, &py_options))
1163 ldb = pyldb_Ldb_AsLdbContext(self);
1165 if (py_options == Py_None) {
1168 options = PyList_AsStrList(ldb, py_options, "options");
1169 if (options == NULL)
1174 ret = ldb_connect(ldb, url, flags, options);
1175 if (ret != LDB_SUCCESS) {
1176 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1181 talloc_free(options);
1185 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1188 struct ldb_context *ldb;
1189 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1194 ret->mem_ctx = talloc_new(NULL);
1195 ldb = ldb_init(ret->mem_ctx, NULL);
1203 return (PyObject *)ret;
1206 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1209 unsigned int flags = 0;
1210 PyObject *py_options = Py_None;
1212 const char **options;
1213 const char * const kwnames[] = { "url", "flags", "options", NULL };
1214 struct ldb_context *ldb_ctx;
1216 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|IO",
1217 discard_const_p(char *, kwnames),
1218 &url, &flags, &py_options))
1221 if (py_options == Py_None) {
1224 options = PyList_AsStrList(NULL, py_options, "options");
1225 if (options == NULL)
1229 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1230 ret = ldb_connect(ldb_ctx, url, flags, options);
1231 talloc_free(options);
1233 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1238 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1241 PyObject *py_controls = Py_None;
1242 struct ldb_context *ldb_ctx;
1243 struct ldb_request *req;
1244 struct ldb_control **parsed_controls;
1245 struct ldb_message *msg;
1247 TALLOC_CTX *mem_ctx;
1249 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1251 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1252 discard_const_p(char *, kwnames),
1253 &py_msg, &py_controls, &validate))
1256 mem_ctx = talloc_new(NULL);
1257 if (mem_ctx == NULL) {
1261 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1263 if (py_controls == Py_None) {
1264 parsed_controls = NULL;
1266 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1267 if (controls == NULL) {
1268 talloc_free(mem_ctx);
1271 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1272 talloc_free(controls);
1275 if (!PyLdbMessage_Check(py_msg)) {
1276 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1277 talloc_free(mem_ctx);
1280 msg = pyldb_Message_AsMessage(py_msg);
1283 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1284 if (ret != LDB_SUCCESS) {
1285 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1286 talloc_free(mem_ctx);
1291 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1292 NULL, ldb_op_default_callback, NULL);
1293 if (ret != LDB_SUCCESS) {
1294 PyErr_SetString(PyExc_TypeError, "failed to build request");
1295 talloc_free(mem_ctx);
1299 /* do request and autostart a transaction */
1300 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1302 ret = ldb_transaction_start(ldb_ctx);
1303 if (ret != LDB_SUCCESS) {
1304 talloc_free(mem_ctx);
1305 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1309 ret = ldb_request(ldb_ctx, req);
1310 if (ret == LDB_SUCCESS) {
1311 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1314 if (ret == LDB_SUCCESS) {
1315 ret = ldb_transaction_commit(ldb_ctx);
1317 ldb_transaction_cancel(ldb_ctx);
1320 talloc_free(mem_ctx);
1321 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1328 * Obtain a ldb message from a Python Dictionary object.
1330 * @param mem_ctx Memory context
1331 * @param py_obj Python Dictionary object
1332 * @param ldb_ctx LDB context
1333 * @param mod_flags Flags to be set on every message element
1334 * @return ldb_message on success or NULL on failure
1336 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1338 struct ldb_context *ldb_ctx,
1339 unsigned int mod_flags)
1341 struct ldb_message *msg;
1342 unsigned int msg_pos = 0;
1343 Py_ssize_t dict_pos = 0;
1344 PyObject *key, *value;
1345 struct ldb_message_element *msg_el;
1346 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1348 msg = ldb_msg_new(mem_ctx);
1353 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1356 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1357 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1360 if (msg->dn == NULL) {
1361 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1365 PyErr_SetString(PyExc_TypeError, "no dn set");
1369 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1370 const char *key_str = PyStr_AsUTF8(key);
1371 if (ldb_attr_cmp(key_str, "dn") != 0) {
1372 msg_el = PyObject_AsMessageElement(msg->elements, value,
1373 mod_flags, key_str);
1374 if (msg_el == NULL) {
1375 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1378 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1383 msg->num_elements = msg_pos;
1388 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1392 struct ldb_context *ldb_ctx;
1393 struct ldb_request *req;
1394 struct ldb_message *msg = NULL;
1395 PyObject *py_controls = Py_None;
1396 TALLOC_CTX *mem_ctx;
1397 struct ldb_control **parsed_controls;
1398 const char * const kwnames[] = { "message", "controls", NULL };
1400 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1401 discard_const_p(char *, kwnames),
1402 &py_obj, &py_controls))
1405 mem_ctx = talloc_new(NULL);
1406 if (mem_ctx == NULL) {
1410 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1412 if (py_controls == Py_None) {
1413 parsed_controls = NULL;
1415 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1416 if (controls == NULL) {
1417 talloc_free(mem_ctx);
1420 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1421 talloc_free(controls);
1424 if (PyLdbMessage_Check(py_obj)) {
1425 msg = pyldb_Message_AsMessage(py_obj);
1426 } else if (PyDict_Check(py_obj)) {
1427 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1429 PyErr_SetString(PyExc_TypeError,
1430 "Dictionary or LdbMessage object expected!");
1434 /* we should have a PyErr already set */
1435 talloc_free(mem_ctx);
1439 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1440 if (ret != LDB_SUCCESS) {
1441 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1442 talloc_free(mem_ctx);
1446 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1447 NULL, ldb_op_default_callback, NULL);
1448 if (ret != LDB_SUCCESS) {
1449 PyErr_SetString(PyExc_TypeError, "failed to build request");
1450 talloc_free(mem_ctx);
1454 /* do request and autostart a transaction */
1455 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1457 ret = ldb_transaction_start(ldb_ctx);
1458 if (ret != LDB_SUCCESS) {
1459 talloc_free(mem_ctx);
1460 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1464 ret = ldb_request(ldb_ctx, req);
1465 if (ret == LDB_SUCCESS) {
1466 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1469 if (ret == LDB_SUCCESS) {
1470 ret = ldb_transaction_commit(ldb_ctx);
1472 ldb_transaction_cancel(ldb_ctx);
1475 talloc_free(mem_ctx);
1476 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1481 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1486 struct ldb_context *ldb_ctx;
1487 struct ldb_request *req;
1488 PyObject *py_controls = Py_None;
1489 TALLOC_CTX *mem_ctx;
1490 struct ldb_control **parsed_controls;
1491 const char * const kwnames[] = { "dn", "controls", NULL };
1493 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1494 discard_const_p(char *, kwnames),
1495 &py_dn, &py_controls))
1498 mem_ctx = talloc_new(NULL);
1499 if (mem_ctx == NULL) {
1503 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1505 if (py_controls == Py_None) {
1506 parsed_controls = NULL;
1508 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1509 if (controls == NULL) {
1510 talloc_free(mem_ctx);
1513 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1514 talloc_free(controls);
1517 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1518 talloc_free(mem_ctx);
1522 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1523 NULL, ldb_op_default_callback, NULL);
1524 if (ret != LDB_SUCCESS) {
1525 PyErr_SetString(PyExc_TypeError, "failed to build request");
1526 talloc_free(mem_ctx);
1530 /* do request and autostart a transaction */
1531 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1533 ret = ldb_transaction_start(ldb_ctx);
1534 if (ret != LDB_SUCCESS) {
1535 talloc_free(mem_ctx);
1536 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1540 ret = ldb_request(ldb_ctx, req);
1541 if (ret == LDB_SUCCESS) {
1542 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1545 if (ret == LDB_SUCCESS) {
1546 ret = ldb_transaction_commit(ldb_ctx);
1548 ldb_transaction_cancel(ldb_ctx);
1551 talloc_free(mem_ctx);
1552 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1557 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1559 PyObject *py_dn1, *py_dn2;
1560 struct ldb_dn *dn1, *dn2;
1562 TALLOC_CTX *mem_ctx;
1563 PyObject *py_controls = Py_None;
1564 struct ldb_control **parsed_controls;
1565 struct ldb_context *ldb_ctx;
1566 struct ldb_request *req;
1567 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1569 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1571 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1572 discard_const_p(char *, kwnames),
1573 &py_dn1, &py_dn2, &py_controls))
1577 mem_ctx = talloc_new(NULL);
1578 if (mem_ctx == NULL) {
1583 if (py_controls == Py_None) {
1584 parsed_controls = NULL;
1586 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1587 if (controls == NULL) {
1588 talloc_free(mem_ctx);
1591 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1592 talloc_free(controls);
1596 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1597 talloc_free(mem_ctx);
1601 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1602 talloc_free(mem_ctx);
1606 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1607 NULL, ldb_op_default_callback, NULL);
1608 if (ret != LDB_SUCCESS) {
1609 PyErr_SetString(PyExc_TypeError, "failed to build request");
1610 talloc_free(mem_ctx);
1614 /* do request and autostart a transaction */
1615 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1617 ret = ldb_transaction_start(ldb_ctx);
1618 if (ret != LDB_SUCCESS) {
1619 talloc_free(mem_ctx);
1620 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1624 ret = ldb_request(ldb_ctx, req);
1625 if (ret == LDB_SUCCESS) {
1626 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1629 if (ret == LDB_SUCCESS) {
1630 ret = ldb_transaction_commit(ldb_ctx);
1632 ldb_transaction_cancel(ldb_ctx);
1635 talloc_free(mem_ctx);
1636 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1641 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1644 if (!PyArg_ParseTuple(args, "s", &name))
1647 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1652 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1654 char *attribute, *syntax;
1657 struct ldb_context *ldb_ctx;
1659 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1662 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1663 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1665 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1670 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1675 /* We don't want this attached to the 'ldb' any more */
1676 PyObject *obj = PyLdbMessage_FromMessage(ldif->msg);
1678 Py_BuildValue(discard_const_p(char, "(iO)"),
1687 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1691 struct ldb_ldif ldif;
1694 TALLOC_CTX *mem_ctx;
1696 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1699 if (!PyLdbMessage_Check(py_msg)) {
1700 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1704 ldif.msg = pyldb_Message_AsMessage(py_msg);
1705 ldif.changetype = changetype;
1707 mem_ctx = talloc_new(NULL);
1709 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1711 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1715 ret = PyStr_FromString(string);
1717 talloc_free(mem_ctx);
1722 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1724 PyObject *list, *ret;
1725 struct ldb_ldif *ldif;
1727 struct ldb_dn *last_dn = NULL;
1729 TALLOC_CTX *mem_ctx;
1731 if (!PyArg_ParseTuple(args, "s", &s))
1734 mem_ctx = talloc_new(NULL);
1739 list = PyList_New(0);
1740 while (s && *s != '\0') {
1741 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1742 talloc_steal(mem_ctx, ldif);
1744 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1745 last_dn = ldif->msg->dn;
1747 const char *last_dn_str = NULL;
1748 const char *err_string = NULL;
1749 if (last_dn == NULL) {
1750 PyErr_SetString(PyExc_ValueError,
1751 "unable to parse LDIF "
1752 "string at first chunk");
1753 talloc_free(mem_ctx);
1758 = ldb_dn_get_linearized(last_dn);
1761 = talloc_asprintf(mem_ctx,
1762 "unable to parse ldif "
1766 PyErr_SetString(PyExc_ValueError,
1768 talloc_free(mem_ctx);
1772 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1773 ret = PyObject_GetIter(list);
1778 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1781 PyObject *py_msg_old;
1782 PyObject *py_msg_new;
1783 struct ldb_message *diff;
1784 struct ldb_context *ldb;
1787 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1790 if (!PyLdbMessage_Check(py_msg_old)) {
1791 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1795 if (!PyLdbMessage_Check(py_msg_new)) {
1796 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1800 ldb = pyldb_Ldb_AsLdbContext(self);
1801 ldb_ret = ldb_msg_difference(ldb, ldb,
1802 pyldb_Message_AsMessage(py_msg_old),
1803 pyldb_Message_AsMessage(py_msg_new),
1805 if (ldb_ret != LDB_SUCCESS) {
1806 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1810 py_ret = PyLdbMessage_FromMessage(diff);
1812 talloc_unlink(ldb, diff);
1817 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1819 const struct ldb_schema_attribute *a;
1820 struct ldb_val old_val;
1821 struct ldb_val new_val;
1822 TALLOC_CTX *mem_ctx;
1829 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1832 result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1833 old_val.length = size;
1836 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1840 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1846 mem_ctx = talloc_new(NULL);
1847 if (mem_ctx == NULL) {
1852 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1853 talloc_free(mem_ctx);
1857 ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1859 talloc_free(mem_ctx);
1864 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1866 PyObject *py_base = Py_None;
1867 int scope = LDB_SCOPE_DEFAULT;
1869 PyObject *py_attrs = Py_None;
1870 PyObject *py_controls = Py_None;
1871 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1873 struct ldb_result *res;
1874 struct ldb_request *req;
1876 struct ldb_context *ldb_ctx;
1877 struct ldb_control **parsed_controls;
1878 struct ldb_dn *base;
1880 TALLOC_CTX *mem_ctx;
1882 /* type "int" rather than "enum" for "scope" is intentional */
1883 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1884 discard_const_p(char *, kwnames),
1885 &py_base, &scope, &expr, &py_attrs, &py_controls))
1889 mem_ctx = talloc_new(NULL);
1890 if (mem_ctx == NULL) {
1894 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1896 if (py_attrs == Py_None) {
1899 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1900 if (attrs == NULL) {
1901 talloc_free(mem_ctx);
1906 if (py_base == Py_None) {
1907 base = ldb_get_default_basedn(ldb_ctx);
1909 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1910 talloc_free(mem_ctx);
1915 if (py_controls == Py_None) {
1916 parsed_controls = NULL;
1918 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1919 if (controls == NULL) {
1920 talloc_free(mem_ctx);
1923 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1924 talloc_free(controls);
1927 res = talloc_zero(mem_ctx, struct ldb_result);
1930 talloc_free(mem_ctx);
1934 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1941 ldb_search_default_callback,
1944 if (ret != LDB_SUCCESS) {
1945 talloc_free(mem_ctx);
1946 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1950 talloc_steal(req, attrs);
1952 ret = ldb_request(ldb_ctx, req);
1954 if (ret == LDB_SUCCESS) {
1955 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1958 if (ret != LDB_SUCCESS) {
1959 talloc_free(mem_ctx);
1960 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1964 py_ret = PyLdbResult_FromResult(res);
1966 talloc_free(mem_ctx);
1971 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
1973 if (reply->py_iter != NULL) {
1974 DLIST_REMOVE(reply->py_iter->state.next, reply);
1975 if (reply->py_iter->state.result == reply) {
1976 reply->py_iter->state.result = NULL;
1978 reply->py_iter = NULL;
1981 if (reply->obj != NULL) {
1982 Py_DECREF(reply->obj);
1989 static int py_ldb_search_iterator_callback(struct ldb_request *req,
1990 struct ldb_reply *ares)
1992 PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
1993 struct ldb_result result = { .msgs = NULL };
1994 struct py_ldb_search_iterator_reply *reply = NULL;
1997 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2000 if (ares->error != LDB_SUCCESS) {
2001 int ret = ares->error;
2003 return ldb_request_done(req, ret);
2006 reply = talloc_zero(py_iter->mem_ctx,
2007 struct py_ldb_search_iterator_reply);
2008 if (reply == NULL) {
2010 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2012 reply->py_iter = py_iter;
2013 talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
2015 switch (ares->type) {
2016 case LDB_REPLY_ENTRY:
2017 reply->obj = PyLdbMessage_FromMessage(ares->message);
2018 if (reply->obj == NULL) {
2020 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2022 DLIST_ADD_END(py_iter->state.next, reply);
2026 case LDB_REPLY_REFERRAL:
2027 reply->obj = PyStr_FromString(ares->referral);
2028 if (reply->obj == NULL) {
2030 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2032 DLIST_ADD_END(py_iter->state.next, reply);
2036 case LDB_REPLY_DONE:
2037 result = (struct ldb_result) { .controls = ares->controls };
2038 reply->obj = PyLdbResult_FromResult(&result);
2039 if (reply->obj == NULL) {
2041 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2043 py_iter->state.result = reply;
2045 return ldb_request_done(req, LDB_SUCCESS);
2049 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2052 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2054 PyObject *py_base = Py_None;
2055 int scope = LDB_SCOPE_DEFAULT;
2058 PyObject *py_attrs = Py_None;
2059 PyObject *py_controls = Py_None;
2060 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
2063 struct ldb_context *ldb_ctx;
2064 struct ldb_control **parsed_controls;
2065 struct ldb_dn *base;
2066 PyLdbSearchIteratorObject *py_iter;
2068 /* type "int" rather than "enum" for "scope" is intentional */
2069 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
2070 discard_const_p(char *, kwnames),
2071 &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
2074 py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
2075 if (py_iter == NULL) {
2079 py_iter->ldb = self;
2081 ZERO_STRUCT(py_iter->state);
2082 py_iter->mem_ctx = talloc_new(NULL);
2083 if (py_iter->mem_ctx == NULL) {
2089 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2091 if (py_attrs == Py_None) {
2094 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2095 if (attrs == NULL) {
2102 if (py_base == Py_None) {
2103 base = ldb_get_default_basedn(ldb_ctx);
2105 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2112 if (py_controls == Py_None) {
2113 parsed_controls = NULL;
2115 const char **controls = NULL;
2117 controls = PyList_AsStrList(py_iter->mem_ctx,
2118 py_controls, "controls");
2119 if (controls == NULL) {
2125 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2128 if (controls[0] != NULL && parsed_controls == NULL) {
2133 talloc_free(controls);
2136 ret = ldb_build_search_req(&py_iter->state.req,
2145 py_ldb_search_iterator_callback,
2147 if (ret != LDB_SUCCESS) {
2149 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2153 ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2155 ret = ldb_request(ldb_ctx, py_iter->state.req);
2156 if (ret != LDB_SUCCESS) {
2158 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2162 return (PyObject *)py_iter;
2165 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2170 if (!PyArg_ParseTuple(args, "s", &name))
2173 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
2178 /* FIXME: More interpretation */
2183 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2188 if (!PyArg_ParseTuple(args, "sO", &name, &data))
2191 /* FIXME: More interpretation */
2193 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
2198 static PyObject *py_ldb_modules(PyLdbObject *self)
2200 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2201 PyObject *ret = PyList_New(0);
2202 struct ldb_module *mod;
2204 for (mod = ldb->modules; mod; mod = mod->next) {
2205 PyList_Append(ret, PyLdbModule_FromModule(mod));
2211 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2213 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2217 if (!PyArg_ParseTuple(args, "i", &type))
2220 /* FIXME: More interpretation */
2222 ret = ldb_sequence_number(ldb, type, &value);
2224 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2226 return PyLong_FromLongLong(value);
2230 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2232 .read_fn = ldb_handler_copy,
2233 .write_clear_fn = ldb_handler_copy,
2234 .write_hex_fn = ldb_handler_copy,
2237 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self)
2239 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2242 ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2244 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2250 static PyMethodDef py_ldb_methods[] = {
2251 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
2252 "S.set_debug(callback) -> None\n"
2253 "Set callback for LDB debug messages.\n"
2254 "The callback should accept a debug level and debug text." },
2255 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
2256 "S.set_create_perms(mode) -> None\n"
2257 "Set mode to use when creating new LDB files." },
2258 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2259 "S.set_modules_dir(path) -> None\n"
2260 "Set path LDB should search for modules" },
2261 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
2262 "S.transaction_start() -> None\n"
2263 "Start a new transaction." },
2264 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2265 "S.transaction_prepare_commit() -> None\n"
2266 "prepare to commit a new transaction (2-stage commit)." },
2267 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
2268 "S.transaction_commit() -> None\n"
2269 "commit a new transaction." },
2270 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
2271 "S.transaction_cancel() -> None\n"
2272 "cancel a new transaction." },
2273 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
2275 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2277 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2279 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2281 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2283 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
2284 "S.connect(url, flags=0, options=None) -> None\n"
2285 "Connect to a LDB URL." },
2286 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
2287 "S.modify(message, controls=None, validate=False) -> None\n"
2288 "Modify an entry." },
2289 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
2290 "S.add(message, controls=None) -> None\n"
2292 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
2293 "S.delete(dn, controls=None) -> None\n"
2294 "Remove an entry." },
2295 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
2296 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2297 "Rename an entry." },
2298 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
2299 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\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 ":return: ldb.Result object\n"
2309 { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS,
2310 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2311 "Search in a database.\n"
2313 ":param base: Optional base DN to search\n"
2314 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2315 ":param expression: Optional search expression\n"
2316 ":param attrs: Attributes to return (defaults to all)\n"
2317 ":param controls: Optional list of controls\n"
2318 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2319 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2321 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2323 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2325 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2327 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2328 "S.parse_ldif(ldif) -> iter(messages)\n"
2329 "Parse a string formatted using LDIF." },
2330 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2331 "S.write_ldif(message, changetype) -> ldif\n"
2332 "Print the message as a string formatted using LDIF." },
2333 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2334 "S.msg_diff(Message) -> Message\n"
2335 "Return an LDB Message of the difference between two Message objects." },
2336 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2337 "S.get_opaque(name) -> value\n"
2338 "Get an opaque value set on this LDB connection. \n"
2339 ":note: The returned value may not be useful in Python."
2341 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2342 "S.set_opaque(name, value) -> None\n"
2343 "Set an opaque value on this LDB connection. \n"
2344 ":note: Passing incorrect values may cause crashes." },
2345 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2346 "S.modules() -> list\n"
2347 "Return the list of modules on this LDB connection " },
2348 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2349 "S.sequence_number(type) -> value\n"
2350 "Return the value of the sequence according to the requested type" },
2351 { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2352 "S._register_test_extensions() -> None\n"
2353 "Register internal extensions used in testing" },
2357 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2359 PyLdbModuleObject *ret;
2361 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2366 ret->mem_ctx = talloc_new(NULL);
2367 ret->mod = talloc_reference(ret->mem_ctx, mod);
2368 return (PyObject *)ret;
2371 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2373 struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2377 return PyLdbModule_FromModule(mod);
2380 static PyGetSetDef py_ldb_getset[] = {
2382 .name = discard_const_p(char, "firstmodule"),
2383 .get = (getter)py_ldb_get_firstmodule,
2388 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2390 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2392 struct ldb_result *result;
2396 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2400 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2402 if (ret != LDB_SUCCESS) {
2403 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2407 count = result->count;
2409 talloc_free(result);
2412 PyErr_Format(PyExc_RuntimeError,
2413 "Searching for [%s] dn gave %u results!",
2414 ldb_dn_get_linearized(dn),
2422 static PySequenceMethods py_ldb_seq = {
2423 .sq_contains = (objobjproc)py_ldb_contains,
2426 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2430 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2435 ret->mem_ctx = talloc_new(NULL);
2436 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2437 return (PyObject *)ret;
2440 static void py_ldb_dealloc(PyLdbObject *self)
2442 talloc_free(self->mem_ctx);
2443 Py_TYPE(self)->tp_free(self);
2446 static PyTypeObject PyLdb = {
2447 .tp_name = "ldb.Ldb",
2448 .tp_methods = py_ldb_methods,
2449 .tp_repr = (reprfunc)py_ldb_repr,
2450 .tp_new = py_ldb_new,
2451 .tp_init = (initproc)py_ldb_init,
2452 .tp_dealloc = (destructor)py_ldb_dealloc,
2453 .tp_getset = py_ldb_getset,
2454 .tp_getattro = PyObject_GenericGetAttr,
2455 .tp_basicsize = sizeof(PyLdbObject),
2456 .tp_doc = "Connection to a LDB database.",
2457 .tp_as_sequence = &py_ldb_seq,
2458 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2461 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2463 talloc_free(self->mem_ctx);
2464 Py_DECREF(self->msgs);
2465 Py_DECREF(self->referals);
2466 Py_DECREF(self->controls);
2467 Py_TYPE(self)->tp_free(self);
2470 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2472 Py_INCREF(self->msgs);
2476 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2478 Py_INCREF(self->controls);
2479 return self->controls;
2482 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2484 Py_INCREF(self->referals);
2485 return self->referals;
2488 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2491 if (self->msgs == NULL) {
2492 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2495 size = PyList_Size(self->msgs);
2496 return PyInt_FromLong(size);
2499 static PyGetSetDef py_ldb_result_getset[] = {
2501 .name = discard_const_p(char, "controls"),
2502 .get = (getter)py_ldb_result_get_controls,
2505 .name = discard_const_p(char, "msgs"),
2506 .get = (getter)py_ldb_result_get_msgs,
2509 .name = discard_const_p(char, "referals"),
2510 .get = (getter)py_ldb_result_get_referals,
2513 .name = discard_const_p(char, "count"),
2514 .get = (getter)py_ldb_result_get_count,
2519 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2521 return PyObject_GetIter(self->msgs);
2524 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2526 return PySequence_Size(self->msgs);
2529 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2531 return PySequence_GetItem(self->msgs, idx);
2534 static PySequenceMethods py_ldb_result_seq = {
2535 .sq_length = (lenfunc)py_ldb_result_len,
2536 .sq_item = (ssizeargfunc)py_ldb_result_find,
2539 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2541 return PyStr_FromString("<ldb result>");
2545 static PyTypeObject PyLdbResult = {
2546 .tp_name = "ldb.Result",
2547 .tp_repr = (reprfunc)py_ldb_result_repr,
2548 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2549 .tp_iter = (getiterfunc)py_ldb_result_iter,
2550 .tp_getset = py_ldb_result_getset,
2551 .tp_getattro = PyObject_GenericGetAttr,
2552 .tp_basicsize = sizeof(PyLdbResultObject),
2553 .tp_as_sequence = &py_ldb_result_seq,
2554 .tp_doc = "LDB result.",
2555 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2558 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2560 Py_XDECREF(self->state.exception);
2561 TALLOC_FREE(self->mem_ctx);
2562 ZERO_STRUCT(self->state);
2563 Py_DECREF(self->ldb);
2564 Py_TYPE(self)->tp_free(self);
2567 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2569 PyObject *py_ret = NULL;
2571 if (self->state.req == NULL) {
2572 PyErr_SetString(PyExc_RuntimeError,
2573 "ldb.SearchIterator request already finished");
2578 * TODO: do we want a non-blocking mode?
2579 * In future we may add an optional 'nonblocking'
2580 * argument to search_iterator().
2582 * For now we keep it simple and wait for at
2586 while (self->state.next == NULL) {
2589 if (self->state.result != NULL) {
2591 * We (already) got a final result from the server.
2593 * We stop the iteration and let
2594 * py_ldb_search_iterator_result() will deliver
2595 * the result details.
2597 TALLOC_FREE(self->state.req);
2598 PyErr_SetNone(PyExc_StopIteration);
2602 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2603 if (ret != LDB_SUCCESS) {
2604 struct ldb_context *ldb_ctx;
2605 TALLOC_FREE(self->state.req);
2606 ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb);
2608 * We stop the iteration and let
2609 * py_ldb_search_iterator_result() will deliver
2612 self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2613 ret, ldb_errstring(ldb_ctx));
2614 PyErr_SetNone(PyExc_StopIteration);
2619 py_ret = self->state.next->obj;
2620 self->state.next->obj = NULL;
2621 /* no TALLOC_FREE() as self->state.next is a list */
2622 talloc_free(self->state.next);
2626 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self)
2628 PyObject *py_ret = NULL;
2630 if (self->state.req != NULL) {
2631 PyErr_SetString(PyExc_RuntimeError,
2632 "ldb.SearchIterator request running");
2636 if (self->state.next != NULL) {
2637 PyErr_SetString(PyExc_RuntimeError,
2638 "ldb.SearchIterator not fully consumed.");
2642 if (self->state.exception != NULL) {
2643 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2644 self->state.exception = NULL;
2648 if (self->state.result == NULL) {
2649 PyErr_SetString(PyExc_RuntimeError,
2650 "ldb.SearchIterator result already consumed");
2654 py_ret = self->state.result->obj;
2655 self->state.result->obj = NULL;
2656 TALLOC_FREE(self->state.result);
2660 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self)
2662 if (self->state.req == NULL) {
2663 PyErr_SetString(PyExc_RuntimeError,
2664 "ldb.SearchIterator request already finished");
2668 Py_XDECREF(self->state.exception);
2669 TALLOC_FREE(self->mem_ctx);
2670 ZERO_STRUCT(self->state);
2674 static PyMethodDef py_ldb_search_iterator_methods[] = {
2675 { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2676 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2677 { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2682 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2684 return PyStr_FromString("<ldb search iterator>");
2687 static PyTypeObject PyLdbSearchIterator = {
2688 .tp_name = "ldb.SearchIterator",
2689 .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2690 .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2691 .tp_iter = PyObject_SelfIter,
2692 .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2693 .tp_methods = py_ldb_search_iterator_methods,
2694 .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2695 .tp_doc = "LDB search_iterator.",
2696 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2699 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2701 return PyStr_FromFormat("<ldb module '%s'>",
2702 pyldb_Module_AsModule(self)->ops->name);
2705 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2707 return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
2710 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2712 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2716 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2718 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2722 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2724 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2728 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2730 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2732 struct ldb_request *req;
2733 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2734 struct ldb_module *mod;
2735 const char * const*attrs;
2737 /* type "int" rather than "enum" for "scope" is intentional */
2738 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2739 discard_const_p(char *, kwnames),
2740 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2745 if (py_attrs == Py_None) {
2748 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2753 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2754 scope, NULL /* expr */, attrs,
2755 NULL /* controls */, NULL, NULL, NULL);
2757 talloc_steal(req, attrs);
2759 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2761 req->op.search.res = NULL;
2763 ret = mod->ops->search(mod, req);
2765 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2767 py_ret = PyLdbResult_FromResult(req->op.search.res);
2775 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2777 struct ldb_request *req;
2778 PyObject *py_message;
2780 struct ldb_module *mod;
2782 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2785 req = talloc_zero(NULL, struct ldb_request);
2786 req->operation = LDB_ADD;
2787 req->op.add.message = pyldb_Message_AsMessage(py_message);
2789 mod = pyldb_Module_AsModule(self);
2790 ret = mod->ops->add(mod, req);
2792 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2797 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2800 struct ldb_request *req;
2801 PyObject *py_message;
2802 struct ldb_module *mod;
2804 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2807 req = talloc_zero(NULL, struct ldb_request);
2808 req->operation = LDB_MODIFY;
2809 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2811 mod = pyldb_Module_AsModule(self);
2812 ret = mod->ops->modify(mod, req);
2814 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2819 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2822 struct ldb_request *req;
2825 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2828 req = talloc_zero(NULL, struct ldb_request);
2829 req->operation = LDB_DELETE;
2830 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2832 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2834 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2839 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2842 struct ldb_request *req;
2843 PyObject *py_dn1, *py_dn2;
2845 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2848 req = talloc_zero(NULL, struct ldb_request);
2850 req->operation = LDB_RENAME;
2851 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2852 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2854 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2856 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2861 static PyMethodDef py_ldb_module_methods[] = {
2862 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2863 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2864 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2865 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2866 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2867 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2868 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2869 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2873 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2875 talloc_free(self->mem_ctx);
2879 static PyTypeObject PyLdbModule = {
2880 .tp_name = "ldb.LdbModule",
2881 .tp_methods = py_ldb_module_methods,
2882 .tp_repr = (reprfunc)py_ldb_module_repr,
2883 .tp_str = (reprfunc)py_ldb_module_str,
2884 .tp_basicsize = sizeof(PyLdbModuleObject),
2885 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2886 .tp_flags = Py_TPFLAGS_DEFAULT,
2887 .tp_doc = "LDB module (extension)",
2892 * Create a ldb_message_element from a Python object.
2894 * This will accept any sequence objects that contains strings, or
2897 * A reference to set_obj will be borrowed.
2899 * @param mem_ctx Memory context
2900 * @param set_obj Python object to convert
2901 * @param flags ldb_message_element flags to set
2902 * @param attr_name Name of the attribute
2903 * @return New ldb_message_element, allocated as child of mem_ctx
2905 static struct ldb_message_element *PyObject_AsMessageElement(
2906 TALLOC_CTX *mem_ctx,
2909 const char *attr_name)
2911 struct ldb_message_element *me;
2912 const char *msg = NULL;
2916 if (pyldb_MessageElement_Check(set_obj)) {
2917 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2918 /* We have to talloc_reference() the memory context, not the pointer
2919 * which may not actually be it's own context */
2920 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2921 return pyldb_MessageElement_AsMessageElement(set_obj);
2926 me = talloc(mem_ctx, struct ldb_message_element);
2932 me->name = talloc_strdup(me, attr_name);
2934 if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) {
2936 me->values = talloc_array(me, struct ldb_val, me->num_values);
2937 if (PyBytes_Check(set_obj)) {
2939 result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
2946 msg = PyStr_AsUTF8AndSize(set_obj, &size);
2952 me->values[0].data = talloc_memdup(me,
2953 (const uint8_t *)msg,
2955 me->values[0].length = size;
2956 } else if (PySequence_Check(set_obj)) {
2958 me->num_values = PySequence_Size(set_obj);
2959 me->values = talloc_array(me, struct ldb_val, me->num_values);
2960 for (i = 0; i < me->num_values; i++) {
2961 PyObject *obj = PySequence_GetItem(set_obj, i);
2962 if (PyBytes_Check(obj)) {
2964 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
2970 } else if (PyUnicode_Check(obj)) {
2971 msg = PyStr_AsUTF8AndSize(obj, &size);
2977 PyErr_Format(PyExc_TypeError,
2978 "Expected string as element %zd in list", i);
2982 me->values[i].data = talloc_memdup(me,
2983 (const uint8_t *)msg,
2985 me->values[i].length = size;
2988 PyErr_Format(PyExc_TypeError,
2989 "String or List type expected for '%s' attribute", attr_name);
2998 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2999 struct ldb_message_element *me)
3004 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3005 result = PyList_New(me->num_values);
3007 for (i = 0; i < me->num_values; i++) {
3008 PyList_SetItem(result, i,
3009 PyObject_FromLdbValue(&me->values[i]));
3015 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
3018 if (!PyArg_ParseTuple(args, "I", &i))
3020 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
3023 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
3026 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
3028 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3029 return PyInt_FromLong(el->flags);
3032 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
3035 struct ldb_message_element *el;
3036 if (!PyArg_ParseTuple(args, "I", &flags))
3039 el = pyldb_MessageElement_AsMessageElement(self);
3044 static PyMethodDef py_ldb_msg_element_methods[] = {
3045 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
3046 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
3047 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
3051 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
3053 return pyldb_MessageElement_AsMessageElement(self)->num_values;
3056 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
3058 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3059 if (idx < 0 || idx >= el->num_values) {
3060 PyErr_SetString(PyExc_IndexError, "Out of range");
3063 return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
3066 static PySequenceMethods py_ldb_msg_element_seq = {
3067 .sq_length = (lenfunc)py_ldb_msg_element_len,
3068 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
3071 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3074 if (!pyldb_MessageElement_Check(other)) {
3075 Py_INCREF(Py_NotImplemented);
3076 return Py_NotImplemented;
3078 ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3079 pyldb_MessageElement_AsMessageElement(other));
3080 return richcmp(ret, op);
3083 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3085 PyObject *el = ldb_msg_element_to_set(NULL,
3086 pyldb_MessageElement_AsMessageElement(self));
3087 PyObject *ret = PyObject_GetIter(el);
3092 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3094 PyLdbMessageElementObject *ret;
3095 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3100 ret->mem_ctx = talloc_new(NULL);
3101 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
3106 return (PyObject *)ret;
3109 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3111 PyObject *py_elements = NULL;
3112 struct ldb_message_element *el;
3113 unsigned int flags = 0;
3115 const char * const kwnames[] = { "elements", "flags", "name", NULL };
3116 PyLdbMessageElementObject *ret;
3117 TALLOC_CTX *mem_ctx;
3118 const char *msg = NULL;
3122 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3123 discard_const_p(char *, kwnames),
3124 &py_elements, &flags, &name))
3127 mem_ctx = talloc_new(NULL);
3128 if (mem_ctx == NULL) {
3133 el = talloc_zero(mem_ctx, struct ldb_message_element);
3136 talloc_free(mem_ctx);
3140 if (py_elements != NULL) {
3142 if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) {
3145 el->values = talloc_array(el, struct ldb_val, 1);
3146 if (el->values == NULL) {
3147 talloc_free(mem_ctx);
3151 if (PyBytes_Check(py_elements)) {
3152 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3155 msg = PyStr_AsUTF8AndSize(py_elements, &size);
3156 result = (msg == NULL) ? -1 : 0;
3159 talloc_free(mem_ctx);
3162 el->values[0].data = talloc_memdup(el->values,
3163 (const uint8_t *)msg, size + 1);
3164 el->values[0].length = size;
3165 } else if (PySequence_Check(py_elements)) {
3166 el->num_values = PySequence_Size(py_elements);
3167 el->values = talloc_array(el, struct ldb_val, el->num_values);
3168 if (el->values == NULL) {
3169 talloc_free(mem_ctx);
3173 for (i = 0; i < el->num_values; i++) {
3174 PyObject *item = PySequence_GetItem(py_elements, i);
3176 talloc_free(mem_ctx);
3179 if (PyBytes_Check(item)) {
3181 result = PyBytes_AsStringAndSize(item, &_msg, &size);
3183 } else if (PyUnicode_Check(item)) {
3184 msg = PyStr_AsUTF8AndSize(item, &size);
3185 result = (msg == NULL) ? -1 : 0;
3187 PyErr_Format(PyExc_TypeError,
3188 "Expected string as element %zd in list", i);
3192 talloc_free(mem_ctx);
3195 el->values[i].data = talloc_memdup(el,
3196 (const uint8_t *)msg, size+1);
3197 el->values[i].length = size;
3200 PyErr_SetString(PyExc_TypeError,
3201 "Expected string or list");
3202 talloc_free(mem_ctx);
3208 el->name = talloc_strdup(el, name);
3210 ret = PyObject_New(PyLdbMessageElementObject, type);
3212 talloc_free(mem_ctx);
3216 ret->mem_ctx = mem_ctx;
3218 return (PyObject *)ret;
3221 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3223 char *element_str = NULL;
3225 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3226 PyObject *ret, *repr;
3228 for (i = 0; i < el->num_values; i++) {
3229 PyObject *o = py_ldb_msg_element_find(self, i);
3230 repr = PyObject_Repr(o);
3231 if (element_str == NULL)
3232 element_str = talloc_strdup(NULL, PyStr_AsUTF8(repr));
3234 element_str = talloc_asprintf_append(element_str, ",%s", PyStr_AsUTF8(repr));
3238 if (element_str != NULL) {
3239 ret = PyStr_FromFormat("MessageElement([%s])", element_str);
3240 talloc_free(element_str);
3242 ret = PyStr_FromString("MessageElement([])");
3248 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3250 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3252 if (el->num_values == 1)
3253 return PyStr_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3258 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3260 talloc_free(self->mem_ctx);
3264 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3266 return wrap_text("MessageElementTextWrapper", self);
3269 static PyGetSetDef py_ldb_msg_element_getset[] = {
3271 .name = discard_const_p(char, "text"),
3272 .get = (getter)py_ldb_msg_element_get_text,
3277 static PyTypeObject PyLdbMessageElement = {
3278 .tp_name = "ldb.MessageElement",
3279 .tp_basicsize = sizeof(PyLdbMessageElementObject),
3280 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3281 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3282 .tp_str = (reprfunc)py_ldb_msg_element_str,
3283 .tp_methods = py_ldb_msg_element_methods,
3284 .tp_getset = py_ldb_msg_element_getset,
3285 .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3286 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3287 .tp_as_sequence = &py_ldb_msg_element_seq,
3288 .tp_new = py_ldb_msg_element_new,
3289 .tp_flags = Py_TPFLAGS_DEFAULT,
3290 .tp_doc = "An element of a Message",
3294 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3299 struct ldb_message *msg;
3300 struct ldb_context *ldb_ctx;
3301 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3303 if (!PyArg_ParseTuple(args, "O!O!|I",
3304 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3309 if (!PyLdb_Check(py_ldb)) {
3310 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
3314 /* mask only flags we are going to use */
3315 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3317 PyErr_SetString(PyExc_ValueError,
3318 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3319 " expected as mod_flag value");
3323 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
3325 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3330 py_ret = PyLdbMessage_FromMessage(msg);
3332 talloc_unlink(ldb_ctx, msg);
3337 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3340 if (!PyArg_ParseTuple(args, "s", &name))
3343 ldb_msg_remove_attr(self->msg, name);
3348 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
3350 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3351 Py_ssize_t i, j = 0;
3352 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3353 if (msg->dn != NULL) {
3354 PyList_SetItem(obj, j, PyStr_FromString("dn"));
3357 for (i = 0; i < msg->num_elements; i++) {
3358 PyList_SetItem(obj, j, PyStr_FromString(msg->elements[i].name));
3364 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
3366 struct ldb_message_element *el;
3368 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3369 name = PyStr_AsUTF8(py_name);
3371 PyErr_SetNone(PyExc_TypeError);
3374 if (!ldb_attr_cmp(name, "dn"))
3375 return pyldb_Dn_FromDn(msg->dn);
3376 el = ldb_msg_find_element(msg, name);
3380 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3383 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3385 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
3387 PyErr_SetString(PyExc_KeyError, "No such element");
3393 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3395 PyObject *def = NULL;
3396 const char *kwnames[] = { "name", "default", "idx", NULL };
3397 const char *name = NULL;
3399 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3400 struct ldb_message_element *el;
3402 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3403 discard_const_p(char *, kwnames), &name, &def, &idx)) {
3407 if (strcasecmp(name, "dn") == 0) {
3408 return pyldb_Dn_FromDn(msg->dn);
3411 el = ldb_msg_find_element(msg, name);
3413 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3422 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3425 return PyObject_FromLdbValue(&el->values[idx]);
3428 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
3430 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3431 Py_ssize_t i, j = 0;
3432 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3434 return PyErr_NoMemory();
3436 if (msg->dn != NULL) {
3437 PyObject *value = NULL;
3438 PyObject *obj = pyldb_Dn_FromDn(msg->dn);
3440 value = Py_BuildValue("(sO)", "dn", obj);
3442 if (value == NULL) {
3446 res = PyList_SetItem(l, 0, value);
3453 for (i = 0; i < msg->num_elements; i++, j++) {
3454 PyObject *value = NULL;
3455 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3458 value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3459 if (value == NULL ) {
3463 res = PyList_SetItem(l, 0, value);
3472 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
3474 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3476 PyObject *l = PyList_New(msg->num_elements);
3477 for (i = 0; i < msg->num_elements; i++) {
3478 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
3483 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3485 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3486 PyLdbMessageElementObject *py_element;
3488 struct ldb_message_element *el;
3489 struct ldb_message_element *el_new;
3491 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
3494 el = py_element->el;
3496 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3500 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3501 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3503 /* now deep copy all attribute values */
3504 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3505 if (el_new->values == NULL) {
3509 el_new->num_values = el->num_values;
3511 for (i = 0; i < el->num_values; i++) {
3512 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
3513 if (el_new->values[i].data == NULL
3514 && el->values[i].length != 0) {
3523 static PyMethodDef py_ldb_msg_methods[] = {
3524 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
3525 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3526 "Class method to create ldb.Message object from Dictionary.\n"
3527 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3528 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
3529 "S.keys() -> list\n\n"
3530 "Return sequence of all attribute names." },
3531 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
3532 "S.remove(name)\n\n"
3533 "Remove all entries for attributes with the specified name."},
3534 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
3535 "msg.get(name,default=None,idx=None) -> string\n"
3536 "idx is the index into the values array\n"
3537 "if idx is None, then a list is returned\n"
3538 "if idx is not None, then the element with that index is returned\n"
3539 "if you pass the special name 'dn' then the DN object is returned\n"},
3540 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
3541 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
3542 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
3543 "S.add(element)\n\n"
3544 "Add an element to this message." },
3548 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
3550 PyObject *list, *iter;
3552 list = py_ldb_msg_keys(self);
3553 iter = PyObject_GetIter(list);
3558 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
3560 const char *attr_name;
3562 attr_name = PyStr_AsUTF8(name);
3563 if (attr_name == NULL) {
3564 PyErr_SetNone(PyExc_TypeError);
3568 if (value == NULL) {
3570 ldb_msg_remove_attr(self->msg, attr_name);
3573 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
3574 value, 0, attr_name);
3578 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
3579 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
3580 if (ret != LDB_SUCCESS) {
3581 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
3588 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
3590 return pyldb_Message_AsMessage(self)->num_elements;
3593 static PyMappingMethods py_ldb_msg_mapping = {
3594 .mp_length = (lenfunc)py_ldb_msg_length,
3595 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
3596 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
3599 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3601 const char * const kwnames[] = { "dn", NULL };
3602 struct ldb_message *ret;
3603 TALLOC_CTX *mem_ctx;
3604 PyObject *pydn = NULL;
3605 PyLdbMessageObject *py_ret;
3607 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
3608 discard_const_p(char *, kwnames),
3612 mem_ctx = talloc_new(NULL);
3613 if (mem_ctx == NULL) {
3618 ret = ldb_msg_new(mem_ctx);
3620 talloc_free(mem_ctx);
3627 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
3628 talloc_free(mem_ctx);
3631 ret->dn = talloc_reference(ret, dn);
3634 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
3635 if (py_ret == NULL) {
3637 talloc_free(mem_ctx);
3641 py_ret->mem_ctx = mem_ctx;
3643 return (PyObject *)py_ret;
3646 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
3648 PyLdbMessageObject *ret;
3650 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3655 ret->mem_ctx = talloc_new(NULL);
3656 ret->msg = talloc_reference(ret->mem_ctx, msg);
3657 return (PyObject *)ret;
3660 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3662 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3663 return pyldb_Dn_FromDn(msg->dn);
3666 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3668 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3669 if (!pyldb_Dn_Check(value)) {
3670 PyErr_SetString(PyExc_TypeError, "expected dn");
3674 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3678 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
3680 return wrap_text("MessageTextWrapper", self);
3683 static PyGetSetDef py_ldb_msg_getset[] = {
3685 .name = discard_const_p(char, "dn"),
3686 .get = (getter)py_ldb_msg_get_dn,
3687 .set = (setter)py_ldb_msg_set_dn,
3690 .name = discard_const_p(char, "text"),
3691 .get = (getter)py_ldb_msg_get_text,
3696 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3698 PyObject *dict = PyDict_New(), *ret, *repr;
3699 if (PyDict_Update(dict, (PyObject *)self) != 0)
3701 repr = PyObject_Repr(dict);
3706 ret = PyStr_FromFormat("Message(%s)", PyStr_AsUTF8(repr));
3712 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3714 talloc_free(self->mem_ctx);
3718 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3719 PyLdbMessageObject *py_msg2, int op)
3721 struct ldb_message *msg1, *msg2;
3725 if (!PyLdbMessage_Check(py_msg2)) {
3726 Py_INCREF(Py_NotImplemented);
3727 return Py_NotImplemented;
3730 msg1 = pyldb_Message_AsMessage(py_msg1),
3731 msg2 = pyldb_Message_AsMessage(py_msg2);
3733 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3734 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3736 return richcmp(ret, op);
3740 ret = msg1->num_elements - msg2->num_elements;
3742 return richcmp(ret, op);
3745 for (i = 0; i < msg1->num_elements; i++) {
3746 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3747 &msg2->elements[i]);
3749 return richcmp(ret, op);
3752 ret = ldb_msg_element_compare(&msg1->elements[i],
3753 &msg2->elements[i]);
3755 return richcmp(ret, op);
3759 return richcmp(0, op);
3762 static PyTypeObject PyLdbMessage = {
3763 .tp_name = "ldb.Message",
3764 .tp_methods = py_ldb_msg_methods,
3765 .tp_getset = py_ldb_msg_getset,
3766 .tp_as_mapping = &py_ldb_msg_mapping,
3767 .tp_basicsize = sizeof(PyLdbMessageObject),
3768 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3769 .tp_new = py_ldb_msg_new,
3770 .tp_repr = (reprfunc)py_ldb_msg_repr,
3771 .tp_flags = Py_TPFLAGS_DEFAULT,
3772 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3773 .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3774 .tp_doc = "A LDB Message",
3777 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3779 PyLdbTreeObject *ret;
3781 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3787 ret->mem_ctx = talloc_new(NULL);
3788 ret->tree = talloc_reference(ret->mem_ctx, tree);
3789 return (PyObject *)ret;
3792 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3794 talloc_free(self->mem_ctx);
3798 static PyTypeObject PyLdbTree = {
3799 .tp_name = "ldb.Tree",
3800 .tp_basicsize = sizeof(PyLdbTreeObject),
3801 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3802 .tp_flags = Py_TPFLAGS_DEFAULT,
3803 .tp_doc = "A search tree",
3807 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3809 PyObject *py_ldb = (PyObject *)mod->private_data;
3810 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3812 py_base = pyldb_Dn_FromDn(req->op.search.base);
3814 if (py_base == NULL)
3815 return LDB_ERR_OPERATIONS_ERROR;
3817 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3819 if (py_tree == NULL)
3820 return LDB_ERR_OPERATIONS_ERROR;
3822 if (req->op.search.attrs == NULL) {
3826 for (len = 0; req->op.search.attrs[len]; len++);
3827 py_attrs = PyList_New(len);
3828 for (i = 0; i < len; i++)
3829 PyList_SetItem(py_attrs, i, PyStr_FromString(req->op.search.attrs[i]));
3832 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3833 discard_const_p(char, "OiOO"),
3834 py_base, req->op.search.scope, py_tree, py_attrs);
3836 Py_DECREF(py_attrs);
3840 if (py_result == NULL) {
3841 return LDB_ERR_PYTHON_EXCEPTION;
3844 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3845 if (req->op.search.res == NULL) {
3846 return LDB_ERR_PYTHON_EXCEPTION;
3849 Py_DECREF(py_result);
3854 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3856 PyObject *py_ldb = (PyObject *)mod->private_data;
3857 PyObject *py_result, *py_msg;
3859 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3861 if (py_msg == NULL) {
3862 return LDB_ERR_OPERATIONS_ERROR;
3865 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3866 discard_const_p(char, "O"),
3871 if (py_result == NULL) {
3872 return LDB_ERR_PYTHON_EXCEPTION;
3875 Py_DECREF(py_result);
3880 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3882 PyObject *py_ldb = (PyObject *)mod->private_data;
3883 PyObject *py_result, *py_msg;
3885 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3887 if (py_msg == NULL) {
3888 return LDB_ERR_OPERATIONS_ERROR;
3891 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3892 discard_const_p(char, "O"),
3897 if (py_result == NULL) {
3898 return LDB_ERR_PYTHON_EXCEPTION;
3901 Py_DECREF(py_result);
3906 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3908 PyObject *py_ldb = (PyObject *)mod->private_data;
3909 PyObject *py_result, *py_dn;
3911 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3914 return LDB_ERR_OPERATIONS_ERROR;
3916 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3917 discard_const_p(char, "O"),
3920 if (py_result == NULL) {
3921 return LDB_ERR_PYTHON_EXCEPTION;
3924 Py_DECREF(py_result);
3929 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3931 PyObject *py_ldb = (PyObject *)mod->private_data;
3932 PyObject *py_result, *py_olddn, *py_newdn;
3934 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3936 if (py_olddn == NULL)
3937 return LDB_ERR_OPERATIONS_ERROR;
3939 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3941 if (py_newdn == NULL)
3942 return LDB_ERR_OPERATIONS_ERROR;
3944 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3945 discard_const_p(char, "OO"),
3946 py_olddn, py_newdn);
3948 Py_DECREF(py_olddn);
3949 Py_DECREF(py_newdn);
3951 if (py_result == NULL) {
3952 return LDB_ERR_PYTHON_EXCEPTION;
3955 Py_DECREF(py_result);
3960 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3962 PyObject *py_ldb = (PyObject *)mod->private_data;
3963 PyObject *py_result;
3965 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3966 discard_const_p(char, ""));
3968 Py_XDECREF(py_result);
3970 return LDB_ERR_OPERATIONS_ERROR;
3973 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3975 PyObject *py_ldb = (PyObject *)mod->private_data;
3976 PyObject *py_result;
3978 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3979 discard_const_p(char, ""));
3981 Py_XDECREF(py_result);
3983 return LDB_ERR_OPERATIONS_ERROR;
3986 static int py_module_start_transaction(struct ldb_module *mod)
3988 PyObject *py_ldb = (PyObject *)mod->private_data;
3989 PyObject *py_result;
3991 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3992 discard_const_p(char, ""));
3994 if (py_result == NULL) {
3995 return LDB_ERR_PYTHON_EXCEPTION;
3998 Py_DECREF(py_result);
4003 static int py_module_end_transaction(struct ldb_module *mod)
4005 PyObject *py_ldb = (PyObject *)mod->private_data;
4006 PyObject *py_result;
4008 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
4009 discard_const_p(char, ""));
4011 if (py_result == NULL) {
4012 return LDB_ERR_PYTHON_EXCEPTION;
4015 Py_DECREF(py_result);
4020 static int py_module_del_transaction(struct ldb_module *mod)
4022 PyObject *py_ldb = (PyObject *)mod->private_data;
4023 PyObject *py_result;
4025 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
4026 discard_const_p(char, ""));
4028 if (py_result == NULL) {
4029 return LDB_ERR_PYTHON_EXCEPTION;
4032 Py_DECREF(py_result);
4037 static int py_module_destructor(struct ldb_module *mod)
4039 Py_DECREF((PyObject *)mod->private_data);
4043 static int py_module_init(struct ldb_module *mod)
4045 PyObject *py_class = (PyObject *)mod->ops->private_data;
4046 PyObject *py_result, *py_next, *py_ldb;
4048 py_ldb = PyLdb_FromLdbContext(mod->ldb);
4051 return LDB_ERR_OPERATIONS_ERROR;
4053 py_next = PyLdbModule_FromModule(mod->next);
4055 if (py_next == NULL)
4056 return LDB_ERR_OPERATIONS_ERROR;
4058 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
4061 if (py_result == NULL) {
4062 return LDB_ERR_PYTHON_EXCEPTION;
4065 mod->private_data = py_result;
4067 talloc_set_destructor(mod, py_module_destructor);
4069 return ldb_next_init(mod);
4072 static PyObject *py_register_module(PyObject *module, PyObject *args)
4075 struct ldb_module_ops *ops;
4078 if (!PyArg_ParseTuple(args, "O", &input))
4081 ops = talloc_zero(NULL, struct ldb_module_ops);
4087 ops->name = talloc_strdup(ops, PyStr_AsUTF8(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
4090 ops->private_data = input;
4091 ops->init_context = py_module_init;
4092 ops->search = py_module_search;
4093 ops->add = py_module_add;
4094 ops->modify = py_module_modify;
4095 ops->del = py_module_del;
4096 ops->rename = py_module_rename;
4097 ops->request = py_module_request;
4098 ops->extended = py_module_extended;
4099 ops->start_transaction = py_module_start_transaction;
4100 ops->end_transaction = py_module_end_transaction;
4101 ops->del_transaction = py_module_del_transaction;
4103 ret = ldb_register_module(ops);
4104 if (ret != LDB_SUCCESS) {
4108 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
4113 static PyObject *py_timestring(PyObject *module, PyObject *args)
4115 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4116 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4120 if (!PyArg_ParseTuple(args, "l", &t_val))
4122 tresult = ldb_timestring(NULL, (time_t) t_val);
4123 ret = PyStr_FromString(tresult);
4124 talloc_free(tresult);
4128 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
4131 if (!PyArg_ParseTuple(args, "s", &str))
4134 return PyInt_FromLong(ldb_string_to_time(str));
4137 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4140 if (!PyArg_ParseTuple(args, "s", &name))
4142 return PyBool_FromLong(ldb_valid_attr_name(name));
4146 encode a string using RFC2254 rules
4148 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4150 char *str, *encoded;
4151 Py_ssize_t size = 0;
4155 if (!PyArg_ParseTuple(args, "s#", &str, &size))
4157 val.data = (uint8_t *)str;
4160 encoded = ldb_binary_encode(NULL, val);
4161 if (encoded == NULL) {
4162 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4165 ret = PyStr_FromString(encoded);
4166 talloc_free(encoded);
4171 decode a string using RFC2254 rules
4173 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4179 if (!PyArg_ParseTuple(args, "s", &str))
4182 val = ldb_binary_decode(NULL, str);
4183 if (val.data == NULL) {
4184 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4187 ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4188 talloc_free(val.data);
4192 static PyMethodDef py_ldb_global_methods[] = {
4193 { "register_module", py_register_module, METH_VARARGS,
4194 "S.register_module(module) -> None\n\n"
4195 "Register a LDB module."},
4196 { "timestring", py_timestring, METH_VARARGS,
4197 "S.timestring(int) -> string\n\n"
4198 "Generate a LDAP time string from a UNIX timestamp" },
4199 { "string_to_time", py_string_to_time, METH_VARARGS,
4200 "S.string_to_time(string) -> int\n\n"
4201 "Parse a LDAP time string into a UNIX timestamp." },
4202 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4203 "S.valid_attr_name(name) -> bool\n\nn"
4204 "Check whether the supplied name is a valid attribute name." },
4205 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
4206 "S.open() -> Ldb\n\n"
4207 "Open a new LDB context." },
4208 { "binary_encode", py_binary_encode, METH_VARARGS,
4209 "S.binary_encode(string) -> string\n\n"
4210 "Perform a RFC2254 binary encoding on a string" },
4211 { "binary_decode", py_binary_decode, METH_VARARGS,
4212 "S.binary_decode(string) -> string\n\n"
4213 "Perform a RFC2254 binary decode on a string" },
4217 #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."
4219 #if PY_MAJOR_VERSION >= 3
4220 static struct PyModuleDef moduledef = {
4221 PyModuleDef_HEAD_INIT,
4223 .m_doc = MODULE_DOC,
4225 .m_methods = py_ldb_global_methods,
4229 static PyObject* module_init(void)
4233 PyLdbBytesType.tp_base = &PyBytes_Type;
4234 if (PyType_Ready(&PyLdbBytesType) < 0) {
4238 if (PyType_Ready(&PyLdbDn) < 0)
4241 if (PyType_Ready(&PyLdbMessage) < 0)
4244 if (PyType_Ready(&PyLdbMessageElement) < 0)
4247 if (PyType_Ready(&PyLdb) < 0)
4250 if (PyType_Ready(&PyLdbModule) < 0)
4253 if (PyType_Ready(&PyLdbTree) < 0)
4256 if (PyType_Ready(&PyLdbResult) < 0)
4259 if (PyType_Ready(&PyLdbSearchIterator) < 0)
4262 if (PyType_Ready(&PyLdbControl) < 0)
4265 #if PY_MAJOR_VERSION >= 3
4266 m = PyModule_Create(&moduledef);
4268 m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC);
4273 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4275 ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4276 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4277 ADD_LDB_INT(SEQ_NEXT);
4278 ADD_LDB_INT(SCOPE_DEFAULT);
4279 ADD_LDB_INT(SCOPE_BASE);
4280 ADD_LDB_INT(SCOPE_ONELEVEL);
4281 ADD_LDB_INT(SCOPE_SUBTREE);
4283 ADD_LDB_INT(CHANGETYPE_NONE);
4284 ADD_LDB_INT(CHANGETYPE_ADD);
4285 ADD_LDB_INT(CHANGETYPE_DELETE);
4286 ADD_LDB_INT(CHANGETYPE_MODIFY);
4288 ADD_LDB_INT(FLAG_MOD_ADD);
4289 ADD_LDB_INT(FLAG_MOD_REPLACE);
4290 ADD_LDB_INT(FLAG_MOD_DELETE);
4292 ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4293 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4294 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4295 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4297 ADD_LDB_INT(SUCCESS);
4298 ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4299 ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4300 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4301 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4302 ADD_LDB_INT(ERR_COMPARE_FALSE);
4303 ADD_LDB_INT(ERR_COMPARE_TRUE);
4304 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4305 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4306 ADD_LDB_INT(ERR_REFERRAL);
4307 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4308 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4309 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4310 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4311 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4312 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4313 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4314 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4315 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4316 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4317 ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4318 ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4319 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4320 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4321 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4322 ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4323 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4324 ADD_LDB_INT(ERR_BUSY);
4325 ADD_LDB_INT(ERR_UNAVAILABLE);
4326 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4327 ADD_LDB_INT(ERR_LOOP_DETECT);
4328 ADD_LDB_INT(ERR_NAMING_VIOLATION);
4329 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4330 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4331 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4332 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4333 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4334 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4335 ADD_LDB_INT(ERR_OTHER);
4337 ADD_LDB_INT(FLG_RDONLY);
4338 ADD_LDB_INT(FLG_NOSYNC);
4339 ADD_LDB_INT(FLG_RECONNECT);
4340 ADD_LDB_INT(FLG_NOMMAP);
4341 ADD_LDB_INT(FLG_SHOW_BINARY);
4342 ADD_LDB_INT(FLG_ENABLE_TRACING);
4343 ADD_LDB_INT(FLG_DONT_CREATE_DB);
4346 /* Historical misspelling */
4347 PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
4349 PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
4351 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
4352 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
4355 Py_INCREF(&PyLdbDn);
4356 Py_INCREF(&PyLdbModule);
4357 Py_INCREF(&PyLdbMessage);
4358 Py_INCREF(&PyLdbMessageElement);
4359 Py_INCREF(&PyLdbTree);
4360 Py_INCREF(&PyLdbResult);
4361 Py_INCREF(&PyLdbControl);
4363 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
4364 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
4365 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
4366 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
4367 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
4368 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
4369 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
4371 PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
4373 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4375 ADD_LDB_STRING(SYNTAX_DN);
4376 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
4377 ADD_LDB_STRING(SYNTAX_INTEGER);
4378 ADD_LDB_STRING(SYNTAX_BOOLEAN);
4379 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
4380 ADD_LDB_STRING(SYNTAX_UTC_TIME);
4381 ADD_LDB_STRING(OID_COMPARATOR_AND);
4382 ADD_LDB_STRING(OID_COMPARATOR_OR);
4387 #if PY_MAJOR_VERSION >= 3
4388 PyMODINIT_FUNC PyInit_ldb(void);
4389 PyMODINIT_FUNC PyInit_ldb(void)
4391 return module_init();