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, "|zIO",
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 return Py_BuildValue(discard_const_p(char, "(iO)"),
1678 PyLdbMessage_FromMessage(ldif->msg));
1683 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1687 struct ldb_ldif ldif;
1690 TALLOC_CTX *mem_ctx;
1692 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1695 if (!PyLdbMessage_Check(py_msg)) {
1696 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1700 ldif.msg = pyldb_Message_AsMessage(py_msg);
1701 ldif.changetype = changetype;
1703 mem_ctx = talloc_new(NULL);
1705 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1707 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1711 ret = PyStr_FromString(string);
1713 talloc_free(mem_ctx);
1718 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1720 PyObject *list, *ret;
1721 struct ldb_ldif *ldif;
1723 struct ldb_dn *last_dn = NULL;
1725 TALLOC_CTX *mem_ctx;
1727 if (!PyArg_ParseTuple(args, "s", &s))
1730 mem_ctx = talloc_new(NULL);
1735 list = PyList_New(0);
1736 while (s && *s != '\0') {
1737 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1738 talloc_steal(mem_ctx, ldif);
1740 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1741 last_dn = ldif->msg->dn;
1743 const char *last_dn_str = NULL;
1744 const char *err_string = NULL;
1745 if (last_dn == NULL) {
1746 PyErr_SetString(PyExc_ValueError,
1747 "unable to parse LDIF "
1748 "string at first chunk");
1749 talloc_free(mem_ctx);
1754 = ldb_dn_get_linearized(last_dn);
1757 = talloc_asprintf(mem_ctx,
1758 "unable to parse ldif "
1762 PyErr_SetString(PyExc_ValueError,
1764 talloc_free(mem_ctx);
1768 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1769 ret = PyObject_GetIter(list);
1774 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1777 PyObject *py_msg_old;
1778 PyObject *py_msg_new;
1779 struct ldb_message *diff;
1780 struct ldb_context *ldb;
1783 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1786 if (!PyLdbMessage_Check(py_msg_old)) {
1787 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1791 if (!PyLdbMessage_Check(py_msg_new)) {
1792 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1796 ldb = pyldb_Ldb_AsLdbContext(self);
1797 ldb_ret = ldb_msg_difference(ldb, ldb,
1798 pyldb_Message_AsMessage(py_msg_old),
1799 pyldb_Message_AsMessage(py_msg_new),
1801 if (ldb_ret != LDB_SUCCESS) {
1802 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1806 py_ret = PyLdbMessage_FromMessage(diff);
1808 talloc_unlink(ldb, diff);
1813 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1815 const struct ldb_schema_attribute *a;
1816 struct ldb_val old_val;
1817 struct ldb_val new_val;
1818 TALLOC_CTX *mem_ctx;
1825 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1828 result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1829 old_val.length = size;
1832 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1836 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1842 mem_ctx = talloc_new(NULL);
1843 if (mem_ctx == NULL) {
1848 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1849 talloc_free(mem_ctx);
1853 ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1855 talloc_free(mem_ctx);
1860 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1862 PyObject *py_base = Py_None;
1863 int scope = LDB_SCOPE_DEFAULT;
1865 PyObject *py_attrs = Py_None;
1866 PyObject *py_controls = Py_None;
1867 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1869 struct ldb_result *res;
1870 struct ldb_request *req;
1872 struct ldb_context *ldb_ctx;
1873 struct ldb_control **parsed_controls;
1874 struct ldb_dn *base;
1876 TALLOC_CTX *mem_ctx;
1878 /* type "int" rather than "enum" for "scope" is intentional */
1879 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1880 discard_const_p(char *, kwnames),
1881 &py_base, &scope, &expr, &py_attrs, &py_controls))
1885 mem_ctx = talloc_new(NULL);
1886 if (mem_ctx == NULL) {
1890 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1892 if (py_attrs == Py_None) {
1895 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1896 if (attrs == NULL) {
1897 talloc_free(mem_ctx);
1902 if (py_base == Py_None) {
1903 base = ldb_get_default_basedn(ldb_ctx);
1905 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1906 talloc_free(mem_ctx);
1911 if (py_controls == Py_None) {
1912 parsed_controls = NULL;
1914 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1915 if (controls == NULL) {
1916 talloc_free(mem_ctx);
1919 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1920 talloc_free(controls);
1923 res = talloc_zero(mem_ctx, struct ldb_result);
1926 talloc_free(mem_ctx);
1930 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1937 ldb_search_default_callback,
1940 if (ret != LDB_SUCCESS) {
1941 talloc_free(mem_ctx);
1942 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1946 talloc_steal(req, attrs);
1948 ret = ldb_request(ldb_ctx, req);
1950 if (ret == LDB_SUCCESS) {
1951 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1954 if (ret != LDB_SUCCESS) {
1955 talloc_free(mem_ctx);
1956 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1960 py_ret = PyLdbResult_FromResult(res);
1962 talloc_free(mem_ctx);
1967 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
1969 if (reply->py_iter != NULL) {
1970 DLIST_REMOVE(reply->py_iter->state.next, reply);
1971 if (reply->py_iter->state.result == reply) {
1972 reply->py_iter->state.result = NULL;
1974 reply->py_iter = NULL;
1977 if (reply->obj != NULL) {
1978 Py_DECREF(reply->obj);
1985 static int py_ldb_search_iterator_callback(struct ldb_request *req,
1986 struct ldb_reply *ares)
1988 PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
1989 struct ldb_result result = { .msgs = NULL };
1990 struct py_ldb_search_iterator_reply *reply = NULL;
1993 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1996 if (ares->error != LDB_SUCCESS) {
1997 int ret = ares->error;
1999 return ldb_request_done(req, ret);
2002 reply = talloc_zero(py_iter->mem_ctx,
2003 struct py_ldb_search_iterator_reply);
2004 if (reply == NULL) {
2006 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2008 reply->py_iter = py_iter;
2009 talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
2011 switch (ares->type) {
2012 case LDB_REPLY_ENTRY:
2013 reply->obj = PyLdbMessage_FromMessage(ares->message);
2014 if (reply->obj == NULL) {
2016 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2018 DLIST_ADD_END(py_iter->state.next, reply);
2022 case LDB_REPLY_REFERRAL:
2023 reply->obj = PyStr_FromString(ares->referral);
2024 if (reply->obj == NULL) {
2026 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2028 DLIST_ADD_END(py_iter->state.next, reply);
2032 case LDB_REPLY_DONE:
2033 result = (struct ldb_result) { .controls = ares->controls };
2034 reply->obj = PyLdbResult_FromResult(&result);
2035 if (reply->obj == NULL) {
2037 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2039 py_iter->state.result = reply;
2041 return ldb_request_done(req, LDB_SUCCESS);
2045 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2048 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2050 PyObject *py_base = Py_None;
2051 int scope = LDB_SCOPE_DEFAULT;
2054 PyObject *py_attrs = Py_None;
2055 PyObject *py_controls = Py_None;
2056 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
2059 struct ldb_context *ldb_ctx;
2060 struct ldb_control **parsed_controls;
2061 struct ldb_dn *base;
2062 PyLdbSearchIteratorObject *py_iter;
2064 /* type "int" rather than "enum" for "scope" is intentional */
2065 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
2066 discard_const_p(char *, kwnames),
2067 &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
2070 py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
2071 if (py_iter == NULL) {
2075 py_iter->ldb = self;
2077 ZERO_STRUCT(py_iter->state);
2078 py_iter->mem_ctx = talloc_new(NULL);
2079 if (py_iter->mem_ctx == NULL) {
2085 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2087 if (py_attrs == Py_None) {
2090 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2091 if (attrs == NULL) {
2098 if (py_base == Py_None) {
2099 base = ldb_get_default_basedn(ldb_ctx);
2101 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2108 if (py_controls == Py_None) {
2109 parsed_controls = NULL;
2111 const char **controls = NULL;
2113 controls = PyList_AsStrList(py_iter->mem_ctx,
2114 py_controls, "controls");
2115 if (controls == NULL) {
2121 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2124 if (controls[0] != NULL && parsed_controls == NULL) {
2129 talloc_free(controls);
2132 ret = ldb_build_search_req(&py_iter->state.req,
2141 py_ldb_search_iterator_callback,
2143 if (ret != LDB_SUCCESS) {
2145 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2149 ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2151 ret = ldb_request(ldb_ctx, py_iter->state.req);
2152 if (ret != LDB_SUCCESS) {
2154 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2158 return (PyObject *)py_iter;
2161 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2166 if (!PyArg_ParseTuple(args, "s", &name))
2169 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
2174 /* FIXME: More interpretation */
2179 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2184 if (!PyArg_ParseTuple(args, "sO", &name, &data))
2187 /* FIXME: More interpretation */
2189 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
2194 static PyObject *py_ldb_modules(PyLdbObject *self)
2196 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2197 PyObject *ret = PyList_New(0);
2198 struct ldb_module *mod;
2200 for (mod = ldb->modules; mod; mod = mod->next) {
2201 PyList_Append(ret, PyLdbModule_FromModule(mod));
2207 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2209 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2213 if (!PyArg_ParseTuple(args, "i", &type))
2216 /* FIXME: More interpretation */
2218 ret = ldb_sequence_number(ldb, type, &value);
2220 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2222 return PyLong_FromLongLong(value);
2226 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2228 .read_fn = ldb_handler_copy,
2229 .write_clear_fn = ldb_handler_copy,
2230 .write_hex_fn = ldb_handler_copy,
2233 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self)
2235 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2238 ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2240 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2246 static PyMethodDef py_ldb_methods[] = {
2247 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
2248 "S.set_debug(callback) -> None\n"
2249 "Set callback for LDB debug messages.\n"
2250 "The callback should accept a debug level and debug text." },
2251 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
2252 "S.set_create_perms(mode) -> None\n"
2253 "Set mode to use when creating new LDB files." },
2254 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2255 "S.set_modules_dir(path) -> None\n"
2256 "Set path LDB should search for modules" },
2257 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
2258 "S.transaction_start() -> None\n"
2259 "Start a new transaction." },
2260 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2261 "S.transaction_prepare_commit() -> None\n"
2262 "prepare to commit a new transaction (2-stage commit)." },
2263 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
2264 "S.transaction_commit() -> None\n"
2265 "commit a new transaction." },
2266 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
2267 "S.transaction_cancel() -> None\n"
2268 "cancel a new transaction." },
2269 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
2271 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2273 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2275 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2277 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2279 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
2280 "S.connect(url, flags=0, options=None) -> None\n"
2281 "Connect to a LDB URL." },
2282 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
2283 "S.modify(message, controls=None, validate=False) -> None\n"
2284 "Modify an entry." },
2285 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
2286 "S.add(message, controls=None) -> None\n"
2288 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
2289 "S.delete(dn, controls=None) -> None\n"
2290 "Remove an entry." },
2291 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
2292 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2293 "Rename an entry." },
2294 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
2295 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2296 "Search in a database.\n"
2298 ":param base: Optional base DN to search\n"
2299 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2300 ":param expression: Optional search expression\n"
2301 ":param attrs: Attributes to return (defaults to all)\n"
2302 ":param controls: Optional list of controls\n"
2303 ":return: ldb.Result object\n"
2305 { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS,
2306 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2307 "Search in a database.\n"
2309 ":param base: Optional base DN to search\n"
2310 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2311 ":param expression: Optional search expression\n"
2312 ":param attrs: Attributes to return (defaults to all)\n"
2313 ":param controls: Optional list of controls\n"
2314 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2315 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2317 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2319 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2321 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2323 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2324 "S.parse_ldif(ldif) -> iter(messages)\n"
2325 "Parse a string formatted using LDIF." },
2326 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2327 "S.write_ldif(message, changetype) -> ldif\n"
2328 "Print the message as a string formatted using LDIF." },
2329 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2330 "S.msg_diff(Message) -> Message\n"
2331 "Return an LDB Message of the difference between two Message objects." },
2332 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2333 "S.get_opaque(name) -> value\n"
2334 "Get an opaque value set on this LDB connection. \n"
2335 ":note: The returned value may not be useful in Python."
2337 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2338 "S.set_opaque(name, value) -> None\n"
2339 "Set an opaque value on this LDB connection. \n"
2340 ":note: Passing incorrect values may cause crashes." },
2341 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2342 "S.modules() -> list\n"
2343 "Return the list of modules on this LDB connection " },
2344 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2345 "S.sequence_number(type) -> value\n"
2346 "Return the value of the sequence according to the requested type" },
2347 { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2348 "S._register_test_extensions() -> None\n"
2349 "Register internal extensions used in testing" },
2353 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2355 PyLdbModuleObject *ret;
2357 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2362 ret->mem_ctx = talloc_new(NULL);
2363 ret->mod = talloc_reference(ret->mem_ctx, mod);
2364 return (PyObject *)ret;
2367 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2369 struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2373 return PyLdbModule_FromModule(mod);
2376 static PyGetSetDef py_ldb_getset[] = {
2378 .name = discard_const_p(char, "firstmodule"),
2379 .get = (getter)py_ldb_get_firstmodule,
2384 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2386 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2388 struct ldb_result *result;
2392 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2396 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2398 if (ret != LDB_SUCCESS) {
2399 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2403 count = result->count;
2405 talloc_free(result);
2408 PyErr_Format(PyExc_RuntimeError,
2409 "Searching for [%s] dn gave %u results!",
2410 ldb_dn_get_linearized(dn),
2418 static PySequenceMethods py_ldb_seq = {
2419 .sq_contains = (objobjproc)py_ldb_contains,
2422 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2426 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2431 ret->mem_ctx = talloc_new(NULL);
2432 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2433 return (PyObject *)ret;
2436 static void py_ldb_dealloc(PyLdbObject *self)
2438 talloc_free(self->mem_ctx);
2439 Py_TYPE(self)->tp_free(self);
2442 static PyTypeObject PyLdb = {
2443 .tp_name = "ldb.Ldb",
2444 .tp_methods = py_ldb_methods,
2445 .tp_repr = (reprfunc)py_ldb_repr,
2446 .tp_new = py_ldb_new,
2447 .tp_init = (initproc)py_ldb_init,
2448 .tp_dealloc = (destructor)py_ldb_dealloc,
2449 .tp_getset = py_ldb_getset,
2450 .tp_getattro = PyObject_GenericGetAttr,
2451 .tp_basicsize = sizeof(PyLdbObject),
2452 .tp_doc = "Connection to a LDB database.",
2453 .tp_as_sequence = &py_ldb_seq,
2454 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2457 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2459 talloc_free(self->mem_ctx);
2460 Py_DECREF(self->msgs);
2461 Py_DECREF(self->referals);
2462 Py_DECREF(self->controls);
2463 Py_TYPE(self)->tp_free(self);
2466 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2468 Py_INCREF(self->msgs);
2472 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2474 Py_INCREF(self->controls);
2475 return self->controls;
2478 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2480 Py_INCREF(self->referals);
2481 return self->referals;
2484 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2487 if (self->msgs == NULL) {
2488 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2491 size = PyList_Size(self->msgs);
2492 return PyInt_FromLong(size);
2495 static PyGetSetDef py_ldb_result_getset[] = {
2497 .name = discard_const_p(char, "controls"),
2498 .get = (getter)py_ldb_result_get_controls,
2501 .name = discard_const_p(char, "msgs"),
2502 .get = (getter)py_ldb_result_get_msgs,
2505 .name = discard_const_p(char, "referals"),
2506 .get = (getter)py_ldb_result_get_referals,
2509 .name = discard_const_p(char, "count"),
2510 .get = (getter)py_ldb_result_get_count,
2515 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2517 return PyObject_GetIter(self->msgs);
2520 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2522 return PySequence_Size(self->msgs);
2525 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2527 return PySequence_GetItem(self->msgs, idx);
2530 static PySequenceMethods py_ldb_result_seq = {
2531 .sq_length = (lenfunc)py_ldb_result_len,
2532 .sq_item = (ssizeargfunc)py_ldb_result_find,
2535 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2537 return PyStr_FromString("<ldb result>");
2541 static PyTypeObject PyLdbResult = {
2542 .tp_name = "ldb.Result",
2543 .tp_repr = (reprfunc)py_ldb_result_repr,
2544 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2545 .tp_iter = (getiterfunc)py_ldb_result_iter,
2546 .tp_getset = py_ldb_result_getset,
2547 .tp_getattro = PyObject_GenericGetAttr,
2548 .tp_basicsize = sizeof(PyLdbResultObject),
2549 .tp_as_sequence = &py_ldb_result_seq,
2550 .tp_doc = "LDB result.",
2551 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2554 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2556 Py_XDECREF(self->state.exception);
2557 TALLOC_FREE(self->mem_ctx);
2558 ZERO_STRUCT(self->state);
2559 Py_DECREF(self->ldb);
2560 Py_TYPE(self)->tp_free(self);
2563 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2565 PyObject *py_ret = NULL;
2567 if (self->state.req == NULL) {
2568 PyErr_SetString(PyExc_RuntimeError,
2569 "ldb.SearchIterator request already finished");
2574 * TODO: do we want a non-blocking mode?
2575 * In future we may add an optional 'nonblocking'
2576 * argument to search_iterator().
2578 * For now we keep it simple and wait for at
2582 while (self->state.next == NULL) {
2585 if (self->state.result != NULL) {
2587 * We (already) got a final result from the server.
2589 * We stop the iteration and let
2590 * py_ldb_search_iterator_result() will deliver
2591 * the result details.
2593 TALLOC_FREE(self->state.req);
2594 PyErr_SetNone(PyExc_StopIteration);
2598 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2599 if (ret != LDB_SUCCESS) {
2600 struct ldb_context *ldb_ctx;
2601 TALLOC_FREE(self->state.req);
2602 ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb);
2604 * We stop the iteration and let
2605 * py_ldb_search_iterator_result() will deliver
2608 self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2609 ret, ldb_errstring(ldb_ctx));
2610 PyErr_SetNone(PyExc_StopIteration);
2615 py_ret = self->state.next->obj;
2616 self->state.next->obj = NULL;
2617 /* no TALLOC_FREE() as self->state.next is a list */
2618 talloc_free(self->state.next);
2622 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self)
2624 PyObject *py_ret = NULL;
2626 if (self->state.req != NULL) {
2627 PyErr_SetString(PyExc_RuntimeError,
2628 "ldb.SearchIterator request running");
2632 if (self->state.next != NULL) {
2633 PyErr_SetString(PyExc_RuntimeError,
2634 "ldb.SearchIterator not fully consumed.");
2638 if (self->state.exception != NULL) {
2639 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2640 self->state.exception = NULL;
2644 if (self->state.result == NULL) {
2645 PyErr_SetString(PyExc_RuntimeError,
2646 "ldb.SearchIterator result already consumed");
2650 py_ret = self->state.result->obj;
2651 self->state.result->obj = NULL;
2652 TALLOC_FREE(self->state.result);
2656 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self)
2658 if (self->state.req == NULL) {
2659 PyErr_SetString(PyExc_RuntimeError,
2660 "ldb.SearchIterator request already finished");
2664 Py_XDECREF(self->state.exception);
2665 TALLOC_FREE(self->mem_ctx);
2666 ZERO_STRUCT(self->state);
2670 static PyMethodDef py_ldb_search_iterator_methods[] = {
2671 { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2672 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2673 { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2678 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2680 return PyStr_FromString("<ldb search iterator>");
2683 static PyTypeObject PyLdbSearchIterator = {
2684 .tp_name = "ldb.SearchIterator",
2685 .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2686 .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2687 .tp_iter = PyObject_SelfIter,
2688 .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2689 .tp_methods = py_ldb_search_iterator_methods,
2690 .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2691 .tp_doc = "LDB search_iterator.",
2692 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2695 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2697 return PyStr_FromFormat("<ldb module '%s'>",
2698 pyldb_Module_AsModule(self)->ops->name);
2701 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2703 return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
2706 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2708 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2712 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2714 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2718 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2720 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2724 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2726 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2728 struct ldb_request *req;
2729 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2730 struct ldb_module *mod;
2731 const char * const*attrs;
2733 /* type "int" rather than "enum" for "scope" is intentional */
2734 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2735 discard_const_p(char *, kwnames),
2736 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2741 if (py_attrs == Py_None) {
2744 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2749 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2750 scope, NULL /* expr */, attrs,
2751 NULL /* controls */, NULL, NULL, NULL);
2753 talloc_steal(req, attrs);
2755 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2757 req->op.search.res = NULL;
2759 ret = mod->ops->search(mod, req);
2761 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2763 py_ret = PyLdbResult_FromResult(req->op.search.res);
2771 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2773 struct ldb_request *req;
2774 PyObject *py_message;
2776 struct ldb_module *mod;
2778 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2781 req = talloc_zero(NULL, struct ldb_request);
2782 req->operation = LDB_ADD;
2783 req->op.add.message = pyldb_Message_AsMessage(py_message);
2785 mod = pyldb_Module_AsModule(self);
2786 ret = mod->ops->add(mod, req);
2788 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2793 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2796 struct ldb_request *req;
2797 PyObject *py_message;
2798 struct ldb_module *mod;
2800 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2803 req = talloc_zero(NULL, struct ldb_request);
2804 req->operation = LDB_MODIFY;
2805 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2807 mod = pyldb_Module_AsModule(self);
2808 ret = mod->ops->modify(mod, req);
2810 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2815 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2818 struct ldb_request *req;
2821 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2824 req = talloc_zero(NULL, struct ldb_request);
2825 req->operation = LDB_DELETE;
2826 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2828 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2830 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2835 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2838 struct ldb_request *req;
2839 PyObject *py_dn1, *py_dn2;
2841 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2844 req = talloc_zero(NULL, struct ldb_request);
2846 req->operation = LDB_RENAME;
2847 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2848 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2850 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2852 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2857 static PyMethodDef py_ldb_module_methods[] = {
2858 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2859 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2860 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2861 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2862 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2863 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2864 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2865 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2869 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2871 talloc_free(self->mem_ctx);
2875 static PyTypeObject PyLdbModule = {
2876 .tp_name = "ldb.LdbModule",
2877 .tp_methods = py_ldb_module_methods,
2878 .tp_repr = (reprfunc)py_ldb_module_repr,
2879 .tp_str = (reprfunc)py_ldb_module_str,
2880 .tp_basicsize = sizeof(PyLdbModuleObject),
2881 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2882 .tp_flags = Py_TPFLAGS_DEFAULT,
2883 .tp_doc = "LDB module (extension)",
2888 * Create a ldb_message_element from a Python object.
2890 * This will accept any sequence objects that contains strings, or
2893 * A reference to set_obj will be borrowed.
2895 * @param mem_ctx Memory context
2896 * @param set_obj Python object to convert
2897 * @param flags ldb_message_element flags to set
2898 * @param attr_name Name of the attribute
2899 * @return New ldb_message_element, allocated as child of mem_ctx
2901 static struct ldb_message_element *PyObject_AsMessageElement(
2902 TALLOC_CTX *mem_ctx,
2905 const char *attr_name)
2907 struct ldb_message_element *me;
2908 const char *msg = NULL;
2912 if (pyldb_MessageElement_Check(set_obj)) {
2913 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2914 /* We have to talloc_reference() the memory context, not the pointer
2915 * which may not actually be it's own context */
2916 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2917 return pyldb_MessageElement_AsMessageElement(set_obj);
2922 me = talloc(mem_ctx, struct ldb_message_element);
2928 me->name = talloc_strdup(me, attr_name);
2930 if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) {
2932 me->values = talloc_array(me, struct ldb_val, me->num_values);
2933 if (PyBytes_Check(set_obj)) {
2935 result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
2942 msg = PyStr_AsUTF8AndSize(set_obj, &size);
2948 me->values[0].data = talloc_memdup(me,
2949 (const uint8_t *)msg,
2951 me->values[0].length = size;
2952 } else if (PySequence_Check(set_obj)) {
2954 me->num_values = PySequence_Size(set_obj);
2955 me->values = talloc_array(me, struct ldb_val, me->num_values);
2956 for (i = 0; i < me->num_values; i++) {
2957 PyObject *obj = PySequence_GetItem(set_obj, i);
2958 if (PyBytes_Check(obj)) {
2960 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
2966 } else if (PyUnicode_Check(obj)) {
2967 msg = PyStr_AsUTF8AndSize(obj, &size);
2973 PyErr_Format(PyExc_TypeError,
2974 "Expected string as element %zd in list", i);
2978 me->values[i].data = talloc_memdup(me,
2979 (const uint8_t *)msg,
2981 me->values[i].length = size;
2984 PyErr_Format(PyExc_TypeError,
2985 "String or List type expected for '%s' attribute", attr_name);
2994 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2995 struct ldb_message_element *me)
3000 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3001 result = PyList_New(me->num_values);
3003 for (i = 0; i < me->num_values; i++) {
3004 PyList_SetItem(result, i,
3005 PyObject_FromLdbValue(&me->values[i]));
3011 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
3014 if (!PyArg_ParseTuple(args, "I", &i))
3016 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
3019 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
3022 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
3024 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3025 return PyInt_FromLong(el->flags);
3028 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
3031 struct ldb_message_element *el;
3032 if (!PyArg_ParseTuple(args, "I", &flags))
3035 el = pyldb_MessageElement_AsMessageElement(self);
3040 static PyMethodDef py_ldb_msg_element_methods[] = {
3041 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
3042 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
3043 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
3047 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
3049 return pyldb_MessageElement_AsMessageElement(self)->num_values;
3052 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
3054 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3055 if (idx < 0 || idx >= el->num_values) {
3056 PyErr_SetString(PyExc_IndexError, "Out of range");
3059 return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
3062 static PySequenceMethods py_ldb_msg_element_seq = {
3063 .sq_length = (lenfunc)py_ldb_msg_element_len,
3064 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
3067 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3070 if (!pyldb_MessageElement_Check(other)) {
3071 Py_INCREF(Py_NotImplemented);
3072 return Py_NotImplemented;
3074 ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3075 pyldb_MessageElement_AsMessageElement(other));
3076 return richcmp(ret, op);
3079 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3081 PyObject *el = ldb_msg_element_to_set(NULL,
3082 pyldb_MessageElement_AsMessageElement(self));
3083 PyObject *ret = PyObject_GetIter(el);
3088 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3090 PyLdbMessageElementObject *ret;
3091 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3096 ret->mem_ctx = talloc_new(NULL);
3097 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
3102 return (PyObject *)ret;
3105 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3107 PyObject *py_elements = NULL;
3108 struct ldb_message_element *el;
3109 unsigned int flags = 0;
3111 const char * const kwnames[] = { "elements", "flags", "name", NULL };
3112 PyLdbMessageElementObject *ret;
3113 TALLOC_CTX *mem_ctx;
3114 const char *msg = NULL;
3118 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3119 discard_const_p(char *, kwnames),
3120 &py_elements, &flags, &name))
3123 mem_ctx = talloc_new(NULL);
3124 if (mem_ctx == NULL) {
3129 el = talloc_zero(mem_ctx, struct ldb_message_element);
3132 talloc_free(mem_ctx);
3136 if (py_elements != NULL) {
3138 if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) {
3141 el->values = talloc_array(el, struct ldb_val, 1);
3142 if (el->values == NULL) {
3143 talloc_free(mem_ctx);
3147 if (PyBytes_Check(py_elements)) {
3148 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3151 msg = PyStr_AsUTF8AndSize(py_elements, &size);
3152 result = (msg == NULL) ? -1 : 0;
3155 talloc_free(mem_ctx);
3158 el->values[0].data = talloc_memdup(el->values,
3159 (const uint8_t *)msg, size + 1);
3160 el->values[0].length = size;
3161 } else if (PySequence_Check(py_elements)) {
3162 el->num_values = PySequence_Size(py_elements);
3163 el->values = talloc_array(el, struct ldb_val, el->num_values);
3164 if (el->values == NULL) {
3165 talloc_free(mem_ctx);
3169 for (i = 0; i < el->num_values; i++) {
3170 PyObject *item = PySequence_GetItem(py_elements, i);
3172 talloc_free(mem_ctx);
3175 if (PyBytes_Check(item)) {
3177 result = PyBytes_AsStringAndSize(item, &_msg, &size);
3179 } else if (PyUnicode_Check(item)) {
3180 msg = PyStr_AsUTF8AndSize(item, &size);
3181 result = (msg == NULL) ? -1 : 0;
3183 PyErr_Format(PyExc_TypeError,
3184 "Expected string as element %zd in list", i);
3188 talloc_free(mem_ctx);
3191 el->values[i].data = talloc_memdup(el,
3192 (const uint8_t *)msg, size+1);
3193 el->values[i].length = size;
3196 PyErr_SetString(PyExc_TypeError,
3197 "Expected string or list");
3198 talloc_free(mem_ctx);
3204 el->name = talloc_strdup(el, name);
3206 ret = PyObject_New(PyLdbMessageElementObject, type);
3208 talloc_free(mem_ctx);
3212 ret->mem_ctx = mem_ctx;
3214 return (PyObject *)ret;
3217 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3219 char *element_str = NULL;
3221 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3222 PyObject *ret, *repr;
3224 for (i = 0; i < el->num_values; i++) {
3225 PyObject *o = py_ldb_msg_element_find(self, i);
3226 repr = PyObject_Repr(o);
3227 if (element_str == NULL)
3228 element_str = talloc_strdup(NULL, PyStr_AsUTF8(repr));
3230 element_str = talloc_asprintf_append(element_str, ",%s", PyStr_AsUTF8(repr));
3234 if (element_str != NULL) {
3235 ret = PyStr_FromFormat("MessageElement([%s])", element_str);
3236 talloc_free(element_str);
3238 ret = PyStr_FromString("MessageElement([])");
3244 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3246 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3248 if (el->num_values == 1)
3249 return PyStr_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3254 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3256 talloc_free(self->mem_ctx);
3260 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3262 return wrap_text("MessageElementTextWrapper", self);
3265 static PyGetSetDef py_ldb_msg_element_getset[] = {
3267 .name = discard_const_p(char, "text"),
3268 .get = (getter)py_ldb_msg_element_get_text,
3273 static PyTypeObject PyLdbMessageElement = {
3274 .tp_name = "ldb.MessageElement",
3275 .tp_basicsize = sizeof(PyLdbMessageElementObject),
3276 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3277 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3278 .tp_str = (reprfunc)py_ldb_msg_element_str,
3279 .tp_methods = py_ldb_msg_element_methods,
3280 .tp_getset = py_ldb_msg_element_getset,
3281 .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3282 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3283 .tp_as_sequence = &py_ldb_msg_element_seq,
3284 .tp_new = py_ldb_msg_element_new,
3285 .tp_flags = Py_TPFLAGS_DEFAULT,
3286 .tp_doc = "An element of a Message",
3290 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3295 struct ldb_message *msg;
3296 struct ldb_context *ldb_ctx;
3297 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3299 if (!PyArg_ParseTuple(args, "O!O!|I",
3300 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3305 if (!PyLdb_Check(py_ldb)) {
3306 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
3310 /* mask only flags we are going to use */
3311 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3313 PyErr_SetString(PyExc_ValueError,
3314 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3315 " expected as mod_flag value");
3319 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
3321 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3326 py_ret = PyLdbMessage_FromMessage(msg);
3328 talloc_unlink(ldb_ctx, msg);
3333 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3336 if (!PyArg_ParseTuple(args, "s", &name))
3339 ldb_msg_remove_attr(self->msg, name);
3344 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
3346 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3347 Py_ssize_t i, j = 0;
3348 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3349 if (msg->dn != NULL) {
3350 PyList_SetItem(obj, j, PyStr_FromString("dn"));
3353 for (i = 0; i < msg->num_elements; i++) {
3354 PyList_SetItem(obj, j, PyStr_FromString(msg->elements[i].name));
3360 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
3362 struct ldb_message_element *el;
3364 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3365 name = PyStr_AsUTF8(py_name);
3367 PyErr_SetNone(PyExc_TypeError);
3370 if (!ldb_attr_cmp(name, "dn"))
3371 return pyldb_Dn_FromDn(msg->dn);
3372 el = ldb_msg_find_element(msg, name);
3376 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3379 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3381 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
3383 PyErr_SetString(PyExc_KeyError, "No such element");
3389 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3391 PyObject *def = NULL;
3392 const char *kwnames[] = { "name", "default", "idx", NULL };
3393 const char *name = NULL;
3395 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3396 struct ldb_message_element *el;
3398 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3399 discard_const_p(char *, kwnames), &name, &def, &idx)) {
3403 if (strcasecmp(name, "dn") == 0) {
3404 return pyldb_Dn_FromDn(msg->dn);
3407 el = ldb_msg_find_element(msg, name);
3409 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3418 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3421 return PyObject_FromLdbValue(&el->values[idx]);
3424 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
3426 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3427 Py_ssize_t i, j = 0;
3428 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3429 if (msg->dn != NULL) {
3430 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
3433 for (i = 0; i < msg->num_elements; i++, j++) {
3434 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3435 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3436 PyList_SetItem(l, j, value);
3441 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
3443 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3445 PyObject *l = PyList_New(msg->num_elements);
3446 for (i = 0; i < msg->num_elements; i++) {
3447 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
3452 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3454 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3455 PyLdbMessageElementObject *py_element;
3457 struct ldb_message_element *el;
3458 struct ldb_message_element *el_new;
3460 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
3463 el = py_element->el;
3465 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3469 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3470 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3472 /* now deep copy all attribute values */
3473 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3474 if (el_new->values == NULL) {
3478 el_new->num_values = el->num_values;
3480 for (i = 0; i < el->num_values; i++) {
3481 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
3482 if (el_new->values[i].data == NULL
3483 && el->values[i].length != 0) {
3492 static PyMethodDef py_ldb_msg_methods[] = {
3493 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
3494 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3495 "Class method to create ldb.Message object from Dictionary.\n"
3496 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3497 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
3498 "S.keys() -> list\n\n"
3499 "Return sequence of all attribute names." },
3500 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
3501 "S.remove(name)\n\n"
3502 "Remove all entries for attributes with the specified name."},
3503 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
3504 "msg.get(name,default=None,idx=None) -> string\n"
3505 "idx is the index into the values array\n"
3506 "if idx is None, then a list is returned\n"
3507 "if idx is not None, then the element with that index is returned\n"
3508 "if you pass the special name 'dn' then the DN object is returned\n"},
3509 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
3510 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
3511 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
3512 "S.add(element)\n\n"
3513 "Add an element to this message." },
3517 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
3519 PyObject *list, *iter;
3521 list = py_ldb_msg_keys(self);
3522 iter = PyObject_GetIter(list);
3527 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
3529 const char *attr_name;
3531 attr_name = PyStr_AsUTF8(name);
3532 if (attr_name == NULL) {
3533 PyErr_SetNone(PyExc_TypeError);
3537 if (value == NULL) {
3539 ldb_msg_remove_attr(self->msg, attr_name);
3542 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
3543 value, 0, attr_name);
3547 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
3548 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
3549 if (ret != LDB_SUCCESS) {
3550 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
3557 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
3559 return pyldb_Message_AsMessage(self)->num_elements;
3562 static PyMappingMethods py_ldb_msg_mapping = {
3563 .mp_length = (lenfunc)py_ldb_msg_length,
3564 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
3565 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
3568 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3570 const char * const kwnames[] = { "dn", NULL };
3571 struct ldb_message *ret;
3572 TALLOC_CTX *mem_ctx;
3573 PyObject *pydn = NULL;
3574 PyLdbMessageObject *py_ret;
3576 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
3577 discard_const_p(char *, kwnames),
3581 mem_ctx = talloc_new(NULL);
3582 if (mem_ctx == NULL) {
3587 ret = ldb_msg_new(mem_ctx);
3589 talloc_free(mem_ctx);
3596 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
3597 talloc_free(mem_ctx);
3600 ret->dn = talloc_reference(ret, dn);
3603 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
3604 if (py_ret == NULL) {
3606 talloc_free(mem_ctx);
3610 py_ret->mem_ctx = mem_ctx;
3612 return (PyObject *)py_ret;
3615 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
3617 PyLdbMessageObject *ret;
3619 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3624 ret->mem_ctx = talloc_new(NULL);
3625 ret->msg = talloc_reference(ret->mem_ctx, msg);
3626 return (PyObject *)ret;
3629 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3631 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3632 return pyldb_Dn_FromDn(msg->dn);
3635 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3637 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3638 if (!pyldb_Dn_Check(value)) {
3639 PyErr_SetString(PyExc_TypeError, "expected dn");
3643 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3647 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
3649 return wrap_text("MessageTextWrapper", self);
3652 static PyGetSetDef py_ldb_msg_getset[] = {
3654 .name = discard_const_p(char, "dn"),
3655 .get = (getter)py_ldb_msg_get_dn,
3656 .set = (setter)py_ldb_msg_set_dn,
3659 .name = discard_const_p(char, "text"),
3660 .get = (getter)py_ldb_msg_get_text,
3665 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3667 PyObject *dict = PyDict_New(), *ret, *repr;
3668 if (PyDict_Update(dict, (PyObject *)self) != 0)
3670 repr = PyObject_Repr(dict);
3675 ret = PyStr_FromFormat("Message(%s)", PyStr_AsUTF8(repr));
3681 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3683 talloc_free(self->mem_ctx);
3687 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3688 PyLdbMessageObject *py_msg2, int op)
3690 struct ldb_message *msg1, *msg2;
3694 if (!PyLdbMessage_Check(py_msg2)) {
3695 Py_INCREF(Py_NotImplemented);
3696 return Py_NotImplemented;
3699 msg1 = pyldb_Message_AsMessage(py_msg1),
3700 msg2 = pyldb_Message_AsMessage(py_msg2);
3702 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3703 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3705 return richcmp(ret, op);
3709 ret = msg1->num_elements - msg2->num_elements;
3711 return richcmp(ret, op);
3714 for (i = 0; i < msg1->num_elements; i++) {
3715 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3716 &msg2->elements[i]);
3718 return richcmp(ret, op);
3721 ret = ldb_msg_element_compare(&msg1->elements[i],
3722 &msg2->elements[i]);
3724 return richcmp(ret, op);
3728 return richcmp(0, op);
3731 static PyTypeObject PyLdbMessage = {
3732 .tp_name = "ldb.Message",
3733 .tp_methods = py_ldb_msg_methods,
3734 .tp_getset = py_ldb_msg_getset,
3735 .tp_as_mapping = &py_ldb_msg_mapping,
3736 .tp_basicsize = sizeof(PyLdbMessageObject),
3737 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3738 .tp_new = py_ldb_msg_new,
3739 .tp_repr = (reprfunc)py_ldb_msg_repr,
3740 .tp_flags = Py_TPFLAGS_DEFAULT,
3741 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3742 .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3743 .tp_doc = "A LDB Message",
3746 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3748 PyLdbTreeObject *ret;
3750 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3756 ret->mem_ctx = talloc_new(NULL);
3757 ret->tree = talloc_reference(ret->mem_ctx, tree);
3758 return (PyObject *)ret;
3761 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3763 talloc_free(self->mem_ctx);
3767 static PyTypeObject PyLdbTree = {
3768 .tp_name = "ldb.Tree",
3769 .tp_basicsize = sizeof(PyLdbTreeObject),
3770 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3771 .tp_flags = Py_TPFLAGS_DEFAULT,
3772 .tp_doc = "A search tree",
3776 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3778 PyObject *py_ldb = (PyObject *)mod->private_data;
3779 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3781 py_base = pyldb_Dn_FromDn(req->op.search.base);
3783 if (py_base == NULL)
3784 return LDB_ERR_OPERATIONS_ERROR;
3786 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3788 if (py_tree == NULL)
3789 return LDB_ERR_OPERATIONS_ERROR;
3791 if (req->op.search.attrs == NULL) {
3795 for (len = 0; req->op.search.attrs[len]; len++);
3796 py_attrs = PyList_New(len);
3797 for (i = 0; i < len; i++)
3798 PyList_SetItem(py_attrs, i, PyStr_FromString(req->op.search.attrs[i]));
3801 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3802 discard_const_p(char, "OiOO"),
3803 py_base, req->op.search.scope, py_tree, py_attrs);
3805 Py_DECREF(py_attrs);
3809 if (py_result == NULL) {
3810 return LDB_ERR_PYTHON_EXCEPTION;
3813 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3814 if (req->op.search.res == NULL) {
3815 return LDB_ERR_PYTHON_EXCEPTION;
3818 Py_DECREF(py_result);
3823 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3825 PyObject *py_ldb = (PyObject *)mod->private_data;
3826 PyObject *py_result, *py_msg;
3828 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3830 if (py_msg == NULL) {
3831 return LDB_ERR_OPERATIONS_ERROR;
3834 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3835 discard_const_p(char, "O"),
3840 if (py_result == NULL) {
3841 return LDB_ERR_PYTHON_EXCEPTION;
3844 Py_DECREF(py_result);
3849 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3851 PyObject *py_ldb = (PyObject *)mod->private_data;
3852 PyObject *py_result, *py_msg;
3854 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3856 if (py_msg == NULL) {
3857 return LDB_ERR_OPERATIONS_ERROR;
3860 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3861 discard_const_p(char, "O"),
3866 if (py_result == NULL) {
3867 return LDB_ERR_PYTHON_EXCEPTION;
3870 Py_DECREF(py_result);
3875 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3877 PyObject *py_ldb = (PyObject *)mod->private_data;
3878 PyObject *py_result, *py_dn;
3880 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3883 return LDB_ERR_OPERATIONS_ERROR;
3885 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3886 discard_const_p(char, "O"),
3889 if (py_result == NULL) {
3890 return LDB_ERR_PYTHON_EXCEPTION;
3893 Py_DECREF(py_result);
3898 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3900 PyObject *py_ldb = (PyObject *)mod->private_data;
3901 PyObject *py_result, *py_olddn, *py_newdn;
3903 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3905 if (py_olddn == NULL)
3906 return LDB_ERR_OPERATIONS_ERROR;
3908 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3910 if (py_newdn == NULL)
3911 return LDB_ERR_OPERATIONS_ERROR;
3913 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3914 discard_const_p(char, "OO"),
3915 py_olddn, py_newdn);
3917 Py_DECREF(py_olddn);
3918 Py_DECREF(py_newdn);
3920 if (py_result == NULL) {
3921 return LDB_ERR_PYTHON_EXCEPTION;
3924 Py_DECREF(py_result);
3929 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3931 PyObject *py_ldb = (PyObject *)mod->private_data;
3932 PyObject *py_result;
3934 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3935 discard_const_p(char, ""));
3937 Py_XDECREF(py_result);
3939 return LDB_ERR_OPERATIONS_ERROR;
3942 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3944 PyObject *py_ldb = (PyObject *)mod->private_data;
3945 PyObject *py_result;
3947 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3948 discard_const_p(char, ""));
3950 Py_XDECREF(py_result);
3952 return LDB_ERR_OPERATIONS_ERROR;
3955 static int py_module_start_transaction(struct ldb_module *mod)
3957 PyObject *py_ldb = (PyObject *)mod->private_data;
3958 PyObject *py_result;
3960 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3961 discard_const_p(char, ""));
3963 if (py_result == NULL) {
3964 return LDB_ERR_PYTHON_EXCEPTION;
3967 Py_DECREF(py_result);
3972 static int py_module_end_transaction(struct ldb_module *mod)
3974 PyObject *py_ldb = (PyObject *)mod->private_data;
3975 PyObject *py_result;
3977 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3978 discard_const_p(char, ""));
3980 if (py_result == NULL) {
3981 return LDB_ERR_PYTHON_EXCEPTION;
3984 Py_DECREF(py_result);
3989 static int py_module_del_transaction(struct ldb_module *mod)
3991 PyObject *py_ldb = (PyObject *)mod->private_data;
3992 PyObject *py_result;
3994 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3995 discard_const_p(char, ""));
3997 if (py_result == NULL) {
3998 return LDB_ERR_PYTHON_EXCEPTION;
4001 Py_DECREF(py_result);
4006 static int py_module_destructor(struct ldb_module *mod)
4008 Py_DECREF((PyObject *)mod->private_data);
4012 static int py_module_init(struct ldb_module *mod)
4014 PyObject *py_class = (PyObject *)mod->ops->private_data;
4015 PyObject *py_result, *py_next, *py_ldb;
4017 py_ldb = PyLdb_FromLdbContext(mod->ldb);
4020 return LDB_ERR_OPERATIONS_ERROR;
4022 py_next = PyLdbModule_FromModule(mod->next);
4024 if (py_next == NULL)
4025 return LDB_ERR_OPERATIONS_ERROR;
4027 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
4030 if (py_result == NULL) {
4031 return LDB_ERR_PYTHON_EXCEPTION;
4034 mod->private_data = py_result;
4036 talloc_set_destructor(mod, py_module_destructor);
4038 return ldb_next_init(mod);
4041 static PyObject *py_register_module(PyObject *module, PyObject *args)
4044 struct ldb_module_ops *ops;
4047 if (!PyArg_ParseTuple(args, "O", &input))
4050 ops = talloc_zero(NULL, struct ldb_module_ops);
4056 ops->name = talloc_strdup(ops, PyStr_AsUTF8(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
4059 ops->private_data = input;
4060 ops->init_context = py_module_init;
4061 ops->search = py_module_search;
4062 ops->add = py_module_add;
4063 ops->modify = py_module_modify;
4064 ops->del = py_module_del;
4065 ops->rename = py_module_rename;
4066 ops->request = py_module_request;
4067 ops->extended = py_module_extended;
4068 ops->start_transaction = py_module_start_transaction;
4069 ops->end_transaction = py_module_end_transaction;
4070 ops->del_transaction = py_module_del_transaction;
4072 ret = ldb_register_module(ops);
4073 if (ret != LDB_SUCCESS) {
4077 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
4082 static PyObject *py_timestring(PyObject *module, PyObject *args)
4084 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4085 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4089 if (!PyArg_ParseTuple(args, "l", &t_val))
4091 tresult = ldb_timestring(NULL, (time_t) t_val);
4092 ret = PyStr_FromString(tresult);
4093 talloc_free(tresult);
4097 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
4100 if (!PyArg_ParseTuple(args, "s", &str))
4103 return PyInt_FromLong(ldb_string_to_time(str));
4106 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4109 if (!PyArg_ParseTuple(args, "s", &name))
4111 return PyBool_FromLong(ldb_valid_attr_name(name));
4115 encode a string using RFC2254 rules
4117 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4119 char *str, *encoded;
4120 Py_ssize_t size = 0;
4124 if (!PyArg_ParseTuple(args, "s#", &str, &size))
4126 val.data = (uint8_t *)str;
4129 encoded = ldb_binary_encode(NULL, val);
4130 if (encoded == NULL) {
4131 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4134 ret = PyStr_FromString(encoded);
4135 talloc_free(encoded);
4140 decode a string using RFC2254 rules
4142 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4148 if (!PyArg_ParseTuple(args, "s", &str))
4151 val = ldb_binary_decode(NULL, str);
4152 if (val.data == NULL) {
4153 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4156 ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4157 talloc_free(val.data);
4161 static PyMethodDef py_ldb_global_methods[] = {
4162 { "register_module", py_register_module, METH_VARARGS,
4163 "S.register_module(module) -> None\n\n"
4164 "Register a LDB module."},
4165 { "timestring", py_timestring, METH_VARARGS,
4166 "S.timestring(int) -> string\n\n"
4167 "Generate a LDAP time string from a UNIX timestamp" },
4168 { "string_to_time", py_string_to_time, METH_VARARGS,
4169 "S.string_to_time(string) -> int\n\n"
4170 "Parse a LDAP time string into a UNIX timestamp." },
4171 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4172 "S.valid_attr_name(name) -> bool\n\nn"
4173 "Check whether the supplied name is a valid attribute name." },
4174 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
4175 "S.open() -> Ldb\n\n"
4176 "Open a new LDB context." },
4177 { "binary_encode", py_binary_encode, METH_VARARGS,
4178 "S.binary_encode(string) -> string\n\n"
4179 "Perform a RFC2254 binary encoding on a string" },
4180 { "binary_decode", py_binary_decode, METH_VARARGS,
4181 "S.binary_decode(string) -> string\n\n"
4182 "Perform a RFC2254 binary decode on a string" },
4186 #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."
4188 #if PY_MAJOR_VERSION >= 3
4189 static struct PyModuleDef moduledef = {
4190 PyModuleDef_HEAD_INIT,
4192 .m_doc = MODULE_DOC,
4194 .m_methods = py_ldb_global_methods,
4198 static PyObject* module_init(void)
4202 PyLdbBytesType.tp_base = &PyBytes_Type;
4203 if (PyType_Ready(&PyLdbBytesType) < 0) {
4207 if (PyType_Ready(&PyLdbDn) < 0)
4210 if (PyType_Ready(&PyLdbMessage) < 0)
4213 if (PyType_Ready(&PyLdbMessageElement) < 0)
4216 if (PyType_Ready(&PyLdb) < 0)
4219 if (PyType_Ready(&PyLdbModule) < 0)
4222 if (PyType_Ready(&PyLdbTree) < 0)
4225 if (PyType_Ready(&PyLdbResult) < 0)
4228 if (PyType_Ready(&PyLdbSearchIterator) < 0)
4231 if (PyType_Ready(&PyLdbControl) < 0)
4234 #if PY_MAJOR_VERSION >= 3
4235 m = PyModule_Create(&moduledef);
4237 m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC);
4242 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4244 ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4245 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4246 ADD_LDB_INT(SEQ_NEXT);
4247 ADD_LDB_INT(SCOPE_DEFAULT);
4248 ADD_LDB_INT(SCOPE_BASE);
4249 ADD_LDB_INT(SCOPE_ONELEVEL);
4250 ADD_LDB_INT(SCOPE_SUBTREE);
4252 ADD_LDB_INT(CHANGETYPE_NONE);
4253 ADD_LDB_INT(CHANGETYPE_ADD);
4254 ADD_LDB_INT(CHANGETYPE_DELETE);
4255 ADD_LDB_INT(CHANGETYPE_MODIFY);
4257 ADD_LDB_INT(FLAG_MOD_ADD);
4258 ADD_LDB_INT(FLAG_MOD_REPLACE);
4259 ADD_LDB_INT(FLAG_MOD_DELETE);
4261 ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4262 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4263 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4264 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4266 ADD_LDB_INT(SUCCESS);
4267 ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4268 ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4269 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4270 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4271 ADD_LDB_INT(ERR_COMPARE_FALSE);
4272 ADD_LDB_INT(ERR_COMPARE_TRUE);
4273 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4274 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4275 ADD_LDB_INT(ERR_REFERRAL);
4276 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4277 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4278 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4279 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4280 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4281 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4282 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4283 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4284 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4285 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4286 ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4287 ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4288 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4289 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4290 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4291 ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4292 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4293 ADD_LDB_INT(ERR_BUSY);
4294 ADD_LDB_INT(ERR_UNAVAILABLE);
4295 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4296 ADD_LDB_INT(ERR_LOOP_DETECT);
4297 ADD_LDB_INT(ERR_NAMING_VIOLATION);
4298 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4299 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4300 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4301 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4302 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4303 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4304 ADD_LDB_INT(ERR_OTHER);
4306 ADD_LDB_INT(FLG_RDONLY);
4307 ADD_LDB_INT(FLG_NOSYNC);
4308 ADD_LDB_INT(FLG_RECONNECT);
4309 ADD_LDB_INT(FLG_NOMMAP);
4310 ADD_LDB_INT(FLG_SHOW_BINARY);
4311 ADD_LDB_INT(FLG_ENABLE_TRACING);
4312 ADD_LDB_INT(FLG_DONT_CREATE_DB);
4315 /* Historical misspelling */
4316 PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
4318 PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
4320 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
4321 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
4324 Py_INCREF(&PyLdbDn);
4325 Py_INCREF(&PyLdbModule);
4326 Py_INCREF(&PyLdbMessage);
4327 Py_INCREF(&PyLdbMessageElement);
4328 Py_INCREF(&PyLdbTree);
4329 Py_INCREF(&PyLdbResult);
4330 Py_INCREF(&PyLdbControl);
4332 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
4333 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
4334 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
4335 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
4336 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
4337 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
4338 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
4340 PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
4342 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4344 ADD_LDB_STRING(SYNTAX_DN);
4345 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
4346 ADD_LDB_STRING(SYNTAX_INTEGER);
4347 ADD_LDB_STRING(SYNTAX_BOOLEAN);
4348 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
4349 ADD_LDB_STRING(SYNTAX_UTC_TIME);
4350 ADD_LDB_STRING(OID_COMPARATOR_AND);
4351 ADD_LDB_STRING(OID_COMPARATOR_OR);
4356 #if PY_MAJOR_VERSION >= 3
4357 PyMODINIT_FUNC PyInit_ldb(void);
4358 PyMODINIT_FUNC PyInit_ldb(void)
4360 return module_init();