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 /* discard signature of 'func' in favour of 'target_sig' */
38 #define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func
40 struct py_ldb_search_iterator_reply;
47 struct ldb_request *req;
48 struct py_ldb_search_iterator_reply *next;
49 struct py_ldb_search_iterator_reply *result;
52 } PyLdbSearchIteratorObject;
54 struct py_ldb_search_iterator_reply {
55 struct py_ldb_search_iterator_reply *prev, *next;
56 PyLdbSearchIteratorObject *py_iter;
61 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
62 static PyObject *PyExc_LdbError;
64 static PyTypeObject PyLdbControl;
65 static PyTypeObject PyLdbResult;
66 static PyTypeObject PyLdbSearchIterator;
67 static PyTypeObject PyLdbMessage;
68 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
69 static PyTypeObject PyLdbModule;
70 static PyTypeObject PyLdbDn;
71 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
72 static PyTypeObject PyLdb;
73 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
74 static PyTypeObject PyLdbMessageElement;
75 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
77 static PyTypeObject PyLdbTree;
78 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
79 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
80 static struct ldb_message_element *PyObject_AsMessageElement(
84 const char *attr_name);
85 static PyTypeObject PyLdbBytesType;
87 #if PY_MAJOR_VERSION >= 3
88 #define PyInt_FromLong PyLong_FromLong
90 #define PYARG_STR_UNI "es"
92 static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size)
94 PyObject* result = NULL;
95 PyObject* args = NULL;
96 args = Py_BuildValue("(y#)", msg, size);
97 result = PyLdbBytesType.tp_new(&PyLdbBytesType, args, NULL);
102 #define PyLdbBytes_FromStringAndSize PyString_FromStringAndSize
104 #define PYARG_STR_UNI "et"
108 static PyObject *richcmp(int cmp_val, int op)
112 case Py_LT: ret = cmp_val < 0; break;
113 case Py_LE: ret = cmp_val <= 0; break;
114 case Py_EQ: ret = cmp_val == 0; break;
115 case Py_NE: ret = cmp_val != 0; break;
116 case Py_GT: ret = cmp_val > 0; break;
117 case Py_GE: ret = cmp_val >= 0; break;
119 Py_INCREF(Py_NotImplemented);
120 return Py_NotImplemented;
122 return PyBool_FromLong(ret);
126 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
128 if (self->data != NULL) {
129 char* control = ldb_control_to_string(self->mem_ctx, self->data);
130 if (control == NULL) {
134 return PyUnicode_FromString(control);
136 return PyUnicode_FromString("ldb control");
140 static void py_ldb_control_dealloc(PyLdbControlObject *self)
142 if (self->mem_ctx != NULL) {
143 talloc_free(self->mem_ctx);
146 Py_TYPE(self)->tp_free(self);
149 /* Create a text (rather than bytes) interface for a LDB result object */
150 static PyObject *wrap_text(const char *type, PyObject *wrapped)
152 PyObject *mod, *cls, *constructor, *inst;
153 mod = PyImport_ImportModule("_ldb_text");
156 cls = PyObject_GetAttrString(mod, type);
162 constructor = PyObject_GetAttrString(cls, "_wrap");
164 if (constructor == NULL) {
167 inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped);
168 Py_DECREF(constructor);
172 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self,
173 PyObject *Py_UNUSED(ignored))
175 return PyUnicode_FromString(self->data->oid);
178 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self,
179 PyObject *Py_UNUSED(ignored))
181 return PyBool_FromLong(self->data->critical);
184 static int py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
186 if (PyObject_IsTrue(value)) {
187 self->data->critical = true;
189 self->data->critical = false;
194 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
197 const char * const kwnames[] = { "ldb", "data", NULL };
198 struct ldb_control *parsed_controls;
199 PyLdbControlObject *ret;
202 struct ldb_context *ldb_ctx;
204 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
205 discard_const_p(char *, kwnames),
206 &PyLdb, &py_ldb, &data))
209 mem_ctx = talloc_new(NULL);
210 if (mem_ctx == NULL) {
215 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
216 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
218 if (!parsed_controls) {
219 talloc_free(mem_ctx);
220 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
224 ret = PyObject_New(PyLdbControlObject, type);
227 talloc_free(mem_ctx);
231 ret->mem_ctx = mem_ctx;
233 ret->data = talloc_move(mem_ctx, &parsed_controls);
234 if (ret->data == NULL) {
237 talloc_free(mem_ctx);
241 return (PyObject *)ret;
244 static PyGetSetDef py_ldb_control_getset[] = {
246 .name = discard_const_p(char, "oid"),
247 .get = (getter)py_ldb_control_get_oid,
250 .name = discard_const_p(char, "critical"),
251 .get = (getter)py_ldb_control_get_critical,
252 .set = (setter)py_ldb_control_set_critical,
257 static PyTypeObject PyLdbControl = {
258 .tp_name = "ldb.control",
259 .tp_dealloc = (destructor)py_ldb_control_dealloc,
260 .tp_getattro = PyObject_GenericGetAttr,
261 .tp_basicsize = sizeof(PyLdbControlObject),
262 .tp_getset = py_ldb_control_getset,
263 .tp_doc = "LDB control.",
264 .tp_str = (reprfunc)py_ldb_control_str,
265 .tp_new = py_ldb_control_new,
266 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
269 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
271 if (ret == LDB_ERR_PYTHON_EXCEPTION)
272 return; /* Python exception should already be set, just keep that */
274 PyErr_SetObject(error,
275 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
276 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
278 static PyObject *py_ldb_bytes_str(PyBytesObject *self)
283 if (!PyBytes_Check(self)) {
284 PyErr_Format(PyExc_TypeError,"Unexpected type");
287 result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size);
289 PyErr_Format(PyExc_TypeError, "Failed to extract bytes");
292 return PyUnicode_FromStringAndSize(msg, size);
295 static PyTypeObject PyLdbBytesType = {
296 PyVarObject_HEAD_INIT(NULL, 0)
297 .tp_name = "ldb.bytes",
298 .tp_doc = "str/bytes (with custom str)",
299 .tp_str = (reprfunc)py_ldb_bytes_str,
300 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
303 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
305 return PyLdbBytes_FromStringAndSize((const char *)val->data, val->length);
308 static PyObject *PyStr_FromLdbValue(const struct ldb_val *val)
310 return PyUnicode_FromStringAndSize((const char *)val->data, val->length);
314 * Create a Python object from a ldb_result.
316 * @param result LDB result to convert
317 * @return Python object with converted result (a list object)
319 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
321 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
322 PyLdbControlObject *ctrl;
323 if (ctl_ctx == NULL) {
328 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
330 talloc_free(ctl_ctx);
334 ctrl->mem_ctx = ctl_ctx;
335 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
336 if (ctrl->data == NULL) {
341 return (PyObject*) ctrl;
345 * Create a Python object from a ldb_result.
347 * @param result LDB result to convert
348 * @return Python object with converted result (a list object)
350 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
352 PyLdbResultObject *ret;
353 PyObject *list, *controls, *referals;
356 if (result == NULL) {
360 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
366 list = PyList_New(result->count);
373 for (i = 0; i < result->count; i++) {
374 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
377 ret->mem_ctx = talloc_new(NULL);
378 if (ret->mem_ctx == NULL) {
387 if (result->controls) {
389 while (result->controls[i]) {
392 controls = PyList_New(i);
393 if (controls == NULL) {
398 for (i=0; result->controls[i]; i++) {
399 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
406 PyList_SetItem(controls, i, ctrl);
410 * No controls so we keep an empty list
412 controls = PyList_New(0);
413 if (controls == NULL) {
420 ret->controls = controls;
424 while (result->refs && result->refs[i]) {
428 referals = PyList_New(i);
429 if (referals == NULL) {
435 for (i = 0;result->refs && result->refs[i]; i++) {
436 PyList_SetItem(referals, i, PyUnicode_FromString(result->refs[i]));
438 ret->referals = referals;
439 return (PyObject *)ret;
443 * Create a LDB Result from a Python object.
444 * If conversion fails, NULL will be returned and a Python exception set.
446 * Note: the result object only includes the messages at the moment; extended
447 * result, controls and referrals are ignored.
449 * @param mem_ctx Memory context in which to allocate the LDB Result
450 * @param obj Python object to convert
451 * @return a ldb_result, or NULL if the conversion failed
453 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
456 struct ldb_result *res;
462 res = talloc_zero(mem_ctx, struct ldb_result);
463 res->count = PyList_Size(obj);
464 res->msgs = talloc_array(res, struct ldb_message *, res->count);
465 for (i = 0; i < res->count; i++) {
466 PyObject *item = PyList_GetItem(obj, i);
467 res->msgs[i] = pyldb_Message_AsMessage(item);
472 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self,
473 PyObject *Py_UNUSED(ignored))
475 return PyBool_FromLong(ldb_dn_validate(self->dn));
478 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self,
479 PyObject *Py_UNUSED(ignored))
481 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
484 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self,
485 PyObject *Py_UNUSED(ignored))
487 return PyBool_FromLong(ldb_dn_is_special(self->dn));
490 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self,
491 PyObject *Py_UNUSED(ignored))
493 return PyBool_FromLong(ldb_dn_is_null(self->dn));
496 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self,
497 PyObject *Py_UNUSED(ignored))
499 return PyUnicode_FromString(ldb_dn_get_casefold(self->dn));
502 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
504 return PyUnicode_FromString(ldb_dn_get_linearized(self->dn));
507 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self,
508 PyObject *Py_UNUSED(ignored))
510 return PyUnicode_FromString(ldb_dn_canonical_string(self->dn, self->dn));
513 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self,
514 PyObject *Py_UNUSED(ignored))
516 return PyUnicode_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
519 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
521 const char * const kwnames[] = { "mode", NULL };
523 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
524 discard_const_p(char *, kwnames),
527 return PyUnicode_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
530 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
533 const struct ldb_val *val;
535 if (!PyArg_ParseTuple(args, "s", &name))
537 val = ldb_dn_get_extended_component(self->dn, name);
542 return PyBytes_FromStringAndSize((const char *)val->data, val->length);
545 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
549 uint8_t *value = NULL;
552 if (!PyArg_ParseTuple(args, "sz#", &name, (char **)&value, &size))
556 err = ldb_dn_set_extended_component(self->dn, name, NULL);
559 val.data = (uint8_t *)value;
561 err = ldb_dn_set_extended_component(self->dn, name, &val);
564 if (err != LDB_SUCCESS) {
565 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
572 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
574 PyObject *str = PyUnicode_FromString(ldb_dn_get_linearized(self->dn));
575 PyObject *repr, *result;
578 repr = PyObject_Repr(str);
583 result = PyUnicode_FromFormat("Dn(%s)", PyUnicode_AsUTF8(repr));
589 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
593 if (!PyArg_ParseTuple(args, "s", &name))
596 return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
599 static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
602 if (!pyldb_Dn_Check(dn2)) {
603 Py_INCREF(Py_NotImplemented);
604 return Py_NotImplemented;
606 ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2));
607 return richcmp(ret, op);
610 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self,
611 PyObject *Py_UNUSED(ignored))
613 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
614 struct ldb_dn *parent;
615 PyLdbDnObject *py_ret;
616 TALLOC_CTX *mem_ctx = talloc_new(NULL);
618 parent = ldb_dn_get_parent(mem_ctx, dn);
619 if (parent == NULL) {
620 talloc_free(mem_ctx);
624 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
625 if (py_ret == NULL) {
627 talloc_free(mem_ctx);
630 py_ret->mem_ctx = mem_ctx;
632 return (PyObject *)py_ret;
635 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
638 struct ldb_dn *dn, *other;
639 if (!PyArg_ParseTuple(args, "O", &py_other))
642 dn = pyldb_Dn_AsDn((PyObject *)self);
644 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
647 return PyBool_FromLong(ldb_dn_add_child(dn, other));
650 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
653 struct ldb_dn *other, *dn;
654 if (!PyArg_ParseTuple(args, "O", &py_other))
657 dn = pyldb_Dn_AsDn((PyObject *)self);
659 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
662 return PyBool_FromLong(ldb_dn_add_base(dn, other));
665 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
669 if (!PyArg_ParseTuple(args, "i", &i))
672 dn = pyldb_Dn_AsDn((PyObject *)self);
674 return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
677 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
680 struct ldb_dn *dn, *base;
681 if (!PyArg_ParseTuple(args, "O", &py_base))
684 dn = pyldb_Dn_AsDn((PyObject *)self);
686 if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
689 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
692 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
696 unsigned int num = 0;
698 if (!PyArg_ParseTuple(args, "I", &num))
701 dn = pyldb_Dn_AsDn((PyObject *)self);
703 name = ldb_dn_get_component_name(dn, num);
708 return PyUnicode_FromString(name);
711 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
714 const struct ldb_val *val;
715 unsigned int num = 0;
717 if (!PyArg_ParseTuple(args, "I", &num))
720 dn = pyldb_Dn_AsDn((PyObject *)self);
722 val = ldb_dn_get_component_val(dn, num);
727 return PyStr_FromLdbValue(val);
730 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
732 unsigned int num = 0;
733 char *name = NULL, *value = NULL;
734 struct ldb_val val = { NULL, };
738 if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size))
741 val.data = (unsigned char*) value;
744 err = ldb_dn_set_component(self->dn, num, name, val);
745 if (err != LDB_SUCCESS) {
746 PyErr_SetString(PyExc_TypeError, "Failed to set component");
753 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self,
754 PyObject *Py_UNUSED(ignored))
759 dn = pyldb_Dn_AsDn((PyObject *)self);
761 name = ldb_dn_get_rdn_name(dn);
766 return PyUnicode_FromString(name);
769 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self,
770 PyObject *Py_UNUSED(ignored))
773 const struct ldb_val *val;
775 dn = pyldb_Dn_AsDn((PyObject *)self);
777 val = ldb_dn_get_rdn_val(dn);
782 return PyStr_FromLdbValue(val);
785 static PyMethodDef py_ldb_dn_methods[] = {
786 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
787 "S.validate() -> bool\n"
788 "Validate DN is correct." },
789 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
790 "S.is_valid() -> bool\n" },
791 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
792 "S.is_special() -> bool\n"
793 "Check whether this is a special LDB DN." },
794 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
795 "Check whether this is a null DN." },
796 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
798 { "get_linearized", PY_DISCARD_FUNC_SIG(PyCFunction,
799 py_ldb_dn_get_linearized),
802 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
803 "S.canonical_str() -> string\n"
804 "Canonical version of this DN (like a posix path)." },
805 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
806 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
807 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
808 "S.canonical_ex_str() -> string\n"
809 "Canonical version of this DN (like a posix path, with terminating newline)." },
810 { "extended_str", PY_DISCARD_FUNC_SIG(PyCFunction,
811 py_ldb_dn_extended_str),
812 METH_VARARGS | METH_KEYWORDS,
813 "S.extended_str(mode=1) -> string\n"
814 "Extended version of this DN" },
815 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
817 "Get the parent for this DN." },
818 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
819 "S.add_child(dn) -> None\n"
820 "Add a child DN to this DN." },
821 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
822 "S.add_base(dn) -> None\n"
823 "Add a base DN to this DN." },
824 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
825 "S.remove_base_components(int) -> bool\n"
826 "Remove a number of DN components from the base of this DN." },
827 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
828 "S.check_special(name) -> bool\n\n"
829 "Check if name is a special DN name"},
830 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
831 "S.get_extended_component(name) -> string\n\n"
832 "returns a DN extended component as a binary string"},
833 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
834 "S.set_extended_component(name, value) -> None\n\n"
835 "set a DN extended component as a binary string"},
836 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
837 "S.get_component_name(num) -> string\n"
838 "get the attribute name of the specified component" },
839 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
840 "S.get_component_value(num) -> string\n"
841 "get the attribute value of the specified component as a binary string" },
842 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
843 "S.get_component_value(num, name, value) -> None\n"
844 "set the attribute name and value of the specified component" },
845 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
846 "S.get_rdn_name() -> string\n"
847 "get the RDN attribute name" },
848 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
849 "S.get_rdn_value() -> string\n"
850 "get the RDN attribute value as a binary string" },
854 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
856 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
860 copy a DN as a python object
862 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
864 PyLdbDnObject *py_ret;
866 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
867 if (py_ret == NULL) {
871 py_ret->mem_ctx = talloc_new(NULL);
872 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
873 return (PyObject *)py_ret;
876 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
878 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
880 PyLdbDnObject *py_ret;
882 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
885 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
886 if (py_ret == NULL) {
890 py_ret->mem_ctx = talloc_new(NULL);
891 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
892 ldb_dn_add_base(py_ret->dn, other);
893 return (PyObject *)py_ret;
896 static PySequenceMethods py_ldb_dn_seq = {
897 .sq_length = (lenfunc)py_ldb_dn_len,
898 .sq_concat = (binaryfunc)py_ldb_dn_concat,
901 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
903 struct ldb_dn *ret = NULL;
905 PyObject *py_ldb = NULL;
906 struct ldb_context *ldb_ctx = NULL;
907 TALLOC_CTX *mem_ctx = NULL;
908 PyLdbDnObject *py_ret = NULL;
909 const char * const kwnames[] = { "ldb", "dn", NULL };
911 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O"PYARG_STR_UNI,
912 discard_const_p(char *, kwnames),
913 &py_ldb, "utf8", &str))
916 if (!PyLdb_Check(py_ldb)) {
917 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
921 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
923 mem_ctx = talloc_new(NULL);
924 if (mem_ctx == NULL) {
929 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
930 if (!ldb_dn_validate(ret)) {
931 talloc_free(mem_ctx);
932 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
936 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
937 if (py_ret == NULL) {
938 talloc_free(mem_ctx);
942 py_ret->mem_ctx = mem_ctx;
946 PyMem_Free(discard_const_p(char, str));
948 return (PyObject *)py_ret;
951 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
953 talloc_free(self->mem_ctx);
957 static PyTypeObject PyLdbDn = {
959 .tp_methods = py_ldb_dn_methods,
960 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
961 .tp_repr = (reprfunc)py_ldb_dn_repr,
962 .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp,
963 .tp_as_sequence = &py_ldb_dn_seq,
964 .tp_doc = "A LDB distinguished name.",
965 .tp_new = py_ldb_dn_new,
966 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
967 .tp_basicsize = sizeof(PyLdbDnObject),
968 .tp_flags = Py_TPFLAGS_DEFAULT,
972 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
973 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
975 PyObject *fn = (PyObject *)context;
976 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyUnicode_FromFormatV(fmt, ap));
979 static PyObject *py_ldb_debug_func;
981 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
984 struct ldb_context *ldb_ctx;
986 if (!PyArg_ParseTuple(args, "O", &cb))
989 if (py_ldb_debug_func != NULL) {
990 Py_DECREF(py_ldb_debug_func);
994 /* FIXME: DECREF cb when exiting program */
995 py_ldb_debug_func = cb;
996 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
997 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
998 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
1004 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
1007 if (!PyArg_ParseTuple(args, "I", &perms))
1010 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
1015 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
1018 if (!PyArg_ParseTuple(args, "s", &modules_dir))
1021 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
1026 static PyObject *py_ldb_transaction_start(PyLdbObject *self,
1027 PyObject *Py_UNUSED(ignored))
1029 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1031 ldb_err = ldb_transaction_start(ldb_ctx);
1032 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1036 static PyObject *py_ldb_transaction_commit(PyLdbObject *self,
1037 PyObject *Py_UNUSED(ignored))
1039 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1041 ldb_err = ldb_transaction_commit(ldb_ctx);
1042 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1046 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self,
1047 PyObject *Py_UNUSED(ignored))
1049 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1051 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
1052 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1056 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self,
1057 PyObject *Py_UNUSED(ignored))
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,
1067 PyObject *Py_UNUSED(ignored))
1069 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1071 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
1072 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1076 static PyObject *py_ldb_repr(PyLdbObject *self)
1078 return PyUnicode_FromString("<ldb connection>");
1081 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self,
1082 PyObject *Py_UNUSED(ignored))
1084 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
1087 return py_ldb_dn_copy(dn);
1091 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self,
1092 PyObject *Py_UNUSED(ignored))
1094 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
1097 return py_ldb_dn_copy(dn);
1100 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self,
1101 PyObject *Py_UNUSED(ignored))
1103 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
1106 return py_ldb_dn_copy(dn);
1109 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self,
1110 PyObject *Py_UNUSED(ignored))
1112 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
1115 return py_ldb_dn_copy(dn);
1118 static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
1119 const char *paramname)
1123 if (!PyList_Check(list)) {
1124 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
1127 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1133 for (i = 0; i < PyList_Size(list); i++) {
1134 const char *str = NULL;
1136 PyObject *item = PyList_GetItem(list, i);
1137 if (!PyUnicode_Check(item)) {
1138 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
1142 str = PyUnicode_AsUTF8AndSize(item, &size);
1147 ret[i] = talloc_strndup(ret, str, size);
1153 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1155 const char * const kwnames[] = { "url", "flags", "options", NULL };
1157 PyObject *py_options = Py_None;
1158 const char **options;
1159 unsigned int flags = 0;
1161 struct ldb_context *ldb;
1163 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1164 discard_const_p(char *, kwnames),
1165 &url, &flags, &py_options))
1168 ldb = pyldb_Ldb_AsLdbContext(self);
1170 if (py_options == Py_None) {
1173 options = PyList_AsStrList(ldb, py_options, "options");
1174 if (options == NULL)
1179 ret = ldb_connect(ldb, url, flags, options);
1180 if (ret != LDB_SUCCESS) {
1181 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1185 ldb_set_flags(ldb, flags);
1188 talloc_free(options);
1192 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1195 struct ldb_context *ldb;
1196 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1201 ret->mem_ctx = talloc_new(NULL);
1202 ldb = ldb_init(ret->mem_ctx, NULL);
1210 return (PyObject *)ret;
1213 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1216 unsigned int flags = 0;
1217 PyObject *py_options = Py_None;
1219 const char **options;
1220 const char * const kwnames[] = { "url", "flags", "options", NULL };
1221 struct ldb_context *ldb_ctx;
1223 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|IO",
1224 discard_const_p(char *, kwnames),
1225 &url, &flags, &py_options))
1228 if (py_options == Py_None) {
1231 options = PyList_AsStrList(NULL, py_options, "options");
1232 if (options == NULL)
1236 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1237 ret = ldb_connect(ldb_ctx, url, flags, options);
1238 talloc_free(options);
1240 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1245 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1248 PyObject *py_controls = Py_None;
1249 struct ldb_context *ldb_ctx;
1250 struct ldb_request *req;
1251 struct ldb_control **parsed_controls;
1252 struct ldb_message *msg;
1254 TALLOC_CTX *mem_ctx;
1256 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1258 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1259 discard_const_p(char *, kwnames),
1260 &py_msg, &py_controls, &validate))
1263 mem_ctx = talloc_new(NULL);
1264 if (mem_ctx == NULL) {
1268 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1270 if (py_controls == Py_None) {
1271 parsed_controls = NULL;
1273 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1274 if (controls == NULL) {
1275 talloc_free(mem_ctx);
1278 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1279 talloc_free(controls);
1282 if (!PyLdbMessage_Check(py_msg)) {
1283 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1284 talloc_free(mem_ctx);
1287 msg = pyldb_Message_AsMessage(py_msg);
1290 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1291 if (ret != LDB_SUCCESS) {
1292 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1293 talloc_free(mem_ctx);
1298 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1299 NULL, ldb_op_default_callback, NULL);
1300 if (ret != LDB_SUCCESS) {
1301 PyErr_SetString(PyExc_TypeError, "failed to build request");
1302 talloc_free(mem_ctx);
1306 /* do request and autostart a transaction */
1307 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1309 ret = ldb_transaction_start(ldb_ctx);
1310 if (ret != LDB_SUCCESS) {
1311 talloc_free(mem_ctx);
1312 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1316 ret = ldb_request(ldb_ctx, req);
1317 if (ret == LDB_SUCCESS) {
1318 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1321 if (ret == LDB_SUCCESS) {
1322 ret = ldb_transaction_commit(ldb_ctx);
1324 ldb_transaction_cancel(ldb_ctx);
1327 talloc_free(mem_ctx);
1328 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1335 * Obtain a ldb message from a Python Dictionary object.
1337 * @param mem_ctx Memory context
1338 * @param py_obj Python Dictionary object
1339 * @param ldb_ctx LDB context
1340 * @param mod_flags Flags to be set on every message element
1341 * @return ldb_message on success or NULL on failure
1343 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1345 struct ldb_context *ldb_ctx,
1346 unsigned int mod_flags)
1348 struct ldb_message *msg;
1349 unsigned int msg_pos = 0;
1350 Py_ssize_t dict_pos = 0;
1351 PyObject *key, *value;
1352 struct ldb_message_element *msg_el;
1353 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1355 msg = ldb_msg_new(mem_ctx);
1360 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1363 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1364 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1367 if (msg->dn == NULL) {
1368 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1372 PyErr_SetString(PyExc_TypeError, "no dn set");
1376 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1377 const char *key_str = PyUnicode_AsUTF8(key);
1378 if (ldb_attr_cmp(key_str, "dn") != 0) {
1379 msg_el = PyObject_AsMessageElement(msg->elements, value,
1380 mod_flags, key_str);
1381 if (msg_el == NULL) {
1382 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1385 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1390 msg->num_elements = msg_pos;
1395 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1399 struct ldb_context *ldb_ctx;
1400 struct ldb_request *req;
1401 struct ldb_message *msg = NULL;
1402 PyObject *py_controls = Py_None;
1403 TALLOC_CTX *mem_ctx;
1404 struct ldb_control **parsed_controls;
1405 const char * const kwnames[] = { "message", "controls", NULL };
1407 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1408 discard_const_p(char *, kwnames),
1409 &py_obj, &py_controls))
1412 mem_ctx = talloc_new(NULL);
1413 if (mem_ctx == NULL) {
1417 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1419 if (py_controls == Py_None) {
1420 parsed_controls = NULL;
1422 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1423 if (controls == NULL) {
1424 talloc_free(mem_ctx);
1427 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1428 talloc_free(controls);
1431 if (PyLdbMessage_Check(py_obj)) {
1432 msg = pyldb_Message_AsMessage(py_obj);
1433 } else if (PyDict_Check(py_obj)) {
1434 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1436 PyErr_SetString(PyExc_TypeError,
1437 "Dictionary or LdbMessage object expected!");
1441 /* we should have a PyErr already set */
1442 talloc_free(mem_ctx);
1446 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1447 if (ret != LDB_SUCCESS) {
1448 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1449 talloc_free(mem_ctx);
1453 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1454 NULL, ldb_op_default_callback, NULL);
1455 if (ret != LDB_SUCCESS) {
1456 PyErr_SetString(PyExc_TypeError, "failed to build request");
1457 talloc_free(mem_ctx);
1461 /* do request and autostart a transaction */
1462 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1464 ret = ldb_transaction_start(ldb_ctx);
1465 if (ret != LDB_SUCCESS) {
1466 talloc_free(mem_ctx);
1467 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1471 ret = ldb_request(ldb_ctx, req);
1472 if (ret == LDB_SUCCESS) {
1473 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1476 if (ret == LDB_SUCCESS) {
1477 ret = ldb_transaction_commit(ldb_ctx);
1479 ldb_transaction_cancel(ldb_ctx);
1482 talloc_free(mem_ctx);
1483 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1488 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1493 struct ldb_context *ldb_ctx;
1494 struct ldb_request *req;
1495 PyObject *py_controls = Py_None;
1496 TALLOC_CTX *mem_ctx;
1497 struct ldb_control **parsed_controls;
1498 const char * const kwnames[] = { "dn", "controls", NULL };
1500 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1501 discard_const_p(char *, kwnames),
1502 &py_dn, &py_controls))
1505 mem_ctx = talloc_new(NULL);
1506 if (mem_ctx == NULL) {
1510 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1512 if (py_controls == Py_None) {
1513 parsed_controls = NULL;
1515 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1516 if (controls == NULL) {
1517 talloc_free(mem_ctx);
1520 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1521 talloc_free(controls);
1524 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1525 talloc_free(mem_ctx);
1529 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1530 NULL, ldb_op_default_callback, NULL);
1531 if (ret != LDB_SUCCESS) {
1532 PyErr_SetString(PyExc_TypeError, "failed to build request");
1533 talloc_free(mem_ctx);
1537 /* do request and autostart a transaction */
1538 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1540 ret = ldb_transaction_start(ldb_ctx);
1541 if (ret != LDB_SUCCESS) {
1542 talloc_free(mem_ctx);
1543 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1547 ret = ldb_request(ldb_ctx, req);
1548 if (ret == LDB_SUCCESS) {
1549 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1552 if (ret == LDB_SUCCESS) {
1553 ret = ldb_transaction_commit(ldb_ctx);
1555 ldb_transaction_cancel(ldb_ctx);
1558 talloc_free(mem_ctx);
1559 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1564 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1566 PyObject *py_dn1, *py_dn2;
1567 struct ldb_dn *dn1, *dn2;
1569 TALLOC_CTX *mem_ctx;
1570 PyObject *py_controls = Py_None;
1571 struct ldb_control **parsed_controls;
1572 struct ldb_context *ldb_ctx;
1573 struct ldb_request *req;
1574 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1576 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1578 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1579 discard_const_p(char *, kwnames),
1580 &py_dn1, &py_dn2, &py_controls))
1584 mem_ctx = talloc_new(NULL);
1585 if (mem_ctx == NULL) {
1590 if (py_controls == Py_None) {
1591 parsed_controls = NULL;
1593 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1594 if (controls == NULL) {
1595 talloc_free(mem_ctx);
1598 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1599 talloc_free(controls);
1603 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1604 talloc_free(mem_ctx);
1608 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1609 talloc_free(mem_ctx);
1613 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1614 NULL, ldb_op_default_callback, NULL);
1615 if (ret != LDB_SUCCESS) {
1616 PyErr_SetString(PyExc_TypeError, "failed to build request");
1617 talloc_free(mem_ctx);
1621 /* do request and autostart a transaction */
1622 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1624 ret = ldb_transaction_start(ldb_ctx);
1625 if (ret != LDB_SUCCESS) {
1626 talloc_free(mem_ctx);
1627 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1631 ret = ldb_request(ldb_ctx, req);
1632 if (ret == LDB_SUCCESS) {
1633 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1636 if (ret == LDB_SUCCESS) {
1637 ret = ldb_transaction_commit(ldb_ctx);
1639 ldb_transaction_cancel(ldb_ctx);
1642 talloc_free(mem_ctx);
1643 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1648 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1651 if (!PyArg_ParseTuple(args, "s", &name))
1654 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1659 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1661 char *attribute, *syntax;
1664 struct ldb_context *ldb_ctx;
1666 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1669 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1670 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1672 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1677 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1682 /* We don't want this attached to the 'ldb' any more */
1683 PyObject *obj = PyLdbMessage_FromMessage(ldif->msg);
1685 Py_BuildValue(discard_const_p(char, "(iO)"),
1694 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1698 struct ldb_ldif ldif;
1701 TALLOC_CTX *mem_ctx;
1703 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1706 if (!PyLdbMessage_Check(py_msg)) {
1707 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1711 ldif.msg = pyldb_Message_AsMessage(py_msg);
1712 ldif.changetype = changetype;
1714 mem_ctx = talloc_new(NULL);
1716 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1718 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1722 ret = PyUnicode_FromString(string);
1724 talloc_free(mem_ctx);
1729 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1731 PyObject *list, *ret;
1732 struct ldb_ldif *ldif;
1734 struct ldb_dn *last_dn = NULL;
1736 TALLOC_CTX *mem_ctx;
1738 if (!PyArg_ParseTuple(args, "s", &s))
1741 mem_ctx = talloc_new(NULL);
1746 list = PyList_New(0);
1747 while (s && *s != '\0') {
1748 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1749 talloc_steal(mem_ctx, ldif);
1752 PyObject *py_ldif = ldb_ldif_to_pyobject(ldif);
1753 if (py_ldif == NULL) {
1755 PyErr_BadArgument();
1756 talloc_free(mem_ctx);
1759 res = PyList_Append(list, py_ldif);
1763 talloc_free(mem_ctx);
1766 last_dn = ldif->msg->dn;
1768 const char *last_dn_str = NULL;
1769 const char *err_string = NULL;
1770 if (last_dn == NULL) {
1771 PyErr_SetString(PyExc_ValueError,
1772 "unable to parse LDIF "
1773 "string at first chunk");
1775 talloc_free(mem_ctx);
1780 = ldb_dn_get_linearized(last_dn);
1783 = talloc_asprintf(mem_ctx,
1784 "unable to parse ldif "
1788 PyErr_SetString(PyExc_ValueError,
1790 talloc_free(mem_ctx);
1795 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1796 ret = PyObject_GetIter(list);
1801 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1804 PyObject *py_msg_old;
1805 PyObject *py_msg_new;
1806 struct ldb_message *diff;
1807 struct ldb_context *ldb;
1810 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1813 if (!PyLdbMessage_Check(py_msg_old)) {
1814 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1818 if (!PyLdbMessage_Check(py_msg_new)) {
1819 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1823 ldb = pyldb_Ldb_AsLdbContext(self);
1824 ldb_ret = ldb_msg_difference(ldb, ldb,
1825 pyldb_Message_AsMessage(py_msg_old),
1826 pyldb_Message_AsMessage(py_msg_new),
1828 if (ldb_ret != LDB_SUCCESS) {
1829 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1833 py_ret = PyLdbMessage_FromMessage(diff);
1835 talloc_unlink(ldb, diff);
1840 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1842 const struct ldb_schema_attribute *a;
1843 struct ldb_val old_val;
1844 struct ldb_val new_val;
1845 TALLOC_CTX *mem_ctx;
1852 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1855 result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1856 old_val.length = size;
1859 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1863 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1869 mem_ctx = talloc_new(NULL);
1870 if (mem_ctx == NULL) {
1875 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1876 talloc_free(mem_ctx);
1880 ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1882 talloc_free(mem_ctx);
1887 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1889 PyObject *py_base = Py_None;
1890 int scope = LDB_SCOPE_DEFAULT;
1892 PyObject *py_attrs = Py_None;
1893 PyObject *py_controls = Py_None;
1894 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1896 struct ldb_result *res;
1897 struct ldb_request *req;
1899 struct ldb_context *ldb_ctx;
1900 struct ldb_control **parsed_controls;
1901 struct ldb_dn *base;
1903 TALLOC_CTX *mem_ctx;
1905 /* type "int" rather than "enum" for "scope" is intentional */
1906 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1907 discard_const_p(char *, kwnames),
1908 &py_base, &scope, &expr, &py_attrs, &py_controls))
1912 mem_ctx = talloc_new(NULL);
1913 if (mem_ctx == NULL) {
1917 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1919 if (py_attrs == Py_None) {
1922 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1923 if (attrs == NULL) {
1924 talloc_free(mem_ctx);
1929 if (py_base == Py_None) {
1930 base = ldb_get_default_basedn(ldb_ctx);
1932 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1933 talloc_free(mem_ctx);
1938 if (py_controls == Py_None) {
1939 parsed_controls = NULL;
1941 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1942 if (controls == NULL) {
1943 talloc_free(mem_ctx);
1946 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1947 talloc_free(controls);
1950 res = talloc_zero(mem_ctx, struct ldb_result);
1953 talloc_free(mem_ctx);
1957 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1964 ldb_search_default_callback,
1967 if (ret != LDB_SUCCESS) {
1968 talloc_free(mem_ctx);
1969 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1973 talloc_steal(req, attrs);
1975 ret = ldb_request(ldb_ctx, req);
1977 if (ret == LDB_SUCCESS) {
1978 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1981 if (ret != LDB_SUCCESS) {
1982 talloc_free(mem_ctx);
1983 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1987 py_ret = PyLdbResult_FromResult(res);
1989 talloc_free(mem_ctx);
1994 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
1996 if (reply->py_iter != NULL) {
1997 DLIST_REMOVE(reply->py_iter->state.next, reply);
1998 if (reply->py_iter->state.result == reply) {
1999 reply->py_iter->state.result = NULL;
2001 reply->py_iter = NULL;
2004 if (reply->obj != NULL) {
2005 Py_DECREF(reply->obj);
2012 static int py_ldb_search_iterator_callback(struct ldb_request *req,
2013 struct ldb_reply *ares)
2015 PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
2016 struct ldb_result result = { .msgs = NULL };
2017 struct py_ldb_search_iterator_reply *reply = NULL;
2020 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2023 if (ares->error != LDB_SUCCESS) {
2024 int ret = ares->error;
2026 return ldb_request_done(req, ret);
2029 reply = talloc_zero(py_iter->mem_ctx,
2030 struct py_ldb_search_iterator_reply);
2031 if (reply == NULL) {
2033 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2035 reply->py_iter = py_iter;
2036 talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
2038 switch (ares->type) {
2039 case LDB_REPLY_ENTRY:
2040 reply->obj = PyLdbMessage_FromMessage(ares->message);
2041 if (reply->obj == NULL) {
2043 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2045 DLIST_ADD_END(py_iter->state.next, reply);
2049 case LDB_REPLY_REFERRAL:
2050 reply->obj = PyUnicode_FromString(ares->referral);
2051 if (reply->obj == NULL) {
2053 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2055 DLIST_ADD_END(py_iter->state.next, reply);
2059 case LDB_REPLY_DONE:
2060 result = (struct ldb_result) { .controls = ares->controls };
2061 reply->obj = PyLdbResult_FromResult(&result);
2062 if (reply->obj == NULL) {
2064 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2066 py_iter->state.result = reply;
2068 return ldb_request_done(req, LDB_SUCCESS);
2072 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2075 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2077 PyObject *py_base = Py_None;
2078 int scope = LDB_SCOPE_DEFAULT;
2081 PyObject *py_attrs = Py_None;
2082 PyObject *py_controls = Py_None;
2083 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
2086 struct ldb_context *ldb_ctx;
2087 struct ldb_control **parsed_controls;
2088 struct ldb_dn *base;
2089 PyLdbSearchIteratorObject *py_iter;
2091 /* type "int" rather than "enum" for "scope" is intentional */
2092 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
2093 discard_const_p(char *, kwnames),
2094 &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
2097 py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
2098 if (py_iter == NULL) {
2102 py_iter->ldb = self;
2104 ZERO_STRUCT(py_iter->state);
2105 py_iter->mem_ctx = talloc_new(NULL);
2106 if (py_iter->mem_ctx == NULL) {
2112 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2114 if (py_attrs == Py_None) {
2117 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2118 if (attrs == NULL) {
2125 if (py_base == Py_None) {
2126 base = ldb_get_default_basedn(ldb_ctx);
2128 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2135 if (py_controls == Py_None) {
2136 parsed_controls = NULL;
2138 const char **controls = NULL;
2140 controls = PyList_AsStrList(py_iter->mem_ctx,
2141 py_controls, "controls");
2142 if (controls == NULL) {
2148 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2151 if (controls[0] != NULL && parsed_controls == NULL) {
2156 talloc_free(controls);
2159 ret = ldb_build_search_req(&py_iter->state.req,
2168 py_ldb_search_iterator_callback,
2170 if (ret != LDB_SUCCESS) {
2172 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2176 ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2178 ret = ldb_request(ldb_ctx, py_iter->state.req);
2179 if (ret != LDB_SUCCESS) {
2181 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2185 return (PyObject *)py_iter;
2188 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2193 if (!PyArg_ParseTuple(args, "s", &name))
2196 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
2201 /* FIXME: More interpretation */
2206 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2211 if (!PyArg_ParseTuple(args, "sO", &name, &data))
2214 /* FIXME: More interpretation */
2216 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
2221 static PyObject *py_ldb_modules(PyLdbObject *self,
2222 PyObject *Py_UNUSED(ignored))
2224 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2225 PyObject *ret = PyList_New(0);
2226 struct ldb_module *mod;
2229 return PyErr_NoMemory();
2231 for (mod = ldb->modules; mod; mod = mod->next) {
2232 PyObject *item = PyLdbModule_FromModule(mod);
2235 PyErr_SetString(PyExc_RuntimeError,
2236 "Failed to load LdbModule");
2240 res = PyList_Append(ret, item);
2251 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2253 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2257 if (!PyArg_ParseTuple(args, "i", &type))
2260 /* FIXME: More interpretation */
2262 ret = ldb_sequence_number(ldb, type, &value);
2264 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2266 return PyLong_FromLongLong(value);
2270 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2272 .read_fn = ldb_handler_copy,
2273 .write_clear_fn = ldb_handler_copy,
2274 .write_hex_fn = ldb_handler_copy,
2277 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self,
2278 PyObject *Py_UNUSED(ignored))
2280 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2283 ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2285 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2291 static PyMethodDef py_ldb_methods[] = {
2292 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
2293 "S.set_debug(callback) -> None\n"
2294 "Set callback for LDB debug messages.\n"
2295 "The callback should accept a debug level and debug text." },
2296 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
2297 "S.set_create_perms(mode) -> None\n"
2298 "Set mode to use when creating new LDB files." },
2299 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2300 "S.set_modules_dir(path) -> None\n"
2301 "Set path LDB should search for modules" },
2302 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
2303 "S.transaction_start() -> None\n"
2304 "Start a new transaction." },
2305 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2306 "S.transaction_prepare_commit() -> None\n"
2307 "prepare to commit a new transaction (2-stage commit)." },
2308 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
2309 "S.transaction_commit() -> None\n"
2310 "commit a new transaction." },
2311 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
2312 "S.transaction_cancel() -> None\n"
2313 "cancel a new transaction." },
2314 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
2316 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2318 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2320 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2322 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2324 { "connect", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_connect),
2325 METH_VARARGS|METH_KEYWORDS,
2326 "S.connect(url, flags=0, options=None) -> None\n"
2327 "Connect to a LDB URL." },
2328 { "modify", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_modify),
2329 METH_VARARGS|METH_KEYWORDS,
2330 "S.modify(message, controls=None, validate=False) -> None\n"
2331 "Modify an entry." },
2332 { "add", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_add),
2333 METH_VARARGS|METH_KEYWORDS,
2334 "S.add(message, controls=None) -> None\n"
2336 { "delete", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_delete),
2337 METH_VARARGS|METH_KEYWORDS,
2338 "S.delete(dn, controls=None) -> None\n"
2339 "Remove an entry." },
2340 { "rename", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_rename),
2341 METH_VARARGS|METH_KEYWORDS,
2342 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2343 "Rename an entry." },
2344 { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_search),
2345 METH_VARARGS|METH_KEYWORDS,
2346 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2347 "Search in a database.\n"
2349 ":param base: Optional base DN to search\n"
2350 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2351 ":param expression: Optional search expression\n"
2352 ":param attrs: Attributes to return (defaults to all)\n"
2353 ":param controls: Optional list of controls\n"
2354 ":return: ldb.Result object\n"
2356 { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction,
2357 py_ldb_search_iterator),
2358 METH_VARARGS|METH_KEYWORDS,
2359 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2360 "Search in a database.\n"
2362 ":param base: Optional base DN to search\n"
2363 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2364 ":param expression: Optional search expression\n"
2365 ":param attrs: Attributes to return (defaults to all)\n"
2366 ":param controls: Optional list of controls\n"
2367 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2368 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2370 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2372 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2374 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2376 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2377 "S.parse_ldif(ldif) -> iter(messages)\n"
2378 "Parse a string formatted using LDIF." },
2379 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2380 "S.write_ldif(message, changetype) -> ldif\n"
2381 "Print the message as a string formatted using LDIF." },
2382 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2383 "S.msg_diff(Message) -> Message\n"
2384 "Return an LDB Message of the difference between two Message objects." },
2385 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2386 "S.get_opaque(name) -> value\n"
2387 "Get an opaque value set on this LDB connection. \n"
2388 ":note: The returned value may not be useful in Python."
2390 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2391 "S.set_opaque(name, value) -> None\n"
2392 "Set an opaque value on this LDB connection. \n"
2393 ":note: Passing incorrect values may cause crashes." },
2394 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2395 "S.modules() -> list\n"
2396 "Return the list of modules on this LDB connection " },
2397 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2398 "S.sequence_number(type) -> value\n"
2399 "Return the value of the sequence according to the requested type" },
2400 { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2401 "S._register_test_extensions() -> None\n"
2402 "Register internal extensions used in testing" },
2406 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2408 PyLdbModuleObject *ret;
2410 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2415 ret->mem_ctx = talloc_new(NULL);
2416 ret->mod = talloc_reference(ret->mem_ctx, mod);
2417 return (PyObject *)ret;
2420 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2422 struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2426 return PyLdbModule_FromModule(mod);
2429 static PyGetSetDef py_ldb_getset[] = {
2431 .name = discard_const_p(char, "firstmodule"),
2432 .get = (getter)py_ldb_get_firstmodule,
2437 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2439 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2441 struct ldb_result *result;
2445 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2449 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2451 if (ret != LDB_SUCCESS) {
2452 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2456 count = result->count;
2458 talloc_free(result);
2461 PyErr_Format(PyExc_RuntimeError,
2462 "Searching for [%s] dn gave %u results!",
2463 ldb_dn_get_linearized(dn),
2471 static PySequenceMethods py_ldb_seq = {
2472 .sq_contains = (objobjproc)py_ldb_contains,
2475 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2479 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2484 ret->mem_ctx = talloc_new(NULL);
2485 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2486 return (PyObject *)ret;
2489 static void py_ldb_dealloc(PyLdbObject *self)
2491 talloc_free(self->mem_ctx);
2492 Py_TYPE(self)->tp_free(self);
2495 static PyTypeObject PyLdb = {
2496 .tp_name = "ldb.Ldb",
2497 .tp_methods = py_ldb_methods,
2498 .tp_repr = (reprfunc)py_ldb_repr,
2499 .tp_new = py_ldb_new,
2500 .tp_init = (initproc)py_ldb_init,
2501 .tp_dealloc = (destructor)py_ldb_dealloc,
2502 .tp_getset = py_ldb_getset,
2503 .tp_getattro = PyObject_GenericGetAttr,
2504 .tp_basicsize = sizeof(PyLdbObject),
2505 .tp_doc = "Connection to a LDB database.",
2506 .tp_as_sequence = &py_ldb_seq,
2507 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2510 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2512 talloc_free(self->mem_ctx);
2513 Py_DECREF(self->msgs);
2514 Py_DECREF(self->referals);
2515 Py_DECREF(self->controls);
2516 Py_TYPE(self)->tp_free(self);
2519 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2521 Py_INCREF(self->msgs);
2525 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2527 Py_INCREF(self->controls);
2528 return self->controls;
2531 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2533 Py_INCREF(self->referals);
2534 return self->referals;
2537 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2540 if (self->msgs == NULL) {
2541 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2544 size = PyList_Size(self->msgs);
2545 return PyInt_FromLong(size);
2548 static PyGetSetDef py_ldb_result_getset[] = {
2550 .name = discard_const_p(char, "controls"),
2551 .get = (getter)py_ldb_result_get_controls,
2554 .name = discard_const_p(char, "msgs"),
2555 .get = (getter)py_ldb_result_get_msgs,
2558 .name = discard_const_p(char, "referals"),
2559 .get = (getter)py_ldb_result_get_referals,
2562 .name = discard_const_p(char, "count"),
2563 .get = (getter)py_ldb_result_get_count,
2568 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2570 return PyObject_GetIter(self->msgs);
2573 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2575 return PySequence_Size(self->msgs);
2578 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2580 return PySequence_GetItem(self->msgs, idx);
2583 static PySequenceMethods py_ldb_result_seq = {
2584 .sq_length = (lenfunc)py_ldb_result_len,
2585 .sq_item = (ssizeargfunc)py_ldb_result_find,
2588 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2590 return PyUnicode_FromString("<ldb result>");
2594 static PyTypeObject PyLdbResult = {
2595 .tp_name = "ldb.Result",
2596 .tp_repr = (reprfunc)py_ldb_result_repr,
2597 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2598 .tp_iter = (getiterfunc)py_ldb_result_iter,
2599 .tp_getset = py_ldb_result_getset,
2600 .tp_getattro = PyObject_GenericGetAttr,
2601 .tp_basicsize = sizeof(PyLdbResultObject),
2602 .tp_as_sequence = &py_ldb_result_seq,
2603 .tp_doc = "LDB result.",
2604 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2607 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2609 Py_XDECREF(self->state.exception);
2610 TALLOC_FREE(self->mem_ctx);
2611 ZERO_STRUCT(self->state);
2612 Py_DECREF(self->ldb);
2613 Py_TYPE(self)->tp_free(self);
2616 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2618 PyObject *py_ret = NULL;
2620 if (self->state.req == NULL) {
2621 PyErr_SetString(PyExc_RuntimeError,
2622 "ldb.SearchIterator request already finished");
2627 * TODO: do we want a non-blocking mode?
2628 * In future we may add an optional 'nonblocking'
2629 * argument to search_iterator().
2631 * For now we keep it simple and wait for at
2635 while (self->state.next == NULL) {
2638 if (self->state.result != NULL) {
2640 * We (already) got a final result from the server.
2642 * We stop the iteration and let
2643 * py_ldb_search_iterator_result() will deliver
2644 * the result details.
2646 TALLOC_FREE(self->state.req);
2647 PyErr_SetNone(PyExc_StopIteration);
2651 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2652 if (ret != LDB_SUCCESS) {
2653 struct ldb_context *ldb_ctx;
2654 TALLOC_FREE(self->state.req);
2655 ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb);
2657 * We stop the iteration and let
2658 * py_ldb_search_iterator_result() will deliver
2661 self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2662 ret, ldb_errstring(ldb_ctx));
2663 PyErr_SetNone(PyExc_StopIteration);
2668 py_ret = self->state.next->obj;
2669 self->state.next->obj = NULL;
2670 /* no TALLOC_FREE() as self->state.next is a list */
2671 talloc_free(self->state.next);
2675 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self,
2676 PyObject *Py_UNUSED(ignored))
2678 PyObject *py_ret = NULL;
2680 if (self->state.req != NULL) {
2681 PyErr_SetString(PyExc_RuntimeError,
2682 "ldb.SearchIterator request running");
2686 if (self->state.next != NULL) {
2687 PyErr_SetString(PyExc_RuntimeError,
2688 "ldb.SearchIterator not fully consumed.");
2692 if (self->state.exception != NULL) {
2693 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2694 self->state.exception = NULL;
2698 if (self->state.result == NULL) {
2699 PyErr_SetString(PyExc_RuntimeError,
2700 "ldb.SearchIterator result already consumed");
2704 py_ret = self->state.result->obj;
2705 self->state.result->obj = NULL;
2706 TALLOC_FREE(self->state.result);
2710 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self,
2711 PyObject *Py_UNUSED(ignored))
2713 if (self->state.req == NULL) {
2714 PyErr_SetString(PyExc_RuntimeError,
2715 "ldb.SearchIterator request already finished");
2719 Py_XDECREF(self->state.exception);
2720 TALLOC_FREE(self->mem_ctx);
2721 ZERO_STRUCT(self->state);
2725 static PyMethodDef py_ldb_search_iterator_methods[] = {
2726 { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2727 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2728 { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2733 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2735 return PyUnicode_FromString("<ldb search iterator>");
2738 static PyTypeObject PyLdbSearchIterator = {
2739 .tp_name = "ldb.SearchIterator",
2740 .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2741 .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2742 .tp_iter = PyObject_SelfIter,
2743 .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2744 .tp_methods = py_ldb_search_iterator_methods,
2745 .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2746 .tp_doc = "LDB search_iterator.",
2747 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2750 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2752 return PyUnicode_FromFormat("<ldb module '%s'>",
2753 pyldb_Module_AsModule(self)->ops->name);
2756 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2758 return PyUnicode_FromString(pyldb_Module_AsModule(self)->ops->name);
2761 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self,
2762 PyObject *Py_UNUSED(ignored))
2764 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2768 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self,
2769 PyObject *Py_UNUSED(ignored))
2771 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2775 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self,
2776 PyObject *Py_UNUSED(ignored))
2778 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2782 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2784 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2786 struct ldb_request *req;
2787 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2788 struct ldb_module *mod;
2789 const char * const*attrs;
2791 /* type "int" rather than "enum" for "scope" is intentional */
2792 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2793 discard_const_p(char *, kwnames),
2794 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2799 if (py_attrs == Py_None) {
2802 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2807 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2808 scope, NULL /* expr */, attrs,
2809 NULL /* controls */, NULL, NULL, NULL);
2811 talloc_steal(req, attrs);
2813 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2815 req->op.search.res = NULL;
2817 ret = mod->ops->search(mod, req);
2819 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2821 py_ret = PyLdbResult_FromResult(req->op.search.res);
2829 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2831 struct ldb_request *req;
2832 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_ADD;
2841 req->op.add.message = pyldb_Message_AsMessage(py_message);
2843 mod = pyldb_Module_AsModule(self);
2844 ret = mod->ops->add(mod, req);
2846 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2851 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2854 struct ldb_request *req;
2855 PyObject *py_message;
2856 struct ldb_module *mod;
2858 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2861 req = talloc_zero(NULL, struct ldb_request);
2862 req->operation = LDB_MODIFY;
2863 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2865 mod = pyldb_Module_AsModule(self);
2866 ret = mod->ops->modify(mod, req);
2868 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2873 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2876 struct ldb_request *req;
2879 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2882 req = talloc_zero(NULL, struct ldb_request);
2883 req->operation = LDB_DELETE;
2884 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2886 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2888 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2893 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2896 struct ldb_request *req;
2897 PyObject *py_dn1, *py_dn2;
2899 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2902 req = talloc_zero(NULL, struct ldb_request);
2904 req->operation = LDB_RENAME;
2905 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2906 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2908 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2910 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2915 static PyMethodDef py_ldb_module_methods[] = {
2916 { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_module_search),
2917 METH_VARARGS|METH_KEYWORDS, NULL },
2918 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2919 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2920 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2921 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2922 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2923 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2924 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2928 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2930 talloc_free(self->mem_ctx);
2934 static PyTypeObject PyLdbModule = {
2935 .tp_name = "ldb.LdbModule",
2936 .tp_methods = py_ldb_module_methods,
2937 .tp_repr = (reprfunc)py_ldb_module_repr,
2938 .tp_str = (reprfunc)py_ldb_module_str,
2939 .tp_basicsize = sizeof(PyLdbModuleObject),
2940 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2941 .tp_flags = Py_TPFLAGS_DEFAULT,
2942 .tp_doc = "LDB module (extension)",
2947 * Create a ldb_message_element from a Python object.
2949 * This will accept any sequence objects that contains strings, or
2952 * A reference to set_obj will be borrowed.
2954 * @param mem_ctx Memory context
2955 * @param set_obj Python object to convert
2956 * @param flags ldb_message_element flags to set
2957 * @param attr_name Name of the attribute
2958 * @return New ldb_message_element, allocated as child of mem_ctx
2960 static struct ldb_message_element *PyObject_AsMessageElement(
2961 TALLOC_CTX *mem_ctx,
2964 const char *attr_name)
2966 struct ldb_message_element *me;
2967 const char *msg = NULL;
2971 if (pyldb_MessageElement_Check(set_obj)) {
2972 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2973 /* We have to talloc_reference() the memory context, not the pointer
2974 * which may not actually be it's own context */
2975 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2976 return pyldb_MessageElement_AsMessageElement(set_obj);
2981 me = talloc(mem_ctx, struct ldb_message_element);
2987 me->name = talloc_strdup(me, attr_name);
2989 if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) {
2991 me->values = talloc_array(me, struct ldb_val, me->num_values);
2992 if (PyBytes_Check(set_obj)) {
2994 result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
3001 msg = PyUnicode_AsUTF8AndSize(set_obj, &size);
3007 me->values[0].data = talloc_memdup(me,
3008 (const uint8_t *)msg,
3010 me->values[0].length = size;
3011 } else if (PySequence_Check(set_obj)) {
3013 me->num_values = PySequence_Size(set_obj);
3014 me->values = talloc_array(me, struct ldb_val, me->num_values);
3015 for (i = 0; i < me->num_values; i++) {
3016 PyObject *obj = PySequence_GetItem(set_obj, i);
3017 if (PyBytes_Check(obj)) {
3019 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
3025 } else if (PyUnicode_Check(obj)) {
3026 msg = PyUnicode_AsUTF8AndSize(obj, &size);
3032 PyErr_Format(PyExc_TypeError,
3033 "Expected string as element %zd in list", i);
3037 me->values[i].data = talloc_memdup(me,
3038 (const uint8_t *)msg,
3040 me->values[i].length = size;
3043 PyErr_Format(PyExc_TypeError,
3044 "String or List type expected for '%s' attribute", attr_name);
3053 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
3054 struct ldb_message_element *me)
3059 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3060 result = PyList_New(me->num_values);
3062 for (i = 0; i < me->num_values; i++) {
3063 PyList_SetItem(result, i,
3064 PyObject_FromLdbValue(&me->values[i]));
3070 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
3073 if (!PyArg_ParseTuple(args, "I", &i))
3075 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
3078 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
3081 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
3083 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3084 return PyInt_FromLong(el->flags);
3087 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
3090 struct ldb_message_element *el;
3091 if (!PyArg_ParseTuple(args, "I", &flags))
3094 el = pyldb_MessageElement_AsMessageElement(self);
3099 static PyMethodDef py_ldb_msg_element_methods[] = {
3100 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
3101 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
3102 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
3106 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
3108 return pyldb_MessageElement_AsMessageElement(self)->num_values;
3111 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
3113 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3114 if (idx < 0 || idx >= el->num_values) {
3115 PyErr_SetString(PyExc_IndexError, "Out of range");
3118 return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
3121 static PySequenceMethods py_ldb_msg_element_seq = {
3122 .sq_length = (lenfunc)py_ldb_msg_element_len,
3123 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
3126 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3129 if (!pyldb_MessageElement_Check(other)) {
3130 Py_INCREF(Py_NotImplemented);
3131 return Py_NotImplemented;
3133 ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3134 pyldb_MessageElement_AsMessageElement(other));
3135 return richcmp(ret, op);
3138 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3140 PyObject *el = ldb_msg_element_to_set(NULL,
3141 pyldb_MessageElement_AsMessageElement(self));
3142 PyObject *ret = PyObject_GetIter(el);
3147 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3149 PyLdbMessageElementObject *ret;
3150 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3155 ret->mem_ctx = talloc_new(NULL);
3156 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
3161 return (PyObject *)ret;
3164 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3166 PyObject *py_elements = NULL;
3167 struct ldb_message_element *el;
3168 unsigned int flags = 0;
3170 const char * const kwnames[] = { "elements", "flags", "name", NULL };
3171 PyLdbMessageElementObject *ret;
3172 TALLOC_CTX *mem_ctx;
3173 const char *msg = NULL;
3177 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3178 discard_const_p(char *, kwnames),
3179 &py_elements, &flags, &name))
3182 mem_ctx = talloc_new(NULL);
3183 if (mem_ctx == NULL) {
3188 el = talloc_zero(mem_ctx, struct ldb_message_element);
3191 talloc_free(mem_ctx);
3195 if (py_elements != NULL) {
3197 if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) {
3200 el->values = talloc_array(el, struct ldb_val, 1);
3201 if (el->values == NULL) {
3202 talloc_free(mem_ctx);
3206 if (PyBytes_Check(py_elements)) {
3207 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3210 msg = PyUnicode_AsUTF8AndSize(py_elements, &size);
3211 result = (msg == NULL) ? -1 : 0;
3214 talloc_free(mem_ctx);
3217 el->values[0].data = talloc_memdup(el->values,
3218 (const uint8_t *)msg, size + 1);
3219 el->values[0].length = size;
3220 } else if (PySequence_Check(py_elements)) {
3221 el->num_values = PySequence_Size(py_elements);
3222 el->values = talloc_array(el, struct ldb_val, el->num_values);
3223 if (el->values == NULL) {
3224 talloc_free(mem_ctx);
3228 for (i = 0; i < el->num_values; i++) {
3229 PyObject *item = PySequence_GetItem(py_elements, i);
3231 talloc_free(mem_ctx);
3234 if (PyBytes_Check(item)) {
3236 result = PyBytes_AsStringAndSize(item, &_msg, &size);
3238 } else if (PyUnicode_Check(item)) {
3239 msg = PyUnicode_AsUTF8AndSize(item, &size);
3240 result = (msg == NULL) ? -1 : 0;
3242 PyErr_Format(PyExc_TypeError,
3243 "Expected string as element %zd in list", i);
3247 talloc_free(mem_ctx);
3250 el->values[i].data = talloc_memdup(el,
3251 (const uint8_t *)msg, size+1);
3252 el->values[i].length = size;
3255 PyErr_SetString(PyExc_TypeError,
3256 "Expected string or list");
3257 talloc_free(mem_ctx);
3263 el->name = talloc_strdup(el, name);
3265 ret = PyObject_New(PyLdbMessageElementObject, type);
3267 talloc_free(mem_ctx);
3271 ret->mem_ctx = mem_ctx;
3273 return (PyObject *)ret;
3276 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3278 char *element_str = NULL;
3280 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3281 PyObject *ret, *repr;
3283 for (i = 0; i < el->num_values; i++) {
3284 PyObject *o = py_ldb_msg_element_find(self, i);
3285 repr = PyObject_Repr(o);
3286 if (element_str == NULL)
3287 element_str = talloc_strdup(NULL, PyUnicode_AsUTF8(repr));
3289 element_str = talloc_asprintf_append(element_str, ",%s", PyUnicode_AsUTF8(repr));
3293 if (element_str != NULL) {
3294 ret = PyUnicode_FromFormat("MessageElement([%s])", element_str);
3295 talloc_free(element_str);
3297 ret = PyUnicode_FromString("MessageElement([])");
3303 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3305 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3307 if (el->num_values == 1)
3308 return PyUnicode_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3313 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3315 talloc_free(self->mem_ctx);
3319 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3321 return wrap_text("MessageElementTextWrapper", self);
3324 static PyGetSetDef py_ldb_msg_element_getset[] = {
3326 .name = discard_const_p(char, "text"),
3327 .get = (getter)py_ldb_msg_element_get_text,
3332 static PyTypeObject PyLdbMessageElement = {
3333 .tp_name = "ldb.MessageElement",
3334 .tp_basicsize = sizeof(PyLdbMessageElementObject),
3335 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3336 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3337 .tp_str = (reprfunc)py_ldb_msg_element_str,
3338 .tp_methods = py_ldb_msg_element_methods,
3339 .tp_getset = py_ldb_msg_element_getset,
3340 .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3341 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3342 .tp_as_sequence = &py_ldb_msg_element_seq,
3343 .tp_new = py_ldb_msg_element_new,
3344 .tp_flags = Py_TPFLAGS_DEFAULT,
3345 .tp_doc = "An element of a Message",
3349 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3354 struct ldb_message *msg;
3355 struct ldb_context *ldb_ctx;
3356 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3358 if (!PyArg_ParseTuple(args, "O!O!|I",
3359 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3364 if (!PyLdb_Check(py_ldb)) {
3365 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
3369 /* mask only flags we are going to use */
3370 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3372 PyErr_SetString(PyExc_ValueError,
3373 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3374 " expected as mod_flag value");
3378 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
3380 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3385 py_ret = PyLdbMessage_FromMessage(msg);
3387 talloc_unlink(ldb_ctx, msg);
3392 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3395 if (!PyArg_ParseTuple(args, "s", &name))
3398 ldb_msg_remove_attr(self->msg, name);
3403 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self,
3404 PyObject *Py_UNUSED(ignored))
3406 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3407 Py_ssize_t i, j = 0;
3408 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3409 if (msg->dn != NULL) {
3410 PyList_SetItem(obj, j, PyUnicode_FromString("dn"));
3413 for (i = 0; i < msg->num_elements; i++) {
3414 PyList_SetItem(obj, j, PyUnicode_FromString(msg->elements[i].name));
3420 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
3422 struct ldb_message_element *el;
3424 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3425 name = PyUnicode_AsUTF8(py_name);
3427 PyErr_SetNone(PyExc_TypeError);
3430 if (!ldb_attr_cmp(name, "dn"))
3431 return pyldb_Dn_FromDn(msg->dn);
3432 el = ldb_msg_find_element(msg, name);
3436 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3439 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3441 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
3443 PyErr_SetString(PyExc_KeyError, "No such element");
3449 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3451 PyObject *def = NULL;
3452 const char *kwnames[] = { "name", "default", "idx", NULL };
3453 const char *name = NULL;
3455 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3456 struct ldb_message_element *el;
3458 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3459 discard_const_p(char *, kwnames), &name, &def, &idx)) {
3463 if (strcasecmp(name, "dn") == 0) {
3464 return pyldb_Dn_FromDn(msg->dn);
3467 el = ldb_msg_find_element(msg, name);
3469 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3478 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3481 return PyObject_FromLdbValue(&el->values[idx]);
3484 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self,
3485 PyObject *Py_UNUSED(ignored))
3487 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3488 Py_ssize_t i, j = 0;
3489 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3491 return PyErr_NoMemory();
3493 if (msg->dn != NULL) {
3494 PyObject *value = NULL;
3495 PyObject *obj = pyldb_Dn_FromDn(msg->dn);
3497 value = Py_BuildValue("(sO)", "dn", obj);
3499 if (value == NULL) {
3503 res = PyList_SetItem(l, 0, value);
3510 for (i = 0; i < msg->num_elements; i++, j++) {
3511 PyObject *value = NULL;
3512 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3515 value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3516 if (value == NULL ) {
3520 res = PyList_SetItem(l, 0, value);
3529 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self,
3530 PyObject *Py_UNUSED(ignored))
3532 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3534 PyObject *l = PyList_New(msg->num_elements);
3535 for (i = 0; i < msg->num_elements; i++) {
3536 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
3541 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3543 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3544 PyLdbMessageElementObject *py_element;
3546 struct ldb_message_element *el;
3547 struct ldb_message_element *el_new;
3549 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
3552 el = py_element->el;
3554 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3557 if (el->name == NULL) {
3558 PyErr_SetString(PyExc_ValueError,
3559 "The element has no name");
3562 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3563 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3565 /* now deep copy all attribute values */
3566 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3567 if (el_new->values == NULL) {
3571 el_new->num_values = el->num_values;
3573 for (i = 0; i < el->num_values; i++) {
3574 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
3575 if (el_new->values[i].data == NULL
3576 && el->values[i].length != 0) {
3585 static PyMethodDef py_ldb_msg_methods[] = {
3586 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
3587 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3588 "Class method to create ldb.Message object from Dictionary.\n"
3589 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3590 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
3591 "S.keys() -> list\n\n"
3592 "Return sequence of all attribute names." },
3593 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
3594 "S.remove(name)\n\n"
3595 "Remove all entries for attributes with the specified name."},
3596 { "get", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_msg_get),
3597 METH_VARARGS | METH_KEYWORDS,
3598 "msg.get(name,default=None,idx=None) -> string\n"
3599 "idx is the index into the values array\n"
3600 "if idx is None, then a list is returned\n"
3601 "if idx is not None, then the element with that index is returned\n"
3602 "if you pass the special name 'dn' then the DN object is returned\n"},
3603 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
3604 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
3605 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
3606 "S.add(element)\n\n"
3607 "Add an element to this message." },
3611 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
3613 PyObject *list, *iter;
3615 list = py_ldb_msg_keys(self, NULL);
3616 iter = PyObject_GetIter(list);
3621 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
3623 const char *attr_name;
3625 attr_name = PyUnicode_AsUTF8(name);
3626 if (attr_name == NULL) {
3627 PyErr_SetNone(PyExc_TypeError);
3631 if (value == NULL) {
3633 ldb_msg_remove_attr(self->msg, attr_name);
3636 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
3637 value, 0, attr_name);
3641 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
3642 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
3643 if (ret != LDB_SUCCESS) {
3644 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
3651 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
3653 return pyldb_Message_AsMessage(self)->num_elements;
3656 static PyMappingMethods py_ldb_msg_mapping = {
3657 .mp_length = (lenfunc)py_ldb_msg_length,
3658 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
3659 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
3662 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3664 const char * const kwnames[] = { "dn", NULL };
3665 struct ldb_message *ret;
3666 TALLOC_CTX *mem_ctx;
3667 PyObject *pydn = NULL;
3668 PyLdbMessageObject *py_ret;
3670 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
3671 discard_const_p(char *, kwnames),
3675 mem_ctx = talloc_new(NULL);
3676 if (mem_ctx == NULL) {
3681 ret = ldb_msg_new(mem_ctx);
3683 talloc_free(mem_ctx);
3690 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
3691 talloc_free(mem_ctx);
3694 ret->dn = talloc_reference(ret, dn);
3697 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
3698 if (py_ret == NULL) {
3700 talloc_free(mem_ctx);
3704 py_ret->mem_ctx = mem_ctx;
3706 return (PyObject *)py_ret;
3709 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
3711 PyLdbMessageObject *ret;
3713 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3718 ret->mem_ctx = talloc_new(NULL);
3719 ret->msg = talloc_reference(ret->mem_ctx, msg);
3720 return (PyObject *)ret;
3723 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3725 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3726 return pyldb_Dn_FromDn(msg->dn);
3729 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3731 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3732 if (!pyldb_Dn_Check(value)) {
3733 PyErr_SetString(PyExc_TypeError, "expected dn");
3737 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3741 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
3743 return wrap_text("MessageTextWrapper", self);
3746 static PyGetSetDef py_ldb_msg_getset[] = {
3748 .name = discard_const_p(char, "dn"),
3749 .get = (getter)py_ldb_msg_get_dn,
3750 .set = (setter)py_ldb_msg_set_dn,
3753 .name = discard_const_p(char, "text"),
3754 .get = (getter)py_ldb_msg_get_text,
3759 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3761 PyObject *dict = PyDict_New(), *ret, *repr;
3762 if (PyDict_Update(dict, (PyObject *)self) != 0)
3764 repr = PyObject_Repr(dict);
3769 ret = PyUnicode_FromFormat("Message(%s)", PyUnicode_AsUTF8(repr));
3775 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3777 talloc_free(self->mem_ctx);
3781 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3782 PyLdbMessageObject *py_msg2, int op)
3784 struct ldb_message *msg1, *msg2;
3788 if (!PyLdbMessage_Check(py_msg2)) {
3789 Py_INCREF(Py_NotImplemented);
3790 return Py_NotImplemented;
3793 msg1 = pyldb_Message_AsMessage(py_msg1),
3794 msg2 = pyldb_Message_AsMessage(py_msg2);
3796 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3797 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3799 return richcmp(ret, op);
3803 ret = msg1->num_elements - msg2->num_elements;
3805 return richcmp(ret, op);
3808 for (i = 0; i < msg1->num_elements; i++) {
3809 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3810 &msg2->elements[i]);
3812 return richcmp(ret, op);
3815 ret = ldb_msg_element_compare(&msg1->elements[i],
3816 &msg2->elements[i]);
3818 return richcmp(ret, op);
3822 return richcmp(0, op);
3825 static PyTypeObject PyLdbMessage = {
3826 .tp_name = "ldb.Message",
3827 .tp_methods = py_ldb_msg_methods,
3828 .tp_getset = py_ldb_msg_getset,
3829 .tp_as_mapping = &py_ldb_msg_mapping,
3830 .tp_basicsize = sizeof(PyLdbMessageObject),
3831 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3832 .tp_new = py_ldb_msg_new,
3833 .tp_repr = (reprfunc)py_ldb_msg_repr,
3834 .tp_flags = Py_TPFLAGS_DEFAULT,
3835 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3836 .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3837 .tp_doc = "A LDB Message",
3840 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3842 PyLdbTreeObject *ret;
3844 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3850 ret->mem_ctx = talloc_new(NULL);
3851 ret->tree = talloc_reference(ret->mem_ctx, tree);
3852 return (PyObject *)ret;
3855 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3857 talloc_free(self->mem_ctx);
3861 static PyTypeObject PyLdbTree = {
3862 .tp_name = "ldb.Tree",
3863 .tp_basicsize = sizeof(PyLdbTreeObject),
3864 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3865 .tp_flags = Py_TPFLAGS_DEFAULT,
3866 .tp_doc = "A search tree",
3870 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3872 PyObject *py_ldb = (PyObject *)mod->private_data;
3873 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3875 py_base = pyldb_Dn_FromDn(req->op.search.base);
3877 if (py_base == NULL)
3878 return LDB_ERR_OPERATIONS_ERROR;
3880 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3882 if (py_tree == NULL)
3883 return LDB_ERR_OPERATIONS_ERROR;
3885 if (req->op.search.attrs == NULL) {
3889 for (len = 0; req->op.search.attrs[len]; len++);
3890 py_attrs = PyList_New(len);
3891 for (i = 0; i < len; i++)
3892 PyList_SetItem(py_attrs, i, PyUnicode_FromString(req->op.search.attrs[i]));
3895 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3896 discard_const_p(char, "OiOO"),
3897 py_base, req->op.search.scope, py_tree, py_attrs);
3899 Py_DECREF(py_attrs);
3903 if (py_result == NULL) {
3904 return LDB_ERR_PYTHON_EXCEPTION;
3907 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3908 if (req->op.search.res == NULL) {
3909 return LDB_ERR_PYTHON_EXCEPTION;
3912 Py_DECREF(py_result);
3917 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3919 PyObject *py_ldb = (PyObject *)mod->private_data;
3920 PyObject *py_result, *py_msg;
3922 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3924 if (py_msg == NULL) {
3925 return LDB_ERR_OPERATIONS_ERROR;
3928 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3929 discard_const_p(char, "O"),
3934 if (py_result == NULL) {
3935 return LDB_ERR_PYTHON_EXCEPTION;
3938 Py_DECREF(py_result);
3943 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3945 PyObject *py_ldb = (PyObject *)mod->private_data;
3946 PyObject *py_result, *py_msg;
3948 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3950 if (py_msg == NULL) {
3951 return LDB_ERR_OPERATIONS_ERROR;
3954 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3955 discard_const_p(char, "O"),
3960 if (py_result == NULL) {
3961 return LDB_ERR_PYTHON_EXCEPTION;
3964 Py_DECREF(py_result);
3969 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3971 PyObject *py_ldb = (PyObject *)mod->private_data;
3972 PyObject *py_result, *py_dn;
3974 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3977 return LDB_ERR_OPERATIONS_ERROR;
3979 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3980 discard_const_p(char, "O"),
3983 if (py_result == NULL) {
3984 return LDB_ERR_PYTHON_EXCEPTION;
3987 Py_DECREF(py_result);
3992 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3994 PyObject *py_ldb = (PyObject *)mod->private_data;
3995 PyObject *py_result, *py_olddn, *py_newdn;
3997 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3999 if (py_olddn == NULL)
4000 return LDB_ERR_OPERATIONS_ERROR;
4002 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
4004 if (py_newdn == NULL)
4005 return LDB_ERR_OPERATIONS_ERROR;
4007 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
4008 discard_const_p(char, "OO"),
4009 py_olddn, py_newdn);
4011 Py_DECREF(py_olddn);
4012 Py_DECREF(py_newdn);
4014 if (py_result == NULL) {
4015 return LDB_ERR_PYTHON_EXCEPTION;
4018 Py_DECREF(py_result);
4023 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
4025 PyObject *py_ldb = (PyObject *)mod->private_data;
4026 PyObject *py_result;
4028 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
4029 discard_const_p(char, ""));
4031 Py_XDECREF(py_result);
4033 return LDB_ERR_OPERATIONS_ERROR;
4036 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
4038 PyObject *py_ldb = (PyObject *)mod->private_data;
4039 PyObject *py_result;
4041 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
4042 discard_const_p(char, ""));
4044 Py_XDECREF(py_result);
4046 return LDB_ERR_OPERATIONS_ERROR;
4049 static int py_module_start_transaction(struct ldb_module *mod)
4051 PyObject *py_ldb = (PyObject *)mod->private_data;
4052 PyObject *py_result;
4054 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
4055 discard_const_p(char, ""));
4057 if (py_result == NULL) {
4058 return LDB_ERR_PYTHON_EXCEPTION;
4061 Py_DECREF(py_result);
4066 static int py_module_end_transaction(struct ldb_module *mod)
4068 PyObject *py_ldb = (PyObject *)mod->private_data;
4069 PyObject *py_result;
4071 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
4072 discard_const_p(char, ""));
4074 if (py_result == NULL) {
4075 return LDB_ERR_PYTHON_EXCEPTION;
4078 Py_DECREF(py_result);
4083 static int py_module_del_transaction(struct ldb_module *mod)
4085 PyObject *py_ldb = (PyObject *)mod->private_data;
4086 PyObject *py_result;
4088 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
4089 discard_const_p(char, ""));
4091 if (py_result == NULL) {
4092 return LDB_ERR_PYTHON_EXCEPTION;
4095 Py_DECREF(py_result);
4100 static int py_module_destructor(struct ldb_module *mod)
4102 Py_DECREF((PyObject *)mod->private_data);
4106 static int py_module_init(struct ldb_module *mod)
4108 PyObject *py_class = (PyObject *)mod->ops->private_data;
4109 PyObject *py_result, *py_next, *py_ldb;
4111 py_ldb = PyLdb_FromLdbContext(mod->ldb);
4114 return LDB_ERR_OPERATIONS_ERROR;
4116 py_next = PyLdbModule_FromModule(mod->next);
4118 if (py_next == NULL)
4119 return LDB_ERR_OPERATIONS_ERROR;
4121 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
4124 if (py_result == NULL) {
4125 return LDB_ERR_PYTHON_EXCEPTION;
4128 mod->private_data = py_result;
4130 talloc_set_destructor(mod, py_module_destructor);
4132 return ldb_next_init(mod);
4135 static PyObject *py_register_module(PyObject *module, PyObject *args)
4138 struct ldb_module_ops *ops;
4142 if (!PyArg_ParseTuple(args, "O", &input))
4145 ops = talloc_zero(NULL, struct ldb_module_ops);
4151 tmp = PyObject_GetAttrString(input, discard_const_p(char, "name"));
4152 ops->name = talloc_strdup(ops, PyUnicode_AsUTF8(tmp));
4156 ops->private_data = input;
4157 ops->init_context = py_module_init;
4158 ops->search = py_module_search;
4159 ops->add = py_module_add;
4160 ops->modify = py_module_modify;
4161 ops->del = py_module_del;
4162 ops->rename = py_module_rename;
4163 ops->request = py_module_request;
4164 ops->extended = py_module_extended;
4165 ops->start_transaction = py_module_start_transaction;
4166 ops->end_transaction = py_module_end_transaction;
4167 ops->del_transaction = py_module_del_transaction;
4169 ret = ldb_register_module(ops);
4170 if (ret != LDB_SUCCESS) {
4174 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
4179 static PyObject *py_timestring(PyObject *module, PyObject *args)
4181 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4182 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4186 if (!PyArg_ParseTuple(args, "l", &t_val))
4188 tresult = ldb_timestring(NULL, (time_t) t_val);
4189 ret = PyUnicode_FromString(tresult);
4190 talloc_free(tresult);
4194 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
4197 if (!PyArg_ParseTuple(args, "s", &str))
4200 return PyInt_FromLong(ldb_string_to_time(str));
4203 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4206 if (!PyArg_ParseTuple(args, "s", &name))
4208 return PyBool_FromLong(ldb_valid_attr_name(name));
4212 encode a string using RFC2254 rules
4214 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4216 char *str, *encoded;
4217 Py_ssize_t size = 0;
4221 if (!PyArg_ParseTuple(args, "s#", &str, &size))
4223 val.data = (uint8_t *)str;
4226 encoded = ldb_binary_encode(NULL, val);
4227 if (encoded == NULL) {
4228 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4231 ret = PyUnicode_FromString(encoded);
4232 talloc_free(encoded);
4237 decode a string using RFC2254 rules
4239 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4245 if (!PyArg_ParseTuple(args, "s", &str))
4248 val = ldb_binary_decode(NULL, str);
4249 if (val.data == NULL) {
4250 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4253 ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4254 talloc_free(val.data);
4258 static PyMethodDef py_ldb_global_methods[] = {
4259 { "register_module", py_register_module, METH_VARARGS,
4260 "S.register_module(module) -> None\n\n"
4261 "Register a LDB module."},
4262 { "timestring", py_timestring, METH_VARARGS,
4263 "S.timestring(int) -> string\n\n"
4264 "Generate a LDAP time string from a UNIX timestamp" },
4265 { "string_to_time", py_string_to_time, METH_VARARGS,
4266 "S.string_to_time(string) -> int\n\n"
4267 "Parse a LDAP time string into a UNIX timestamp." },
4268 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4269 "S.valid_attr_name(name) -> bool\n\nn"
4270 "Check whether the supplied name is a valid attribute name." },
4271 { "open", PY_DISCARD_FUNC_SIG(PyCFunction,py_ldb_new),
4272 METH_VARARGS|METH_KEYWORDS,
4273 "S.open() -> Ldb\n\n"
4274 "Open a new LDB context." },
4275 { "binary_encode", py_binary_encode, METH_VARARGS,
4276 "S.binary_encode(string) -> string\n\n"
4277 "Perform a RFC2254 binary encoding on a string" },
4278 { "binary_decode", py_binary_decode, METH_VARARGS,
4279 "S.binary_decode(string) -> string\n\n"
4280 "Perform a RFC2254 binary decode on a string" },
4284 #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."
4286 #if PY_MAJOR_VERSION >= 3
4287 static struct PyModuleDef moduledef = {
4288 PyModuleDef_HEAD_INIT,
4290 .m_doc = MODULE_DOC,
4292 .m_methods = py_ldb_global_methods,
4296 static PyObject* module_init(void)
4300 PyLdbBytesType.tp_base = &PyBytes_Type;
4301 if (PyType_Ready(&PyLdbBytesType) < 0) {
4305 if (PyType_Ready(&PyLdbDn) < 0)
4308 if (PyType_Ready(&PyLdbMessage) < 0)
4311 if (PyType_Ready(&PyLdbMessageElement) < 0)
4314 if (PyType_Ready(&PyLdb) < 0)
4317 if (PyType_Ready(&PyLdbModule) < 0)
4320 if (PyType_Ready(&PyLdbTree) < 0)
4323 if (PyType_Ready(&PyLdbResult) < 0)
4326 if (PyType_Ready(&PyLdbSearchIterator) < 0)
4329 if (PyType_Ready(&PyLdbControl) < 0)
4332 #if PY_MAJOR_VERSION >= 3
4333 m = PyModule_Create(&moduledef);
4335 m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC);
4340 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4342 ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4343 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4344 ADD_LDB_INT(SEQ_NEXT);
4345 ADD_LDB_INT(SCOPE_DEFAULT);
4346 ADD_LDB_INT(SCOPE_BASE);
4347 ADD_LDB_INT(SCOPE_ONELEVEL);
4348 ADD_LDB_INT(SCOPE_SUBTREE);
4350 ADD_LDB_INT(CHANGETYPE_NONE);
4351 ADD_LDB_INT(CHANGETYPE_ADD);
4352 ADD_LDB_INT(CHANGETYPE_DELETE);
4353 ADD_LDB_INT(CHANGETYPE_MODIFY);
4355 ADD_LDB_INT(FLAG_MOD_ADD);
4356 ADD_LDB_INT(FLAG_MOD_REPLACE);
4357 ADD_LDB_INT(FLAG_MOD_DELETE);
4358 ADD_LDB_INT(FLAG_FORCE_NO_BASE64_LDIF);
4360 ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4361 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4362 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4363 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4365 ADD_LDB_INT(SUCCESS);
4366 ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4367 ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4368 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4369 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4370 ADD_LDB_INT(ERR_COMPARE_FALSE);
4371 ADD_LDB_INT(ERR_COMPARE_TRUE);
4372 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4373 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4374 ADD_LDB_INT(ERR_REFERRAL);
4375 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4376 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4377 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4378 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4379 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4380 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4381 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4382 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4383 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4384 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4385 ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4386 ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4387 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4388 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4389 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4390 ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4391 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4392 ADD_LDB_INT(ERR_BUSY);
4393 ADD_LDB_INT(ERR_UNAVAILABLE);
4394 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4395 ADD_LDB_INT(ERR_LOOP_DETECT);
4396 ADD_LDB_INT(ERR_NAMING_VIOLATION);
4397 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4398 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4399 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4400 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4401 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4402 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4403 ADD_LDB_INT(ERR_OTHER);
4405 ADD_LDB_INT(FLG_RDONLY);
4406 ADD_LDB_INT(FLG_NOSYNC);
4407 ADD_LDB_INT(FLG_RECONNECT);
4408 ADD_LDB_INT(FLG_NOMMAP);
4409 ADD_LDB_INT(FLG_SHOW_BINARY);
4410 ADD_LDB_INT(FLG_ENABLE_TRACING);
4411 ADD_LDB_INT(FLG_DONT_CREATE_DB);
4413 ADD_LDB_INT(PACKING_FORMAT);
4414 ADD_LDB_INT(PACKING_FORMAT_V2);
4416 /* Historical misspelling */
4417 PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
4419 PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
4421 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
4422 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
4425 Py_INCREF(&PyLdbDn);
4426 Py_INCREF(&PyLdbModule);
4427 Py_INCREF(&PyLdbMessage);
4428 Py_INCREF(&PyLdbMessageElement);
4429 Py_INCREF(&PyLdbTree);
4430 Py_INCREF(&PyLdbResult);
4431 Py_INCREF(&PyLdbControl);
4433 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
4434 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
4435 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
4436 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
4437 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
4438 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
4439 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
4441 PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
4443 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4445 ADD_LDB_STRING(SYNTAX_DN);
4446 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
4447 ADD_LDB_STRING(SYNTAX_INTEGER);
4448 ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER);
4449 ADD_LDB_STRING(SYNTAX_BOOLEAN);
4450 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
4451 ADD_LDB_STRING(SYNTAX_UTC_TIME);
4452 ADD_LDB_STRING(OID_COMPARATOR_AND);
4453 ADD_LDB_STRING(OID_COMPARATOR_OR);
4458 #if PY_MAJOR_VERSION >= 3
4459 PyMODINIT_FUNC PyInit_ldb(void);
4460 PyMODINIT_FUNC PyInit_ldb(void)
4462 return module_init();