2 Unix SMB/CIFS implementation.
4 Python interface to ldb.
6 Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7 Copyright (C) 2006 Simo Sorce <idra@samba.org>
8 Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9 Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10 Copyright (C) 2009-2011 Andrew Tridgell
11 Copyright (C) 2009-2011 Andrew Bartlett
13 ** NOTE! The following LGPL license applies to the ldb
14 ** library. This does NOT imply that all of Samba is released
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public
19 License as published by the Free Software Foundation; either
20 version 3 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 #include "ldb_private.h"
33 #include "ldb_handlers.h"
35 #include "dlinklist.h"
37 struct py_ldb_search_iterator_reply;
44 struct ldb_request *req;
45 struct py_ldb_search_iterator_reply *next;
46 struct py_ldb_search_iterator_reply *result;
49 } PyLdbSearchIteratorObject;
51 struct py_ldb_search_iterator_reply {
52 struct py_ldb_search_iterator_reply *prev, *next;
53 PyLdbSearchIteratorObject *py_iter;
58 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
59 static PyObject *PyExc_LdbError;
61 static PyTypeObject PyLdbControl;
62 static PyTypeObject PyLdbResult;
63 static PyTypeObject PyLdbSearchIterator;
64 static PyTypeObject PyLdbMessage;
65 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
66 static PyTypeObject PyLdbModule;
67 static PyTypeObject PyLdbDn;
68 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
69 static PyTypeObject PyLdb;
70 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
71 static PyTypeObject PyLdbMessageElement;
72 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
74 static PyTypeObject PyLdbTree;
75 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
76 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
77 static struct ldb_message_element *PyObject_AsMessageElement(
81 const char *attr_name);
82 static PyTypeObject PyLdbBytesType;
84 #if PY_MAJOR_VERSION >= 3
85 #define PyStr_Check PyUnicode_Check
86 #define PyStr_FromString PyUnicode_FromString
87 #define PyStr_FromStringAndSize PyUnicode_FromStringAndSize
88 #define PyStr_FromFormat PyUnicode_FromFormat
89 #define PyStr_FromFormatV PyUnicode_FromFormatV
90 #define PyStr_AsUTF8 PyUnicode_AsUTF8
91 #define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize
92 #define PyInt_FromLong PyLong_FromLong
94 #define PYARG_STR_UNI "es"
96 static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size)
98 PyObject* result = NULL;
99 PyObject* args = NULL;
100 args = Py_BuildValue("(y#)", msg, size);
101 result = PyLdbBytesType.tp_new(&PyLdbBytesType, args, NULL);
106 #define PyStr_Check PyString_Check
107 #define PyStr_FromString PyString_FromString
108 #define PyStr_FromStringAndSize PyString_FromStringAndSize
109 #define PyStr_FromFormat PyString_FromFormat
110 #define PyStr_FromFormatV PyString_FromFormatV
111 #define PyStr_AsUTF8 PyString_AsString
112 #define PyLdbBytes_FromStringAndSize PyString_FromStringAndSize
114 #define PYARG_STR_UNI "et"
116 const char *PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr);
118 PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr)
120 const char * ret = PyString_AsString(pystr);
123 *sizeptr = PyString_Size(pystr);
128 static PyObject *richcmp(int cmp_val, int op)
132 case Py_LT: ret = cmp_val < 0; break;
133 case Py_LE: ret = cmp_val <= 0; break;
134 case Py_EQ: ret = cmp_val == 0; break;
135 case Py_NE: ret = cmp_val != 0; break;
136 case Py_GT: ret = cmp_val > 0; break;
137 case Py_GE: ret = cmp_val >= 0; break;
139 Py_INCREF(Py_NotImplemented);
140 return Py_NotImplemented;
142 return PyBool_FromLong(ret);
146 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
148 if (self->data != NULL) {
149 char* control = ldb_control_to_string(self->mem_ctx, self->data);
150 if (control == NULL) {
154 return PyStr_FromString(control);
156 return PyStr_FromString("ldb control");
160 static void py_ldb_control_dealloc(PyLdbControlObject *self)
162 if (self->mem_ctx != NULL) {
163 talloc_free(self->mem_ctx);
166 Py_TYPE(self)->tp_free(self);
169 /* Create a text (rather than bytes) interface for a LDB result object */
170 static PyObject *wrap_text(const char *type, PyObject *wrapped)
172 PyObject *mod, *cls, *constructor, *inst;
173 mod = PyImport_ImportModule("_ldb_text");
176 cls = PyObject_GetAttrString(mod, type);
182 constructor = PyObject_GetAttrString(cls, "_wrap");
184 if (constructor == NULL) {
187 inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped);
188 Py_DECREF(constructor);
192 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
194 return PyStr_FromString(self->data->oid);
197 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
199 return PyBool_FromLong(self->data->critical);
202 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
204 if (PyObject_IsTrue(value)) {
205 self->data->critical = true;
207 self->data->critical = false;
212 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
215 const char * const kwnames[] = { "ldb", "data", NULL };
216 struct ldb_control *parsed_controls;
217 PyLdbControlObject *ret;
220 struct ldb_context *ldb_ctx;
222 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
223 discard_const_p(char *, kwnames),
224 &PyLdb, &py_ldb, &data))
227 mem_ctx = talloc_new(NULL);
228 if (mem_ctx == NULL) {
233 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
234 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
236 if (!parsed_controls) {
237 talloc_free(mem_ctx);
238 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
242 ret = PyObject_New(PyLdbControlObject, type);
245 talloc_free(mem_ctx);
249 ret->mem_ctx = mem_ctx;
251 ret->data = talloc_move(mem_ctx, &parsed_controls);
252 if (ret->data == NULL) {
255 talloc_free(mem_ctx);
259 return (PyObject *)ret;
262 static PyGetSetDef py_ldb_control_getset[] = {
264 .name = discard_const_p(char, "oid"),
265 .get = (getter)py_ldb_control_get_oid,
268 .name = discard_const_p(char, "critical"),
269 .get = (getter)py_ldb_control_get_critical,
270 .set = (setter)py_ldb_control_set_critical,
275 static PyTypeObject PyLdbControl = {
276 .tp_name = "ldb.control",
277 .tp_dealloc = (destructor)py_ldb_control_dealloc,
278 .tp_getattro = PyObject_GenericGetAttr,
279 .tp_basicsize = sizeof(PyLdbControlObject),
280 .tp_getset = py_ldb_control_getset,
281 .tp_doc = "LDB control.",
282 .tp_str = (reprfunc)py_ldb_control_str,
283 .tp_new = py_ldb_control_new,
284 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
287 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
289 if (ret == LDB_ERR_PYTHON_EXCEPTION)
290 return; /* Python exception should already be set, just keep that */
292 PyErr_SetObject(error,
293 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
294 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
296 static PyObject *py_ldb_bytes_str(PyBytesObject *self)
301 if (!PyBytes_Check(self)) {
302 PyErr_Format(PyExc_TypeError,"Unexpected type");
305 result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size);
307 PyErr_Format(PyExc_TypeError, "Failed to extract bytes");
310 return PyUnicode_FromStringAndSize(msg, size);
313 static PyTypeObject PyLdbBytesType = {
314 PyVarObject_HEAD_INIT(NULL, 0)
315 .tp_name = "ldb.bytes",
316 .tp_doc = "str/bytes (with custom str)",
317 .tp_str = (reprfunc)py_ldb_bytes_str,
318 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
321 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
323 return PyLdbBytes_FromStringAndSize((const char *)val->data, val->length);
326 static PyObject *PyStr_FromLdbValue(const struct ldb_val *val)
328 return PyStr_FromStringAndSize((const char *)val->data, val->length);
332 * Create a Python object from a ldb_result.
334 * @param result LDB result to convert
335 * @return Python object with converted result (a list object)
337 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
339 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
340 PyLdbControlObject *ctrl;
341 if (ctl_ctx == NULL) {
346 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
348 talloc_free(ctl_ctx);
352 ctrl->mem_ctx = ctl_ctx;
353 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
354 if (ctrl->data == NULL) {
359 return (PyObject*) ctrl;
363 * Create a Python object from a ldb_result.
365 * @param result LDB result to convert
366 * @return Python object with converted result (a list object)
368 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
370 PyLdbResultObject *ret;
371 PyObject *list, *controls, *referals;
374 if (result == NULL) {
378 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
384 list = PyList_New(result->count);
391 for (i = 0; i < result->count; i++) {
392 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
395 ret->mem_ctx = talloc_new(NULL);
396 if (ret->mem_ctx == NULL) {
405 if (result->controls) {
407 while (result->controls[i]) {
410 controls = PyList_New(i);
411 if (controls == NULL) {
416 for (i=0; result->controls[i]; i++) {
417 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
424 PyList_SetItem(controls, i, ctrl);
428 * No controls so we keep an empty list
430 controls = PyList_New(0);
431 if (controls == NULL) {
438 ret->controls = controls;
442 while (result->refs && result->refs[i]) {
446 referals = PyList_New(i);
447 if (referals == NULL) {
453 for (i = 0;result->refs && result->refs[i]; i++) {
454 PyList_SetItem(referals, i, PyStr_FromString(result->refs[i]));
456 ret->referals = referals;
457 return (PyObject *)ret;
461 * Create a LDB Result from a Python object.
462 * If conversion fails, NULL will be returned and a Python exception set.
464 * Note: the result object only includes the messages at the moment; extended
465 * result, controls and referrals are ignored.
467 * @param mem_ctx Memory context in which to allocate the LDB Result
468 * @param obj Python object to convert
469 * @return a ldb_result, or NULL if the conversion failed
471 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
474 struct ldb_result *res;
480 res = talloc_zero(mem_ctx, struct ldb_result);
481 res->count = PyList_Size(obj);
482 res->msgs = talloc_array(res, struct ldb_message *, res->count);
483 for (i = 0; i < res->count; i++) {
484 PyObject *item = PyList_GetItem(obj, i);
485 res->msgs[i] = pyldb_Message_AsMessage(item);
490 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
492 return PyBool_FromLong(ldb_dn_validate(self->dn));
495 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
497 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
500 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
502 return PyBool_FromLong(ldb_dn_is_special(self->dn));
505 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
507 return PyBool_FromLong(ldb_dn_is_null(self->dn));
510 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
512 return PyStr_FromString(ldb_dn_get_casefold(self->dn));
515 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
517 return PyStr_FromString(ldb_dn_get_linearized(self->dn));
520 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
522 return PyStr_FromString(ldb_dn_canonical_string(self->dn, self->dn));
525 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
527 return PyStr_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
530 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
532 const char * const kwnames[] = { "mode", NULL };
534 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
535 discard_const_p(char *, kwnames),
538 return PyStr_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
541 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
544 const struct ldb_val *val;
546 if (!PyArg_ParseTuple(args, "s", &name))
548 val = ldb_dn_get_extended_component(self->dn, name);
553 return PyBytes_FromStringAndSize((const char *)val->data, val->length);
556 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
560 uint8_t *value = NULL;
563 if (!PyArg_ParseTuple(args, "sz#", &name, (char **)&value, &size))
567 err = ldb_dn_set_extended_component(self->dn, name, NULL);
570 val.data = (uint8_t *)value;
572 err = ldb_dn_set_extended_component(self->dn, name, &val);
575 if (err != LDB_SUCCESS) {
576 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
583 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
585 PyObject *str = PyStr_FromString(ldb_dn_get_linearized(self->dn));
586 PyObject *repr, *result;
589 repr = PyObject_Repr(str);
594 result = PyStr_FromFormat("Dn(%s)", PyStr_AsUTF8(repr));
600 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
604 if (!PyArg_ParseTuple(args, "s", &name))
607 return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
610 static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
613 if (!pyldb_Dn_Check(dn2)) {
614 Py_INCREF(Py_NotImplemented);
615 return Py_NotImplemented;
617 ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2));
618 return richcmp(ret, op);
621 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
623 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
624 struct ldb_dn *parent;
625 PyLdbDnObject *py_ret;
626 TALLOC_CTX *mem_ctx = talloc_new(NULL);
628 parent = ldb_dn_get_parent(mem_ctx, dn);
629 if (parent == NULL) {
630 talloc_free(mem_ctx);
634 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
635 if (py_ret == NULL) {
637 talloc_free(mem_ctx);
640 py_ret->mem_ctx = mem_ctx;
642 return (PyObject *)py_ret;
645 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
648 struct ldb_dn *dn, *other;
649 if (!PyArg_ParseTuple(args, "O", &py_other))
652 dn = pyldb_Dn_AsDn((PyObject *)self);
654 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
657 return PyBool_FromLong(ldb_dn_add_child(dn, other));
660 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
663 struct ldb_dn *other, *dn;
664 if (!PyArg_ParseTuple(args, "O", &py_other))
667 dn = pyldb_Dn_AsDn((PyObject *)self);
669 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
672 return PyBool_FromLong(ldb_dn_add_base(dn, other));
675 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
679 if (!PyArg_ParseTuple(args, "i", &i))
682 dn = pyldb_Dn_AsDn((PyObject *)self);
684 return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
687 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
690 struct ldb_dn *dn, *base;
691 if (!PyArg_ParseTuple(args, "O", &py_base))
694 dn = pyldb_Dn_AsDn((PyObject *)self);
696 if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
699 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
702 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
706 unsigned int num = 0;
708 if (!PyArg_ParseTuple(args, "I", &num))
711 dn = pyldb_Dn_AsDn((PyObject *)self);
713 name = ldb_dn_get_component_name(dn, num);
718 return PyStr_FromString(name);
721 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
724 const struct ldb_val *val;
725 unsigned int num = 0;
727 if (!PyArg_ParseTuple(args, "I", &num))
730 dn = pyldb_Dn_AsDn((PyObject *)self);
732 val = ldb_dn_get_component_val(dn, num);
737 return PyStr_FromLdbValue(val);
740 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
742 unsigned int num = 0;
743 char *name = NULL, *value = NULL;
744 struct ldb_val val = { NULL, };
748 if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size))
751 val.data = (unsigned char*) value;
754 err = ldb_dn_set_component(self->dn, num, name, val);
755 if (err != LDB_SUCCESS) {
756 PyErr_SetString(PyExc_TypeError, "Failed to set component");
763 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
768 dn = pyldb_Dn_AsDn((PyObject *)self);
770 name = ldb_dn_get_rdn_name(dn);
775 return PyStr_FromString(name);
778 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
781 const struct ldb_val *val;
783 dn = pyldb_Dn_AsDn((PyObject *)self);
785 val = ldb_dn_get_rdn_val(dn);
790 return PyStr_FromLdbValue(val);
793 static PyMethodDef py_ldb_dn_methods[] = {
794 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
795 "S.validate() -> bool\n"
796 "Validate DN is correct." },
797 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
798 "S.is_valid() -> bool\n" },
799 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
800 "S.is_special() -> bool\n"
801 "Check whether this is a special LDB DN." },
802 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
803 "Check whether this is a null DN." },
804 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
806 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
808 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
809 "S.canonical_str() -> string\n"
810 "Canonical version of this DN (like a posix path)." },
811 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
812 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
813 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
814 "S.canonical_ex_str() -> string\n"
815 "Canonical version of this DN (like a posix path, with terminating newline)." },
816 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
817 "S.extended_str(mode=1) -> string\n"
818 "Extended version of this DN" },
819 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
821 "Get the parent for this DN." },
822 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
823 "S.add_child(dn) -> None\n"
824 "Add a child DN to this DN." },
825 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
826 "S.add_base(dn) -> None\n"
827 "Add a base DN to this DN." },
828 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
829 "S.remove_base_components(int) -> bool\n"
830 "Remove a number of DN components from the base of this DN." },
831 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
832 "S.check_special(name) -> bool\n\n"
833 "Check if name is a special DN name"},
834 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
835 "S.get_extended_component(name) -> string\n\n"
836 "returns a DN extended component as a binary string"},
837 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
838 "S.set_extended_component(name, value) -> None\n\n"
839 "set a DN extended component as a binary string"},
840 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
841 "S.get_component_name(num) -> string\n"
842 "get the attribute name of the specified component" },
843 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
844 "S.get_component_value(num) -> string\n"
845 "get the attribute value of the specified component as a binary string" },
846 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
847 "S.get_component_value(num, name, value) -> None\n"
848 "set the attribute name and value of the specified component" },
849 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
850 "S.get_rdn_name() -> string\n"
851 "get the RDN attribute name" },
852 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
853 "S.get_rdn_value() -> string\n"
854 "get the RDN attribute value as a binary string" },
858 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
860 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
864 copy a DN as a python object
866 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
868 PyLdbDnObject *py_ret;
870 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
871 if (py_ret == NULL) {
875 py_ret->mem_ctx = talloc_new(NULL);
876 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
877 return (PyObject *)py_ret;
880 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
882 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
884 PyLdbDnObject *py_ret;
886 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
889 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
890 if (py_ret == NULL) {
894 py_ret->mem_ctx = talloc_new(NULL);
895 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
896 ldb_dn_add_base(py_ret->dn, other);
897 return (PyObject *)py_ret;
900 static PySequenceMethods py_ldb_dn_seq = {
901 .sq_length = (lenfunc)py_ldb_dn_len,
902 .sq_concat = (binaryfunc)py_ldb_dn_concat,
905 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
907 struct ldb_dn *ret = NULL;
909 PyObject *py_ldb = NULL;
910 struct ldb_context *ldb_ctx = NULL;
911 TALLOC_CTX *mem_ctx = NULL;
912 PyLdbDnObject *py_ret = NULL;
913 const char * const kwnames[] = { "ldb", "dn", NULL };
915 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O"PYARG_STR_UNI,
916 discard_const_p(char *, kwnames),
917 &py_ldb, "utf8", &str))
920 if (!PyLdb_Check(py_ldb)) {
921 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
925 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
927 mem_ctx = talloc_new(NULL);
928 if (mem_ctx == NULL) {
933 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
934 if (!ldb_dn_validate(ret)) {
935 talloc_free(mem_ctx);
936 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
940 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
941 if (py_ret == NULL) {
942 talloc_free(mem_ctx);
946 py_ret->mem_ctx = mem_ctx;
950 PyMem_Free(discard_const_p(char, str));
952 return (PyObject *)py_ret;
955 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
957 talloc_free(self->mem_ctx);
961 static PyTypeObject PyLdbDn = {
963 .tp_methods = py_ldb_dn_methods,
964 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
965 .tp_repr = (reprfunc)py_ldb_dn_repr,
966 .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp,
967 .tp_as_sequence = &py_ldb_dn_seq,
968 .tp_doc = "A LDB distinguished name.",
969 .tp_new = py_ldb_dn_new,
970 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
971 .tp_basicsize = sizeof(PyLdbDnObject),
972 .tp_flags = Py_TPFLAGS_DEFAULT,
976 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
977 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
979 PyObject *fn = (PyObject *)context;
980 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyStr_FromFormatV(fmt, ap));
983 static PyObject *py_ldb_debug_func;
985 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
988 struct ldb_context *ldb_ctx;
990 if (!PyArg_ParseTuple(args, "O", &cb))
993 if (py_ldb_debug_func != NULL) {
994 Py_DECREF(py_ldb_debug_func);
998 /* FIXME: DECREF cb when exiting program */
999 py_ldb_debug_func = cb;
1000 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1001 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
1002 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
1008 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
1011 if (!PyArg_ParseTuple(args, "I", &perms))
1014 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
1019 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
1022 if (!PyArg_ParseTuple(args, "s", &modules_dir))
1025 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
1030 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
1032 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1034 ldb_err = ldb_transaction_start(ldb_ctx);
1035 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1039 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
1041 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1043 ldb_err = ldb_transaction_commit(ldb_ctx);
1044 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1048 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
1050 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1052 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
1053 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1057 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
1059 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1061 ldb_err = ldb_transaction_cancel(ldb_ctx);
1062 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1066 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
1068 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1070 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
1071 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1075 static PyObject *py_ldb_repr(PyLdbObject *self)
1077 return PyStr_FromString("<ldb connection>");
1080 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
1082 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
1085 return py_ldb_dn_copy(dn);
1089 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
1091 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
1094 return py_ldb_dn_copy(dn);
1097 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
1099 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
1102 return py_ldb_dn_copy(dn);
1105 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
1107 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
1110 return py_ldb_dn_copy(dn);
1113 static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
1114 const char *paramname)
1118 if (!PyList_Check(list)) {
1119 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
1122 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1128 for (i = 0; i < PyList_Size(list); i++) {
1129 const char *str = NULL;
1131 PyObject *item = PyList_GetItem(list, i);
1132 if (!(PyStr_Check(item) || PyUnicode_Check(item))) {
1133 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
1137 str = PyStr_AsUTF8AndSize(item, &size);
1142 ret[i] = talloc_strndup(ret, str, size);
1148 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1150 const char * const kwnames[] = { "url", "flags", "options", NULL };
1152 PyObject *py_options = Py_None;
1153 const char **options;
1154 unsigned int flags = 0;
1156 struct ldb_context *ldb;
1158 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1159 discard_const_p(char *, kwnames),
1160 &url, &flags, &py_options))
1163 ldb = pyldb_Ldb_AsLdbContext(self);
1165 if (py_options == Py_None) {
1168 options = PyList_AsStrList(ldb, py_options, "options");
1169 if (options == NULL)
1174 ret = ldb_connect(ldb, url, flags, options);
1175 if (ret != LDB_SUCCESS) {
1176 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1181 talloc_free(options);
1185 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1188 struct ldb_context *ldb;
1189 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1194 ret->mem_ctx = talloc_new(NULL);
1195 ldb = ldb_init(ret->mem_ctx, NULL);
1203 return (PyObject *)ret;
1206 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1209 unsigned int flags = 0;
1210 PyObject *py_options = Py_None;
1212 const char **options;
1213 const char * const kwnames[] = { "url", "flags", "options", NULL };
1214 struct ldb_context *ldb_ctx;
1216 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|IO",
1217 discard_const_p(char *, kwnames),
1218 &url, &flags, &py_options))
1221 if (py_options == Py_None) {
1224 options = PyList_AsStrList(NULL, py_options, "options");
1225 if (options == NULL)
1229 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1230 ret = ldb_connect(ldb_ctx, url, flags, options);
1231 talloc_free(options);
1233 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1238 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1241 PyObject *py_controls = Py_None;
1242 struct ldb_context *ldb_ctx;
1243 struct ldb_request *req;
1244 struct ldb_control **parsed_controls;
1245 struct ldb_message *msg;
1247 TALLOC_CTX *mem_ctx;
1249 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1251 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1252 discard_const_p(char *, kwnames),
1253 &py_msg, &py_controls, &validate))
1256 mem_ctx = talloc_new(NULL);
1257 if (mem_ctx == NULL) {
1261 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1263 if (py_controls == Py_None) {
1264 parsed_controls = NULL;
1266 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1267 if (controls == NULL) {
1268 talloc_free(mem_ctx);
1271 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1272 talloc_free(controls);
1275 if (!PyLdbMessage_Check(py_msg)) {
1276 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1277 talloc_free(mem_ctx);
1280 msg = pyldb_Message_AsMessage(py_msg);
1283 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1284 if (ret != LDB_SUCCESS) {
1285 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1286 talloc_free(mem_ctx);
1291 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1292 NULL, ldb_op_default_callback, NULL);
1293 if (ret != LDB_SUCCESS) {
1294 PyErr_SetString(PyExc_TypeError, "failed to build request");
1295 talloc_free(mem_ctx);
1299 /* do request and autostart a transaction */
1300 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1302 ret = ldb_transaction_start(ldb_ctx);
1303 if (ret != LDB_SUCCESS) {
1304 talloc_free(mem_ctx);
1305 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1309 ret = ldb_request(ldb_ctx, req);
1310 if (ret == LDB_SUCCESS) {
1311 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1314 if (ret == LDB_SUCCESS) {
1315 ret = ldb_transaction_commit(ldb_ctx);
1317 ldb_transaction_cancel(ldb_ctx);
1320 talloc_free(mem_ctx);
1321 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1328 * Obtain a ldb message from a Python Dictionary object.
1330 * @param mem_ctx Memory context
1331 * @param py_obj Python Dictionary object
1332 * @param ldb_ctx LDB context
1333 * @param mod_flags Flags to be set on every message element
1334 * @return ldb_message on success or NULL on failure
1336 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1338 struct ldb_context *ldb_ctx,
1339 unsigned int mod_flags)
1341 struct ldb_message *msg;
1342 unsigned int msg_pos = 0;
1343 Py_ssize_t dict_pos = 0;
1344 PyObject *key, *value;
1345 struct ldb_message_element *msg_el;
1346 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1348 msg = ldb_msg_new(mem_ctx);
1353 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1356 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1357 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1360 if (msg->dn == NULL) {
1361 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1365 PyErr_SetString(PyExc_TypeError, "no dn set");
1369 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1370 const char *key_str = PyStr_AsUTF8(key);
1371 if (ldb_attr_cmp(key_str, "dn") != 0) {
1372 msg_el = PyObject_AsMessageElement(msg->elements, value,
1373 mod_flags, key_str);
1374 if (msg_el == NULL) {
1375 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1378 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1383 msg->num_elements = msg_pos;
1388 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1392 struct ldb_context *ldb_ctx;
1393 struct ldb_request *req;
1394 struct ldb_message *msg = NULL;
1395 PyObject *py_controls = Py_None;
1396 TALLOC_CTX *mem_ctx;
1397 struct ldb_control **parsed_controls;
1398 const char * const kwnames[] = { "message", "controls", NULL };
1400 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1401 discard_const_p(char *, kwnames),
1402 &py_obj, &py_controls))
1405 mem_ctx = talloc_new(NULL);
1406 if (mem_ctx == NULL) {
1410 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1412 if (py_controls == Py_None) {
1413 parsed_controls = NULL;
1415 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1416 if (controls == NULL) {
1417 talloc_free(mem_ctx);
1420 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1421 talloc_free(controls);
1424 if (PyLdbMessage_Check(py_obj)) {
1425 msg = pyldb_Message_AsMessage(py_obj);
1426 } else if (PyDict_Check(py_obj)) {
1427 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1429 PyErr_SetString(PyExc_TypeError,
1430 "Dictionary or LdbMessage object expected!");
1434 /* we should have a PyErr already set */
1435 talloc_free(mem_ctx);
1439 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1440 if (ret != LDB_SUCCESS) {
1441 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1442 talloc_free(mem_ctx);
1446 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1447 NULL, ldb_op_default_callback, NULL);
1448 if (ret != LDB_SUCCESS) {
1449 PyErr_SetString(PyExc_TypeError, "failed to build request");
1450 talloc_free(mem_ctx);
1454 /* do request and autostart a transaction */
1455 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1457 ret = ldb_transaction_start(ldb_ctx);
1458 if (ret != LDB_SUCCESS) {
1459 talloc_free(mem_ctx);
1460 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1464 ret = ldb_request(ldb_ctx, req);
1465 if (ret == LDB_SUCCESS) {
1466 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1469 if (ret == LDB_SUCCESS) {
1470 ret = ldb_transaction_commit(ldb_ctx);
1472 ldb_transaction_cancel(ldb_ctx);
1475 talloc_free(mem_ctx);
1476 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1481 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1486 struct ldb_context *ldb_ctx;
1487 struct ldb_request *req;
1488 PyObject *py_controls = Py_None;
1489 TALLOC_CTX *mem_ctx;
1490 struct ldb_control **parsed_controls;
1491 const char * const kwnames[] = { "dn", "controls", NULL };
1493 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1494 discard_const_p(char *, kwnames),
1495 &py_dn, &py_controls))
1498 mem_ctx = talloc_new(NULL);
1499 if (mem_ctx == NULL) {
1503 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1505 if (py_controls == Py_None) {
1506 parsed_controls = NULL;
1508 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1509 if (controls == NULL) {
1510 talloc_free(mem_ctx);
1513 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1514 talloc_free(controls);
1517 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1518 talloc_free(mem_ctx);
1522 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1523 NULL, ldb_op_default_callback, NULL);
1524 if (ret != LDB_SUCCESS) {
1525 PyErr_SetString(PyExc_TypeError, "failed to build request");
1526 talloc_free(mem_ctx);
1530 /* do request and autostart a transaction */
1531 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1533 ret = ldb_transaction_start(ldb_ctx);
1534 if (ret != LDB_SUCCESS) {
1535 talloc_free(mem_ctx);
1536 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1540 ret = ldb_request(ldb_ctx, req);
1541 if (ret == LDB_SUCCESS) {
1542 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1545 if (ret == LDB_SUCCESS) {
1546 ret = ldb_transaction_commit(ldb_ctx);
1548 ldb_transaction_cancel(ldb_ctx);
1551 talloc_free(mem_ctx);
1552 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1557 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1559 PyObject *py_dn1, *py_dn2;
1560 struct ldb_dn *dn1, *dn2;
1562 TALLOC_CTX *mem_ctx;
1563 PyObject *py_controls = Py_None;
1564 struct ldb_control **parsed_controls;
1565 struct ldb_context *ldb_ctx;
1566 struct ldb_request *req;
1567 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1569 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1571 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1572 discard_const_p(char *, kwnames),
1573 &py_dn1, &py_dn2, &py_controls))
1577 mem_ctx = talloc_new(NULL);
1578 if (mem_ctx == NULL) {
1583 if (py_controls == Py_None) {
1584 parsed_controls = NULL;
1586 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1587 if (controls == NULL) {
1588 talloc_free(mem_ctx);
1591 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1592 talloc_free(controls);
1596 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1597 talloc_free(mem_ctx);
1601 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1602 talloc_free(mem_ctx);
1606 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1607 NULL, ldb_op_default_callback, NULL);
1608 if (ret != LDB_SUCCESS) {
1609 PyErr_SetString(PyExc_TypeError, "failed to build request");
1610 talloc_free(mem_ctx);
1614 /* do request and autostart a transaction */
1615 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1617 ret = ldb_transaction_start(ldb_ctx);
1618 if (ret != LDB_SUCCESS) {
1619 talloc_free(mem_ctx);
1620 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1624 ret = ldb_request(ldb_ctx, req);
1625 if (ret == LDB_SUCCESS) {
1626 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1629 if (ret == LDB_SUCCESS) {
1630 ret = ldb_transaction_commit(ldb_ctx);
1632 ldb_transaction_cancel(ldb_ctx);
1635 talloc_free(mem_ctx);
1636 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1641 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1644 if (!PyArg_ParseTuple(args, "s", &name))
1647 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1652 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1654 char *attribute, *syntax;
1657 struct ldb_context *ldb_ctx;
1659 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1662 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1663 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1665 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1670 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1675 /* We don't want this attached to the 'ldb' any more */
1676 PyObject *obj = PyLdbMessage_FromMessage(ldif->msg);
1678 Py_BuildValue(discard_const_p(char, "(iO)"),
1687 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1691 struct ldb_ldif ldif;
1694 TALLOC_CTX *mem_ctx;
1696 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1699 if (!PyLdbMessage_Check(py_msg)) {
1700 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1704 ldif.msg = pyldb_Message_AsMessage(py_msg);
1705 ldif.changetype = changetype;
1707 mem_ctx = talloc_new(NULL);
1709 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1711 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1715 ret = PyStr_FromString(string);
1717 talloc_free(mem_ctx);
1722 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1724 PyObject *list, *ret;
1725 struct ldb_ldif *ldif;
1727 struct ldb_dn *last_dn = NULL;
1729 TALLOC_CTX *mem_ctx;
1731 if (!PyArg_ParseTuple(args, "s", &s))
1734 mem_ctx = talloc_new(NULL);
1739 list = PyList_New(0);
1740 while (s && *s != '\0') {
1741 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1742 talloc_steal(mem_ctx, ldif);
1745 PyObject *py_ldif = ldb_ldif_to_pyobject(ldif);
1746 if (py_ldif == NULL) {
1748 PyErr_BadArgument();
1749 talloc_free(mem_ctx);
1752 res = PyList_Append(list, py_ldif);
1756 talloc_free(mem_ctx);
1759 last_dn = ldif->msg->dn;
1761 const char *last_dn_str = NULL;
1762 const char *err_string = NULL;
1763 if (last_dn == NULL) {
1764 PyErr_SetString(PyExc_ValueError,
1765 "unable to parse LDIF "
1766 "string at first chunk");
1768 talloc_free(mem_ctx);
1773 = ldb_dn_get_linearized(last_dn);
1776 = talloc_asprintf(mem_ctx,
1777 "unable to parse ldif "
1781 PyErr_SetString(PyExc_ValueError,
1783 talloc_free(mem_ctx);
1788 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1789 ret = PyObject_GetIter(list);
1794 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1797 PyObject *py_msg_old;
1798 PyObject *py_msg_new;
1799 struct ldb_message *diff;
1800 struct ldb_context *ldb;
1803 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1806 if (!PyLdbMessage_Check(py_msg_old)) {
1807 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1811 if (!PyLdbMessage_Check(py_msg_new)) {
1812 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1816 ldb = pyldb_Ldb_AsLdbContext(self);
1817 ldb_ret = ldb_msg_difference(ldb, ldb,
1818 pyldb_Message_AsMessage(py_msg_old),
1819 pyldb_Message_AsMessage(py_msg_new),
1821 if (ldb_ret != LDB_SUCCESS) {
1822 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1826 py_ret = PyLdbMessage_FromMessage(diff);
1828 talloc_unlink(ldb, diff);
1833 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1835 const struct ldb_schema_attribute *a;
1836 struct ldb_val old_val;
1837 struct ldb_val new_val;
1838 TALLOC_CTX *mem_ctx;
1845 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1848 result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1849 old_val.length = size;
1852 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1856 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1862 mem_ctx = talloc_new(NULL);
1863 if (mem_ctx == NULL) {
1868 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1869 talloc_free(mem_ctx);
1873 ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1875 talloc_free(mem_ctx);
1880 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1882 PyObject *py_base = Py_None;
1883 int scope = LDB_SCOPE_DEFAULT;
1885 PyObject *py_attrs = Py_None;
1886 PyObject *py_controls = Py_None;
1887 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1889 struct ldb_result *res;
1890 struct ldb_request *req;
1892 struct ldb_context *ldb_ctx;
1893 struct ldb_control **parsed_controls;
1894 struct ldb_dn *base;
1896 TALLOC_CTX *mem_ctx;
1898 /* type "int" rather than "enum" for "scope" is intentional */
1899 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1900 discard_const_p(char *, kwnames),
1901 &py_base, &scope, &expr, &py_attrs, &py_controls))
1905 mem_ctx = talloc_new(NULL);
1906 if (mem_ctx == NULL) {
1910 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1912 if (py_attrs == Py_None) {
1915 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1916 if (attrs == NULL) {
1917 talloc_free(mem_ctx);
1922 if (py_base == Py_None) {
1923 base = ldb_get_default_basedn(ldb_ctx);
1925 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1926 talloc_free(mem_ctx);
1931 if (py_controls == Py_None) {
1932 parsed_controls = NULL;
1934 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1935 if (controls == NULL) {
1936 talloc_free(mem_ctx);
1939 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1940 talloc_free(controls);
1943 res = talloc_zero(mem_ctx, struct ldb_result);
1946 talloc_free(mem_ctx);
1950 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1957 ldb_search_default_callback,
1960 if (ret != LDB_SUCCESS) {
1961 talloc_free(mem_ctx);
1962 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1966 talloc_steal(req, attrs);
1968 ret = ldb_request(ldb_ctx, req);
1970 if (ret == LDB_SUCCESS) {
1971 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1974 if (ret != LDB_SUCCESS) {
1975 talloc_free(mem_ctx);
1976 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1980 py_ret = PyLdbResult_FromResult(res);
1982 talloc_free(mem_ctx);
1987 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
1989 if (reply->py_iter != NULL) {
1990 DLIST_REMOVE(reply->py_iter->state.next, reply);
1991 if (reply->py_iter->state.result == reply) {
1992 reply->py_iter->state.result = NULL;
1994 reply->py_iter = NULL;
1997 if (reply->obj != NULL) {
1998 Py_DECREF(reply->obj);
2005 static int py_ldb_search_iterator_callback(struct ldb_request *req,
2006 struct ldb_reply *ares)
2008 PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
2009 struct ldb_result result = { .msgs = NULL };
2010 struct py_ldb_search_iterator_reply *reply = NULL;
2013 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2016 if (ares->error != LDB_SUCCESS) {
2017 int ret = ares->error;
2019 return ldb_request_done(req, ret);
2022 reply = talloc_zero(py_iter->mem_ctx,
2023 struct py_ldb_search_iterator_reply);
2024 if (reply == NULL) {
2026 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2028 reply->py_iter = py_iter;
2029 talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
2031 switch (ares->type) {
2032 case LDB_REPLY_ENTRY:
2033 reply->obj = PyLdbMessage_FromMessage(ares->message);
2034 if (reply->obj == NULL) {
2036 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2038 DLIST_ADD_END(py_iter->state.next, reply);
2042 case LDB_REPLY_REFERRAL:
2043 reply->obj = PyStr_FromString(ares->referral);
2044 if (reply->obj == NULL) {
2046 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2048 DLIST_ADD_END(py_iter->state.next, reply);
2052 case LDB_REPLY_DONE:
2053 result = (struct ldb_result) { .controls = ares->controls };
2054 reply->obj = PyLdbResult_FromResult(&result);
2055 if (reply->obj == NULL) {
2057 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2059 py_iter->state.result = reply;
2061 return ldb_request_done(req, LDB_SUCCESS);
2065 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2068 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2070 PyObject *py_base = Py_None;
2071 int scope = LDB_SCOPE_DEFAULT;
2074 PyObject *py_attrs = Py_None;
2075 PyObject *py_controls = Py_None;
2076 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
2079 struct ldb_context *ldb_ctx;
2080 struct ldb_control **parsed_controls;
2081 struct ldb_dn *base;
2082 PyLdbSearchIteratorObject *py_iter;
2084 /* type "int" rather than "enum" for "scope" is intentional */
2085 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
2086 discard_const_p(char *, kwnames),
2087 &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
2090 py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
2091 if (py_iter == NULL) {
2095 py_iter->ldb = self;
2097 ZERO_STRUCT(py_iter->state);
2098 py_iter->mem_ctx = talloc_new(NULL);
2099 if (py_iter->mem_ctx == NULL) {
2105 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2107 if (py_attrs == Py_None) {
2110 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2111 if (attrs == NULL) {
2118 if (py_base == Py_None) {
2119 base = ldb_get_default_basedn(ldb_ctx);
2121 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2128 if (py_controls == Py_None) {
2129 parsed_controls = NULL;
2131 const char **controls = NULL;
2133 controls = PyList_AsStrList(py_iter->mem_ctx,
2134 py_controls, "controls");
2135 if (controls == NULL) {
2141 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2144 if (controls[0] != NULL && parsed_controls == NULL) {
2149 talloc_free(controls);
2152 ret = ldb_build_search_req(&py_iter->state.req,
2161 py_ldb_search_iterator_callback,
2163 if (ret != LDB_SUCCESS) {
2165 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2169 ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2171 ret = ldb_request(ldb_ctx, py_iter->state.req);
2172 if (ret != LDB_SUCCESS) {
2174 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2178 return (PyObject *)py_iter;
2181 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2186 if (!PyArg_ParseTuple(args, "s", &name))
2189 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
2194 /* FIXME: More interpretation */
2199 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2204 if (!PyArg_ParseTuple(args, "sO", &name, &data))
2207 /* FIXME: More interpretation */
2209 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
2214 static PyObject *py_ldb_modules(PyLdbObject *self)
2216 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2217 PyObject *ret = PyList_New(0);
2218 struct ldb_module *mod;
2221 return PyErr_NoMemory();
2223 for (mod = ldb->modules; mod; mod = mod->next) {
2224 PyObject *item = PyLdbModule_FromModule(mod);
2227 PyErr_SetString(PyExc_RuntimeError,
2228 "Failed to load LdbModule");
2232 res = PyList_Append(ret, item);
2243 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2245 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2249 if (!PyArg_ParseTuple(args, "i", &type))
2252 /* FIXME: More interpretation */
2254 ret = ldb_sequence_number(ldb, type, &value);
2256 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2258 return PyLong_FromLongLong(value);
2262 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2264 .read_fn = ldb_handler_copy,
2265 .write_clear_fn = ldb_handler_copy,
2266 .write_hex_fn = ldb_handler_copy,
2269 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self)
2271 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2274 ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2276 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2282 static PyMethodDef py_ldb_methods[] = {
2283 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
2284 "S.set_debug(callback) -> None\n"
2285 "Set callback for LDB debug messages.\n"
2286 "The callback should accept a debug level and debug text." },
2287 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
2288 "S.set_create_perms(mode) -> None\n"
2289 "Set mode to use when creating new LDB files." },
2290 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2291 "S.set_modules_dir(path) -> None\n"
2292 "Set path LDB should search for modules" },
2293 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
2294 "S.transaction_start() -> None\n"
2295 "Start a new transaction." },
2296 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2297 "S.transaction_prepare_commit() -> None\n"
2298 "prepare to commit a new transaction (2-stage commit)." },
2299 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
2300 "S.transaction_commit() -> None\n"
2301 "commit a new transaction." },
2302 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
2303 "S.transaction_cancel() -> None\n"
2304 "cancel a new transaction." },
2305 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
2307 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2309 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2311 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2313 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2315 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
2316 "S.connect(url, flags=0, options=None) -> None\n"
2317 "Connect to a LDB URL." },
2318 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
2319 "S.modify(message, controls=None, validate=False) -> None\n"
2320 "Modify an entry." },
2321 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
2322 "S.add(message, controls=None) -> None\n"
2324 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
2325 "S.delete(dn, controls=None) -> None\n"
2326 "Remove an entry." },
2327 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
2328 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2329 "Rename an entry." },
2330 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
2331 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2332 "Search in a database.\n"
2334 ":param base: Optional base DN to search\n"
2335 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2336 ":param expression: Optional search expression\n"
2337 ":param attrs: Attributes to return (defaults to all)\n"
2338 ":param controls: Optional list of controls\n"
2339 ":return: ldb.Result object\n"
2341 { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS,
2342 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2343 "Search in a database.\n"
2345 ":param base: Optional base DN to search\n"
2346 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2347 ":param expression: Optional search expression\n"
2348 ":param attrs: Attributes to return (defaults to all)\n"
2349 ":param controls: Optional list of controls\n"
2350 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2351 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2353 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2355 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2357 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2359 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2360 "S.parse_ldif(ldif) -> iter(messages)\n"
2361 "Parse a string formatted using LDIF." },
2362 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2363 "S.write_ldif(message, changetype) -> ldif\n"
2364 "Print the message as a string formatted using LDIF." },
2365 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2366 "S.msg_diff(Message) -> Message\n"
2367 "Return an LDB Message of the difference between two Message objects." },
2368 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2369 "S.get_opaque(name) -> value\n"
2370 "Get an opaque value set on this LDB connection. \n"
2371 ":note: The returned value may not be useful in Python."
2373 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2374 "S.set_opaque(name, value) -> None\n"
2375 "Set an opaque value on this LDB connection. \n"
2376 ":note: Passing incorrect values may cause crashes." },
2377 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2378 "S.modules() -> list\n"
2379 "Return the list of modules on this LDB connection " },
2380 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2381 "S.sequence_number(type) -> value\n"
2382 "Return the value of the sequence according to the requested type" },
2383 { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2384 "S._register_test_extensions() -> None\n"
2385 "Register internal extensions used in testing" },
2389 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2391 PyLdbModuleObject *ret;
2393 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2398 ret->mem_ctx = talloc_new(NULL);
2399 ret->mod = talloc_reference(ret->mem_ctx, mod);
2400 return (PyObject *)ret;
2403 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2405 struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2409 return PyLdbModule_FromModule(mod);
2412 static PyGetSetDef py_ldb_getset[] = {
2414 .name = discard_const_p(char, "firstmodule"),
2415 .get = (getter)py_ldb_get_firstmodule,
2420 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2422 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2424 struct ldb_result *result;
2428 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2432 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2434 if (ret != LDB_SUCCESS) {
2435 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2439 count = result->count;
2441 talloc_free(result);
2444 PyErr_Format(PyExc_RuntimeError,
2445 "Searching for [%s] dn gave %u results!",
2446 ldb_dn_get_linearized(dn),
2454 static PySequenceMethods py_ldb_seq = {
2455 .sq_contains = (objobjproc)py_ldb_contains,
2458 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2462 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2467 ret->mem_ctx = talloc_new(NULL);
2468 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2469 return (PyObject *)ret;
2472 static void py_ldb_dealloc(PyLdbObject *self)
2474 talloc_free(self->mem_ctx);
2475 Py_TYPE(self)->tp_free(self);
2478 static PyTypeObject PyLdb = {
2479 .tp_name = "ldb.Ldb",
2480 .tp_methods = py_ldb_methods,
2481 .tp_repr = (reprfunc)py_ldb_repr,
2482 .tp_new = py_ldb_new,
2483 .tp_init = (initproc)py_ldb_init,
2484 .tp_dealloc = (destructor)py_ldb_dealloc,
2485 .tp_getset = py_ldb_getset,
2486 .tp_getattro = PyObject_GenericGetAttr,
2487 .tp_basicsize = sizeof(PyLdbObject),
2488 .tp_doc = "Connection to a LDB database.",
2489 .tp_as_sequence = &py_ldb_seq,
2490 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2493 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2495 talloc_free(self->mem_ctx);
2496 Py_DECREF(self->msgs);
2497 Py_DECREF(self->referals);
2498 Py_DECREF(self->controls);
2499 Py_TYPE(self)->tp_free(self);
2502 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2504 Py_INCREF(self->msgs);
2508 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2510 Py_INCREF(self->controls);
2511 return self->controls;
2514 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2516 Py_INCREF(self->referals);
2517 return self->referals;
2520 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2523 if (self->msgs == NULL) {
2524 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2527 size = PyList_Size(self->msgs);
2528 return PyInt_FromLong(size);
2531 static PyGetSetDef py_ldb_result_getset[] = {
2533 .name = discard_const_p(char, "controls"),
2534 .get = (getter)py_ldb_result_get_controls,
2537 .name = discard_const_p(char, "msgs"),
2538 .get = (getter)py_ldb_result_get_msgs,
2541 .name = discard_const_p(char, "referals"),
2542 .get = (getter)py_ldb_result_get_referals,
2545 .name = discard_const_p(char, "count"),
2546 .get = (getter)py_ldb_result_get_count,
2551 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2553 return PyObject_GetIter(self->msgs);
2556 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2558 return PySequence_Size(self->msgs);
2561 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2563 return PySequence_GetItem(self->msgs, idx);
2566 static PySequenceMethods py_ldb_result_seq = {
2567 .sq_length = (lenfunc)py_ldb_result_len,
2568 .sq_item = (ssizeargfunc)py_ldb_result_find,
2571 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2573 return PyStr_FromString("<ldb result>");
2577 static PyTypeObject PyLdbResult = {
2578 .tp_name = "ldb.Result",
2579 .tp_repr = (reprfunc)py_ldb_result_repr,
2580 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2581 .tp_iter = (getiterfunc)py_ldb_result_iter,
2582 .tp_getset = py_ldb_result_getset,
2583 .tp_getattro = PyObject_GenericGetAttr,
2584 .tp_basicsize = sizeof(PyLdbResultObject),
2585 .tp_as_sequence = &py_ldb_result_seq,
2586 .tp_doc = "LDB result.",
2587 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2590 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2592 Py_XDECREF(self->state.exception);
2593 TALLOC_FREE(self->mem_ctx);
2594 ZERO_STRUCT(self->state);
2595 Py_DECREF(self->ldb);
2596 Py_TYPE(self)->tp_free(self);
2599 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2601 PyObject *py_ret = NULL;
2603 if (self->state.req == NULL) {
2604 PyErr_SetString(PyExc_RuntimeError,
2605 "ldb.SearchIterator request already finished");
2610 * TODO: do we want a non-blocking mode?
2611 * In future we may add an optional 'nonblocking'
2612 * argument to search_iterator().
2614 * For now we keep it simple and wait for at
2618 while (self->state.next == NULL) {
2621 if (self->state.result != NULL) {
2623 * We (already) got a final result from the server.
2625 * We stop the iteration and let
2626 * py_ldb_search_iterator_result() will deliver
2627 * the result details.
2629 TALLOC_FREE(self->state.req);
2630 PyErr_SetNone(PyExc_StopIteration);
2634 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2635 if (ret != LDB_SUCCESS) {
2636 struct ldb_context *ldb_ctx;
2637 TALLOC_FREE(self->state.req);
2638 ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb);
2640 * We stop the iteration and let
2641 * py_ldb_search_iterator_result() will deliver
2644 self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2645 ret, ldb_errstring(ldb_ctx));
2646 PyErr_SetNone(PyExc_StopIteration);
2651 py_ret = self->state.next->obj;
2652 self->state.next->obj = NULL;
2653 /* no TALLOC_FREE() as self->state.next is a list */
2654 talloc_free(self->state.next);
2658 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self)
2660 PyObject *py_ret = NULL;
2662 if (self->state.req != NULL) {
2663 PyErr_SetString(PyExc_RuntimeError,
2664 "ldb.SearchIterator request running");
2668 if (self->state.next != NULL) {
2669 PyErr_SetString(PyExc_RuntimeError,
2670 "ldb.SearchIterator not fully consumed.");
2674 if (self->state.exception != NULL) {
2675 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2676 self->state.exception = NULL;
2680 if (self->state.result == NULL) {
2681 PyErr_SetString(PyExc_RuntimeError,
2682 "ldb.SearchIterator result already consumed");
2686 py_ret = self->state.result->obj;
2687 self->state.result->obj = NULL;
2688 TALLOC_FREE(self->state.result);
2692 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self)
2694 if (self->state.req == NULL) {
2695 PyErr_SetString(PyExc_RuntimeError,
2696 "ldb.SearchIterator request already finished");
2700 Py_XDECREF(self->state.exception);
2701 TALLOC_FREE(self->mem_ctx);
2702 ZERO_STRUCT(self->state);
2706 static PyMethodDef py_ldb_search_iterator_methods[] = {
2707 { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2708 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2709 { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2714 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2716 return PyStr_FromString("<ldb search iterator>");
2719 static PyTypeObject PyLdbSearchIterator = {
2720 .tp_name = "ldb.SearchIterator",
2721 .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2722 .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2723 .tp_iter = PyObject_SelfIter,
2724 .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2725 .tp_methods = py_ldb_search_iterator_methods,
2726 .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2727 .tp_doc = "LDB search_iterator.",
2728 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2731 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2733 return PyStr_FromFormat("<ldb module '%s'>",
2734 pyldb_Module_AsModule(self)->ops->name);
2737 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2739 return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
2742 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2744 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2748 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2750 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2754 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2756 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2760 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2762 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2764 struct ldb_request *req;
2765 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2766 struct ldb_module *mod;
2767 const char * const*attrs;
2769 /* type "int" rather than "enum" for "scope" is intentional */
2770 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2771 discard_const_p(char *, kwnames),
2772 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2777 if (py_attrs == Py_None) {
2780 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2785 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2786 scope, NULL /* expr */, attrs,
2787 NULL /* controls */, NULL, NULL, NULL);
2789 talloc_steal(req, attrs);
2791 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2793 req->op.search.res = NULL;
2795 ret = mod->ops->search(mod, req);
2797 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2799 py_ret = PyLdbResult_FromResult(req->op.search.res);
2807 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2809 struct ldb_request *req;
2810 PyObject *py_message;
2812 struct ldb_module *mod;
2814 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2817 req = talloc_zero(NULL, struct ldb_request);
2818 req->operation = LDB_ADD;
2819 req->op.add.message = pyldb_Message_AsMessage(py_message);
2821 mod = pyldb_Module_AsModule(self);
2822 ret = mod->ops->add(mod, req);
2824 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2829 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2832 struct ldb_request *req;
2833 PyObject *py_message;
2834 struct ldb_module *mod;
2836 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2839 req = talloc_zero(NULL, struct ldb_request);
2840 req->operation = LDB_MODIFY;
2841 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2843 mod = pyldb_Module_AsModule(self);
2844 ret = mod->ops->modify(mod, req);
2846 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2851 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2854 struct ldb_request *req;
2857 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2860 req = talloc_zero(NULL, struct ldb_request);
2861 req->operation = LDB_DELETE;
2862 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2864 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2866 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2871 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2874 struct ldb_request *req;
2875 PyObject *py_dn1, *py_dn2;
2877 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2880 req = talloc_zero(NULL, struct ldb_request);
2882 req->operation = LDB_RENAME;
2883 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2884 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2886 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2888 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2893 static PyMethodDef py_ldb_module_methods[] = {
2894 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2895 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2896 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2897 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2898 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2899 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2900 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2901 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2905 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2907 talloc_free(self->mem_ctx);
2911 static PyTypeObject PyLdbModule = {
2912 .tp_name = "ldb.LdbModule",
2913 .tp_methods = py_ldb_module_methods,
2914 .tp_repr = (reprfunc)py_ldb_module_repr,
2915 .tp_str = (reprfunc)py_ldb_module_str,
2916 .tp_basicsize = sizeof(PyLdbModuleObject),
2917 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2918 .tp_flags = Py_TPFLAGS_DEFAULT,
2919 .tp_doc = "LDB module (extension)",
2924 * Create a ldb_message_element from a Python object.
2926 * This will accept any sequence objects that contains strings, or
2929 * A reference to set_obj will be borrowed.
2931 * @param mem_ctx Memory context
2932 * @param set_obj Python object to convert
2933 * @param flags ldb_message_element flags to set
2934 * @param attr_name Name of the attribute
2935 * @return New ldb_message_element, allocated as child of mem_ctx
2937 static struct ldb_message_element *PyObject_AsMessageElement(
2938 TALLOC_CTX *mem_ctx,
2941 const char *attr_name)
2943 struct ldb_message_element *me;
2944 const char *msg = NULL;
2948 if (pyldb_MessageElement_Check(set_obj)) {
2949 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2950 /* We have to talloc_reference() the memory context, not the pointer
2951 * which may not actually be it's own context */
2952 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2953 return pyldb_MessageElement_AsMessageElement(set_obj);
2958 me = talloc(mem_ctx, struct ldb_message_element);
2964 me->name = talloc_strdup(me, attr_name);
2966 if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) {
2968 me->values = talloc_array(me, struct ldb_val, me->num_values);
2969 if (PyBytes_Check(set_obj)) {
2971 result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
2978 msg = PyStr_AsUTF8AndSize(set_obj, &size);
2984 me->values[0].data = talloc_memdup(me,
2985 (const uint8_t *)msg,
2987 me->values[0].length = size;
2988 } else if (PySequence_Check(set_obj)) {
2990 me->num_values = PySequence_Size(set_obj);
2991 me->values = talloc_array(me, struct ldb_val, me->num_values);
2992 for (i = 0; i < me->num_values; i++) {
2993 PyObject *obj = PySequence_GetItem(set_obj, i);
2994 if (PyBytes_Check(obj)) {
2996 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
3002 } else if (PyUnicode_Check(obj)) {
3003 msg = PyStr_AsUTF8AndSize(obj, &size);
3009 PyErr_Format(PyExc_TypeError,
3010 "Expected string as element %zd in list", i);
3014 me->values[i].data = talloc_memdup(me,
3015 (const uint8_t *)msg,
3017 me->values[i].length = size;
3020 PyErr_Format(PyExc_TypeError,
3021 "String or List type expected for '%s' attribute", attr_name);
3030 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
3031 struct ldb_message_element *me)
3036 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3037 result = PyList_New(me->num_values);
3039 for (i = 0; i < me->num_values; i++) {
3040 PyList_SetItem(result, i,
3041 PyObject_FromLdbValue(&me->values[i]));
3047 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
3050 if (!PyArg_ParseTuple(args, "I", &i))
3052 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
3055 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
3058 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
3060 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3061 return PyInt_FromLong(el->flags);
3064 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
3067 struct ldb_message_element *el;
3068 if (!PyArg_ParseTuple(args, "I", &flags))
3071 el = pyldb_MessageElement_AsMessageElement(self);
3076 static PyMethodDef py_ldb_msg_element_methods[] = {
3077 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
3078 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
3079 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
3083 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
3085 return pyldb_MessageElement_AsMessageElement(self)->num_values;
3088 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
3090 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3091 if (idx < 0 || idx >= el->num_values) {
3092 PyErr_SetString(PyExc_IndexError, "Out of range");
3095 return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
3098 static PySequenceMethods py_ldb_msg_element_seq = {
3099 .sq_length = (lenfunc)py_ldb_msg_element_len,
3100 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
3103 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3106 if (!pyldb_MessageElement_Check(other)) {
3107 Py_INCREF(Py_NotImplemented);
3108 return Py_NotImplemented;
3110 ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3111 pyldb_MessageElement_AsMessageElement(other));
3112 return richcmp(ret, op);
3115 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3117 PyObject *el = ldb_msg_element_to_set(NULL,
3118 pyldb_MessageElement_AsMessageElement(self));
3119 PyObject *ret = PyObject_GetIter(el);
3124 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3126 PyLdbMessageElementObject *ret;
3127 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3132 ret->mem_ctx = talloc_new(NULL);
3133 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
3138 return (PyObject *)ret;
3141 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3143 PyObject *py_elements = NULL;
3144 struct ldb_message_element *el;
3145 unsigned int flags = 0;
3147 const char * const kwnames[] = { "elements", "flags", "name", NULL };
3148 PyLdbMessageElementObject *ret;
3149 TALLOC_CTX *mem_ctx;
3150 const char *msg = NULL;
3154 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3155 discard_const_p(char *, kwnames),
3156 &py_elements, &flags, &name))
3159 mem_ctx = talloc_new(NULL);
3160 if (mem_ctx == NULL) {
3165 el = talloc_zero(mem_ctx, struct ldb_message_element);
3168 talloc_free(mem_ctx);
3172 if (py_elements != NULL) {
3174 if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) {
3177 el->values = talloc_array(el, struct ldb_val, 1);
3178 if (el->values == NULL) {
3179 talloc_free(mem_ctx);
3183 if (PyBytes_Check(py_elements)) {
3184 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3187 msg = PyStr_AsUTF8AndSize(py_elements, &size);
3188 result = (msg == NULL) ? -1 : 0;
3191 talloc_free(mem_ctx);
3194 el->values[0].data = talloc_memdup(el->values,
3195 (const uint8_t *)msg, size + 1);
3196 el->values[0].length = size;
3197 } else if (PySequence_Check(py_elements)) {
3198 el->num_values = PySequence_Size(py_elements);
3199 el->values = talloc_array(el, struct ldb_val, el->num_values);
3200 if (el->values == NULL) {
3201 talloc_free(mem_ctx);
3205 for (i = 0; i < el->num_values; i++) {
3206 PyObject *item = PySequence_GetItem(py_elements, i);
3208 talloc_free(mem_ctx);
3211 if (PyBytes_Check(item)) {
3213 result = PyBytes_AsStringAndSize(item, &_msg, &size);
3215 } else if (PyUnicode_Check(item)) {
3216 msg = PyStr_AsUTF8AndSize(item, &size);
3217 result = (msg == NULL) ? -1 : 0;
3219 PyErr_Format(PyExc_TypeError,
3220 "Expected string as element %zd in list", i);
3224 talloc_free(mem_ctx);
3227 el->values[i].data = talloc_memdup(el,
3228 (const uint8_t *)msg, size+1);
3229 el->values[i].length = size;
3232 PyErr_SetString(PyExc_TypeError,
3233 "Expected string or list");
3234 talloc_free(mem_ctx);
3240 el->name = talloc_strdup(el, name);