2 Unix SMB/CIFS implementation.
4 Python interface to ldb.
6 Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7 Copyright (C) 2006 Simo Sorce <idra@samba.org>
8 Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9 Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10 Copyright (C) 2009-2011 Andrew Tridgell
11 Copyright (C) 2009-2011 Andrew Bartlett
13 ** NOTE! The following LGPL license applies to the ldb
14 ** library. This does NOT imply that all of Samba is released
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public
19 License as published by the Free Software Foundation; either
20 version 3 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 #include "ldb_private.h"
33 #include "ldb_handlers.h"
35 #include "dlinklist.h"
37 struct py_ldb_search_iterator_reply;
44 struct ldb_request *req;
45 struct py_ldb_search_iterator_reply *next;
46 struct py_ldb_search_iterator_reply *result;
49 } PyLdbSearchIteratorObject;
51 struct py_ldb_search_iterator_reply {
52 struct py_ldb_search_iterator_reply *prev, *next;
53 PyLdbSearchIteratorObject *py_iter;
58 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
59 static PyObject *PyExc_LdbError;
61 static PyTypeObject PyLdbControl;
62 static PyTypeObject PyLdbResult;
63 static PyTypeObject PyLdbSearchIterator;
64 static PyTypeObject PyLdbMessage;
65 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
66 static PyTypeObject PyLdbModule;
67 static PyTypeObject PyLdbDn;
68 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
69 static PyTypeObject PyLdb;
70 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
71 static PyTypeObject PyLdbMessageElement;
72 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
74 static PyTypeObject PyLdbTree;
75 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
76 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
77 static struct ldb_message_element *PyObject_AsMessageElement(
81 const char *attr_name);
83 #if PY_MAJOR_VERSION >= 3
84 #define PyStr_Check PyUnicode_Check
85 #define PyStr_FromString PyUnicode_FromString
86 #define PyStr_FromStringAndSize PyUnicode_FromStringAndSize
87 #define PyStr_FromFormat PyUnicode_FromFormat
88 #define PyStr_FromFormatV PyUnicode_FromFormatV
89 #define PyStr_AsUTF8 PyUnicode_AsUTF8
90 #define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize
91 #define PyInt_FromLong PyLong_FromLong
93 #define PyStr_Check PyString_Check
94 #define PyStr_FromString PyString_FromString
95 #define PyStr_FromStringAndSize PyString_FromStringAndSize
96 #define PyStr_FromFormat PyString_FromFormat
97 #define PyStr_FromFormatV PyString_FromFormatV
98 #define PyStr_AsUTF8 PyString_AsString
100 const char *PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr);
102 PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr)
104 const char * ret = PyString_AsString(pystr);
107 *sizeptr = PyString_Size(pystr);
112 static PyObject *richcmp(int cmp_val, int op)
116 case Py_LT: ret = cmp_val < 0; break;
117 case Py_LE: ret = cmp_val <= 0; break;
118 case Py_EQ: ret = cmp_val == 0; break;
119 case Py_NE: ret = cmp_val != 0; break;
120 case Py_GT: ret = cmp_val > 0; break;
121 case Py_GE: ret = cmp_val >= 0; break;
123 Py_INCREF(Py_NotImplemented);
124 return Py_NotImplemented;
126 return PyBool_FromLong(ret);
130 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
132 if (self->data != NULL) {
133 char* control = ldb_control_to_string(self->mem_ctx, self->data);
134 if (control == NULL) {
138 return PyStr_FromString(control);
140 return PyStr_FromString("ldb control");
144 static void py_ldb_control_dealloc(PyLdbControlObject *self)
146 if (self->mem_ctx != NULL) {
147 talloc_free(self->mem_ctx);
150 Py_TYPE(self)->tp_free(self);
153 /* Create a text (rather than bytes) interface for a LDB result object */
154 static PyObject *wrap_text(const char *type, PyObject *wrapped)
156 PyObject *mod, *cls, *constructor, *inst;
157 mod = PyImport_ImportModule("_ldb_text");
160 cls = PyObject_GetAttrString(mod, type);
166 constructor = PyObject_GetAttrString(cls, "_wrap");
168 if (constructor == NULL) {
171 inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped);
172 Py_DECREF(constructor);
176 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
178 return PyStr_FromString(self->data->oid);
181 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
183 return PyBool_FromLong(self->data->critical);
186 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
188 if (PyObject_IsTrue(value)) {
189 self->data->critical = true;
191 self->data->critical = false;
196 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
199 const char * const kwnames[] = { "ldb", "data", NULL };
200 struct ldb_control *parsed_controls;
201 PyLdbControlObject *ret;
204 struct ldb_context *ldb_ctx;
206 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
207 discard_const_p(char *, kwnames),
208 &PyLdb, &py_ldb, &data))
211 mem_ctx = talloc_new(NULL);
212 if (mem_ctx == NULL) {
217 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
218 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
220 if (!parsed_controls) {
221 talloc_free(mem_ctx);
222 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
226 ret = PyObject_New(PyLdbControlObject, type);
229 talloc_free(mem_ctx);
233 ret->mem_ctx = mem_ctx;
235 ret->data = talloc_move(mem_ctx, &parsed_controls);
236 if (ret->data == NULL) {
239 talloc_free(mem_ctx);
243 return (PyObject *)ret;
246 static PyGetSetDef py_ldb_control_getset[] = {
247 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
248 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
252 static PyTypeObject PyLdbControl = {
253 .tp_name = "ldb.control",
254 .tp_dealloc = (destructor)py_ldb_control_dealloc,
255 .tp_getattro = PyObject_GenericGetAttr,
256 .tp_basicsize = sizeof(PyLdbControlObject),
257 .tp_getset = py_ldb_control_getset,
258 .tp_doc = "LDB control.",
259 .tp_str = (reprfunc)py_ldb_control_str,
260 .tp_new = py_ldb_control_new,
261 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
264 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
266 if (ret == LDB_ERR_PYTHON_EXCEPTION)
267 return; /* Python exception should already be set, just keep that */
269 PyErr_SetObject(error,
270 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
271 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
274 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
276 return PyBytes_FromStringAndSize((const char *)val->data, val->length);
279 static PyObject *PyStr_FromLdbValue(const struct ldb_val *val)
281 return PyStr_FromStringAndSize((const char *)val->data, val->length);
285 * Create a Python object from a ldb_result.
287 * @param result LDB result to convert
288 * @return Python object with converted result (a list object)
290 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
292 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
293 PyLdbControlObject *ctrl;
294 if (ctl_ctx == NULL) {
299 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
301 talloc_free(ctl_ctx);
305 ctrl->mem_ctx = ctl_ctx;
306 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
307 if (ctrl->data == NULL) {
312 return (PyObject*) ctrl;
316 * Create a Python object from a ldb_result.
318 * @param result LDB result to convert
319 * @return Python object with converted result (a list object)
321 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
323 PyLdbResultObject *ret;
324 PyObject *list, *controls, *referals;
327 if (result == NULL) {
331 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
337 list = PyList_New(result->count);
344 for (i = 0; i < result->count; i++) {
345 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
348 ret->mem_ctx = talloc_new(NULL);
349 if (ret->mem_ctx == NULL) {
358 if (result->controls) {
360 while (result->controls[i]) {
363 controls = PyList_New(i);
364 if (controls == NULL) {
369 for (i=0; result->controls[i]; i++) {
370 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
377 PyList_SetItem(controls, i, ctrl);
381 * No controls so we keep an empty list
383 controls = PyList_New(0);
384 if (controls == NULL) {
391 ret->controls = controls;
395 while (result->refs && result->refs[i]) {
399 referals = PyList_New(i);
400 if (referals == NULL) {
406 for (i = 0;result->refs && result->refs[i]; i++) {
407 PyList_SetItem(referals, i, PyStr_FromString(result->refs[i]));
409 ret->referals = referals;
410 return (PyObject *)ret;
414 * Create a LDB Result from a Python object.
415 * If conversion fails, NULL will be returned and a Python exception set.
417 * Note: the result object only includes the messages at the moment; extended
418 * result, controls and referrals are ignored.
420 * @param mem_ctx Memory context in which to allocate the LDB Result
421 * @param obj Python object to convert
422 * @return a ldb_result, or NULL if the conversion failed
424 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
427 struct ldb_result *res;
433 res = talloc_zero(mem_ctx, struct ldb_result);
434 res->count = PyList_Size(obj);
435 res->msgs = talloc_array(res, struct ldb_message *, res->count);
436 for (i = 0; i < res->count; i++) {
437 PyObject *item = PyList_GetItem(obj, i);
438 res->msgs[i] = pyldb_Message_AsMessage(item);
443 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
445 return PyBool_FromLong(ldb_dn_validate(self->dn));
448 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
450 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
453 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
455 return PyBool_FromLong(ldb_dn_is_special(self->dn));
458 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
460 return PyBool_FromLong(ldb_dn_is_null(self->dn));
463 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
465 return PyStr_FromString(ldb_dn_get_casefold(self->dn));
468 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
470 return PyStr_FromString(ldb_dn_get_linearized(self->dn));
473 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
475 return PyStr_FromString(ldb_dn_canonical_string(self->dn, self->dn));
478 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
480 return PyStr_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
483 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
485 const char * const kwnames[] = { "mode", NULL };
487 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
488 discard_const_p(char *, kwnames),
491 return PyStr_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
494 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
497 const struct ldb_val *val;
499 if (!PyArg_ParseTuple(args, "s", &name))
501 val = ldb_dn_get_extended_component(self->dn, name);
506 return PyBytes_FromStringAndSize((const char *)val->data, val->length);
509 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
516 if (!PyArg_ParseTuple(args, "sz#", &name, (const char**)&value, &size))
520 err = ldb_dn_set_extended_component(self->dn, name, NULL);
523 val.data = (uint8_t *)value;
525 err = ldb_dn_set_extended_component(self->dn, name, &val);
528 if (err != LDB_SUCCESS) {
529 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
536 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
538 PyObject *str = PyStr_FromString(ldb_dn_get_linearized(self->dn));
539 PyObject *repr, *result;
542 repr = PyObject_Repr(str);
547 result = PyStr_FromFormat("Dn(%s)", PyStr_AsUTF8(repr));
553 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
557 if (!PyArg_ParseTuple(args, "s", &name))
560 return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
563 static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
566 if (!pyldb_Dn_Check(dn2)) {
567 Py_INCREF(Py_NotImplemented);
568 return Py_NotImplemented;
570 ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2));
571 return richcmp(ret, op);
574 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
576 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
577 struct ldb_dn *parent;
578 PyLdbDnObject *py_ret;
579 TALLOC_CTX *mem_ctx = talloc_new(NULL);
581 parent = ldb_dn_get_parent(mem_ctx, dn);
582 if (parent == NULL) {
583 talloc_free(mem_ctx);
587 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
588 if (py_ret == NULL) {
590 talloc_free(mem_ctx);
593 py_ret->mem_ctx = mem_ctx;
595 return (PyObject *)py_ret;
598 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
601 struct ldb_dn *dn, *other;
602 if (!PyArg_ParseTuple(args, "O", &py_other))
605 dn = pyldb_Dn_AsDn((PyObject *)self);
607 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
610 return PyBool_FromLong(ldb_dn_add_child(dn, other));
613 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
616 struct ldb_dn *other, *dn;
617 if (!PyArg_ParseTuple(args, "O", &py_other))
620 dn = pyldb_Dn_AsDn((PyObject *)self);
622 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
625 return PyBool_FromLong(ldb_dn_add_base(dn, other));
628 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
632 if (!PyArg_ParseTuple(args, "i", &i))
635 dn = pyldb_Dn_AsDn((PyObject *)self);
637 return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
640 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
643 struct ldb_dn *dn, *base;
644 if (!PyArg_ParseTuple(args, "O", &py_base))
647 dn = pyldb_Dn_AsDn((PyObject *)self);
649 if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
652 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
655 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
659 unsigned int num = 0;
661 if (!PyArg_ParseTuple(args, "I", &num))
664 dn = pyldb_Dn_AsDn((PyObject *)self);
666 name = ldb_dn_get_component_name(dn, num);
671 return PyStr_FromString(name);
674 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
677 const struct ldb_val *val;
678 unsigned int num = 0;
680 if (!PyArg_ParseTuple(args, "I", &num))
683 dn = pyldb_Dn_AsDn((PyObject *)self);
685 val = ldb_dn_get_component_val(dn, num);
690 return PyStr_FromLdbValue(val);
693 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
695 unsigned int num = 0;
696 char *name = NULL, *value = NULL;
697 struct ldb_val val = { NULL, };
701 if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size))
704 val.data = (unsigned char*) value;
707 err = ldb_dn_set_component(self->dn, num, name, val);
708 if (err != LDB_SUCCESS) {
709 PyErr_SetString(PyExc_TypeError, "Failed to set component");
716 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
721 dn = pyldb_Dn_AsDn((PyObject *)self);
723 name = ldb_dn_get_rdn_name(dn);
728 return PyStr_FromString(name);
731 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
734 const struct ldb_val *val;
736 dn = pyldb_Dn_AsDn((PyObject *)self);
738 val = ldb_dn_get_rdn_val(dn);
743 return PyStr_FromLdbValue(val);
746 static PyMethodDef py_ldb_dn_methods[] = {
747 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
748 "S.validate() -> bool\n"
749 "Validate DN is correct." },
750 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
751 "S.is_valid() -> bool\n" },
752 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
753 "S.is_special() -> bool\n"
754 "Check whether this is a special LDB DN." },
755 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
756 "Check whether this is a null DN." },
757 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
759 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
761 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
762 "S.canonical_str() -> string\n"
763 "Canonical version of this DN (like a posix path)." },
764 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
765 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
766 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
767 "S.canonical_ex_str() -> string\n"
768 "Canonical version of this DN (like a posix path, with terminating newline)." },
769 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
770 "S.extended_str(mode=1) -> string\n"
771 "Extended version of this DN" },
772 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
774 "Get the parent for this DN." },
775 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
776 "S.add_child(dn) -> None\n"
777 "Add a child DN to this DN." },
778 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
779 "S.add_base(dn) -> None\n"
780 "Add a base DN to this DN." },
781 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
782 "S.remove_base_components(int) -> bool\n"
783 "Remove a number of DN components from the base of this DN." },
784 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
785 "S.check_special(name) -> bool\n\n"
786 "Check if name is a special DN name"},
787 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
788 "S.get_extended_component(name) -> string\n\n"
789 "returns a DN extended component as a binary string"},
790 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
791 "S.set_extended_component(name, value) -> None\n\n"
792 "set a DN extended component as a binary string"},
793 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
794 "S.get_component_name(num) -> string\n"
795 "get the attribute name of the specified component" },
796 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
797 "S.get_component_value(num) -> string\n"
798 "get the attribute value of the specified component as a binary string" },
799 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
800 "S.get_component_value(num, name, value) -> None\n"
801 "set the attribute name and value of the specified component" },
802 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
803 "S.get_rdn_name() -> string\n"
804 "get the RDN attribute name" },
805 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
806 "S.get_rdn_value() -> string\n"
807 "get the RDN attribute value as a binary string" },
811 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
813 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
817 copy a DN as a python object
819 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
821 PyLdbDnObject *py_ret;
823 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
824 if (py_ret == NULL) {
828 py_ret->mem_ctx = talloc_new(NULL);
829 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
830 return (PyObject *)py_ret;
833 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
835 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
837 PyLdbDnObject *py_ret;
839 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
842 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
843 if (py_ret == NULL) {
847 py_ret->mem_ctx = talloc_new(NULL);
848 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
849 ldb_dn_add_base(py_ret->dn, other);
850 return (PyObject *)py_ret;
853 static PySequenceMethods py_ldb_dn_seq = {
854 .sq_length = (lenfunc)py_ldb_dn_len,
855 .sq_concat = (binaryfunc)py_ldb_dn_concat,
858 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
863 struct ldb_context *ldb_ctx;
865 PyLdbDnObject *py_ret;
866 const char * const kwnames[] = { "ldb", "dn", NULL };
868 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
869 discard_const_p(char *, kwnames),
873 if (!PyLdb_Check(py_ldb)) {
874 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
878 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
880 mem_ctx = talloc_new(NULL);
881 if (mem_ctx == NULL) {
886 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
887 if (!ldb_dn_validate(ret)) {
888 talloc_free(mem_ctx);
889 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
893 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
895 talloc_free(mem_ctx);
899 py_ret->mem_ctx = mem_ctx;
901 return (PyObject *)py_ret;
904 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
906 talloc_free(self->mem_ctx);
910 static PyTypeObject PyLdbDn = {
912 .tp_methods = py_ldb_dn_methods,
913 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
914 .tp_repr = (reprfunc)py_ldb_dn_repr,
915 .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp,
916 .tp_as_sequence = &py_ldb_dn_seq,
917 .tp_doc = "A LDB distinguished name.",
918 .tp_new = py_ldb_dn_new,
919 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
920 .tp_basicsize = sizeof(PyLdbDnObject),
921 .tp_flags = Py_TPFLAGS_DEFAULT,
925 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
926 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
928 PyObject *fn = (PyObject *)context;
929 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyStr_FromFormatV(fmt, ap));
932 static PyObject *py_ldb_debug_func;
934 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
937 struct ldb_context *ldb_ctx;
939 if (!PyArg_ParseTuple(args, "O", &cb))
942 if (py_ldb_debug_func != NULL) {
943 Py_DECREF(py_ldb_debug_func);
947 /* FIXME: DECREF cb when exiting program */
948 py_ldb_debug_func = cb;
949 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
950 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
951 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
957 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
960 if (!PyArg_ParseTuple(args, "I", &perms))
963 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
968 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
971 if (!PyArg_ParseTuple(args, "s", &modules_dir))
974 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
979 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
981 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
983 ldb_err = ldb_transaction_start(ldb_ctx);
984 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
988 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
990 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
992 ldb_err = ldb_transaction_commit(ldb_ctx);
993 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
997 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
999 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1001 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
1002 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1006 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
1008 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1010 ldb_err = ldb_transaction_cancel(ldb_ctx);
1011 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1015 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
1017 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1019 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
1020 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1024 static PyObject *py_ldb_repr(PyLdbObject *self)
1026 return PyStr_FromString("<ldb connection>");
1029 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
1031 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
1034 return py_ldb_dn_copy(dn);
1038 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
1040 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
1043 return py_ldb_dn_copy(dn);
1046 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
1048 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
1051 return py_ldb_dn_copy(dn);
1054 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
1056 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
1059 return py_ldb_dn_copy(dn);
1062 static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
1063 const char *paramname)
1067 if (!PyList_Check(list)) {
1068 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
1071 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1077 for (i = 0; i < PyList_Size(list); i++) {
1078 const char *str = NULL;
1080 PyObject *item = PyList_GetItem(list, i);
1081 if (!PyStr_Check(item)) {
1082 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
1086 str = PyStr_AsUTF8AndSize(item, &size);
1091 ret[i] = talloc_strndup(ret, str, size);
1097 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1099 const char * const kwnames[] = { "url", "flags", "options", NULL };
1101 PyObject *py_options = Py_None;
1102 const char **options;
1103 unsigned int flags = 0;
1105 struct ldb_context *ldb;
1107 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1108 discard_const_p(char *, kwnames),
1109 &url, &flags, &py_options))
1112 ldb = pyldb_Ldb_AsLdbContext(self);
1114 if (py_options == Py_None) {
1117 options = PyList_AsStrList(ldb, py_options, "options");
1118 if (options == NULL)
1123 ret = ldb_connect(ldb, url, flags, options);
1124 if (ret != LDB_SUCCESS) {
1125 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1130 talloc_free(options);
1134 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1137 struct ldb_context *ldb;
1138 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1143 ret->mem_ctx = talloc_new(NULL);
1144 ldb = ldb_init(ret->mem_ctx, NULL);
1152 return (PyObject *)ret;
1155 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1158 unsigned int flags = 0;
1159 PyObject *py_options = Py_None;
1161 const char **options;
1162 const char * const kwnames[] = { "url", "flags", "options", NULL };
1163 struct ldb_context *ldb_ctx;
1165 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
1166 discard_const_p(char *, kwnames),
1167 &url, &flags, &py_options))
1170 if (py_options == Py_None) {
1173 options = PyList_AsStrList(NULL, py_options, "options");
1174 if (options == NULL)
1178 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1179 ret = ldb_connect(ldb_ctx, url, flags, options);
1180 talloc_free(options);
1182 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1187 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1190 PyObject *py_controls = Py_None;
1191 struct ldb_context *ldb_ctx;
1192 struct ldb_request *req;
1193 struct ldb_control **parsed_controls;
1194 struct ldb_message *msg;
1196 TALLOC_CTX *mem_ctx;
1198 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1200 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1201 discard_const_p(char *, kwnames),
1202 &py_msg, &py_controls, &validate))
1205 mem_ctx = talloc_new(NULL);
1206 if (mem_ctx == NULL) {
1210 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1212 if (py_controls == Py_None) {
1213 parsed_controls = NULL;
1215 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1216 if (controls == NULL) {
1217 talloc_free(mem_ctx);
1220 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1221 talloc_free(controls);
1224 if (!PyLdbMessage_Check(py_msg)) {
1225 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1226 talloc_free(mem_ctx);
1229 msg = pyldb_Message_AsMessage(py_msg);
1232 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1233 if (ret != LDB_SUCCESS) {
1234 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1235 talloc_free(mem_ctx);
1240 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1241 NULL, ldb_op_default_callback, NULL);
1242 if (ret != LDB_SUCCESS) {
1243 PyErr_SetString(PyExc_TypeError, "failed to build request");
1244 talloc_free(mem_ctx);
1248 /* do request and autostart a transaction */
1249 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1251 ret = ldb_transaction_start(ldb_ctx);
1252 if (ret != LDB_SUCCESS) {
1253 talloc_free(mem_ctx);
1254 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1258 ret = ldb_request(ldb_ctx, req);
1259 if (ret == LDB_SUCCESS) {
1260 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1263 if (ret == LDB_SUCCESS) {
1264 ret = ldb_transaction_commit(ldb_ctx);
1266 ldb_transaction_cancel(ldb_ctx);
1269 talloc_free(mem_ctx);
1270 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1277 * Obtain a ldb message from a Python Dictionary object.
1279 * @param mem_ctx Memory context
1280 * @param py_obj Python Dictionary object
1281 * @param ldb_ctx LDB context
1282 * @param mod_flags Flags to be set on every message element
1283 * @return ldb_message on success or NULL on failure
1285 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1287 struct ldb_context *ldb_ctx,
1288 unsigned int mod_flags)
1290 struct ldb_message *msg;
1291 unsigned int msg_pos = 0;
1292 Py_ssize_t dict_pos = 0;
1293 PyObject *key, *value;
1294 struct ldb_message_element *msg_el;
1295 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1297 msg = ldb_msg_new(mem_ctx);
1302 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1305 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1306 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1309 if (msg->dn == NULL) {
1310 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1314 PyErr_SetString(PyExc_TypeError, "no dn set");
1318 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1319 char *key_str = PyStr_AsUTF8(key);
1320 if (ldb_attr_cmp(key_str, "dn") != 0) {
1321 msg_el = PyObject_AsMessageElement(msg->elements, value,
1322 mod_flags, key_str);
1323 if (msg_el == NULL) {
1324 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1327 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1332 msg->num_elements = msg_pos;
1337 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1341 struct ldb_context *ldb_ctx;
1342 struct ldb_request *req;
1343 struct ldb_message *msg = NULL;
1344 PyObject *py_controls = Py_None;
1345 TALLOC_CTX *mem_ctx;
1346 struct ldb_control **parsed_controls;
1347 const char * const kwnames[] = { "message", "controls", NULL };
1349 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1350 discard_const_p(char *, kwnames),
1351 &py_obj, &py_controls))
1354 mem_ctx = talloc_new(NULL);
1355 if (mem_ctx == NULL) {
1359 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1361 if (py_controls == Py_None) {
1362 parsed_controls = NULL;
1364 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1365 if (controls == NULL) {
1366 talloc_free(mem_ctx);
1369 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1370 talloc_free(controls);
1373 if (PyLdbMessage_Check(py_obj)) {
1374 msg = pyldb_Message_AsMessage(py_obj);
1375 } else if (PyDict_Check(py_obj)) {
1376 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1378 PyErr_SetString(PyExc_TypeError,
1379 "Dictionary or LdbMessage object expected!");
1383 /* we should have a PyErr already set */
1384 talloc_free(mem_ctx);
1388 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1389 if (ret != LDB_SUCCESS) {
1390 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1391 talloc_free(mem_ctx);
1395 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1396 NULL, ldb_op_default_callback, NULL);
1397 if (ret != LDB_SUCCESS) {
1398 PyErr_SetString(PyExc_TypeError, "failed to build request");
1399 talloc_free(mem_ctx);
1403 /* do request and autostart a transaction */
1404 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1406 ret = ldb_transaction_start(ldb_ctx);
1407 if (ret != LDB_SUCCESS) {
1408 talloc_free(mem_ctx);
1409 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1413 ret = ldb_request(ldb_ctx, req);
1414 if (ret == LDB_SUCCESS) {
1415 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1418 if (ret == LDB_SUCCESS) {
1419 ret = ldb_transaction_commit(ldb_ctx);
1421 ldb_transaction_cancel(ldb_ctx);
1424 talloc_free(mem_ctx);
1425 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1430 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1435 struct ldb_context *ldb_ctx;
1436 struct ldb_request *req;
1437 PyObject *py_controls = Py_None;
1438 TALLOC_CTX *mem_ctx;
1439 struct ldb_control **parsed_controls;
1440 const char * const kwnames[] = { "dn", "controls", NULL };
1442 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1443 discard_const_p(char *, kwnames),
1444 &py_dn, &py_controls))
1447 mem_ctx = talloc_new(NULL);
1448 if (mem_ctx == NULL) {
1452 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1454 if (py_controls == Py_None) {
1455 parsed_controls = NULL;
1457 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1458 if (controls == NULL) {
1459 talloc_free(mem_ctx);
1462 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1463 talloc_free(controls);
1466 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1467 talloc_free(mem_ctx);
1471 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1472 NULL, ldb_op_default_callback, NULL);
1473 if (ret != LDB_SUCCESS) {
1474 PyErr_SetString(PyExc_TypeError, "failed to build request");
1475 talloc_free(mem_ctx);
1479 /* do request and autostart a transaction */
1480 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1482 ret = ldb_transaction_start(ldb_ctx);
1483 if (ret != LDB_SUCCESS) {
1484 talloc_free(mem_ctx);
1485 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1489 ret = ldb_request(ldb_ctx, req);
1490 if (ret == LDB_SUCCESS) {
1491 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1494 if (ret == LDB_SUCCESS) {
1495 ret = ldb_transaction_commit(ldb_ctx);
1497 ldb_transaction_cancel(ldb_ctx);
1500 talloc_free(mem_ctx);
1501 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1506 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1508 PyObject *py_dn1, *py_dn2;
1509 struct ldb_dn *dn1, *dn2;
1511 TALLOC_CTX *mem_ctx;
1512 PyObject *py_controls = Py_None;
1513 struct ldb_control **parsed_controls;
1514 struct ldb_context *ldb_ctx;
1515 struct ldb_request *req;
1516 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1518 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1520 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1521 discard_const_p(char *, kwnames),
1522 &py_dn1, &py_dn2, &py_controls))
1526 mem_ctx = talloc_new(NULL);
1527 if (mem_ctx == NULL) {
1532 if (py_controls == Py_None) {
1533 parsed_controls = NULL;
1535 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1536 if (controls == NULL) {
1537 talloc_free(mem_ctx);
1540 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1541 talloc_free(controls);
1545 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1546 talloc_free(mem_ctx);
1550 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1551 talloc_free(mem_ctx);
1555 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1556 NULL, ldb_op_default_callback, NULL);
1557 if (ret != LDB_SUCCESS) {
1558 PyErr_SetString(PyExc_TypeError, "failed to build request");
1559 talloc_free(mem_ctx);
1563 /* do request and autostart a transaction */
1564 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1566 ret = ldb_transaction_start(ldb_ctx);
1567 if (ret != LDB_SUCCESS) {
1568 talloc_free(mem_ctx);
1569 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1573 ret = ldb_request(ldb_ctx, req);
1574 if (ret == LDB_SUCCESS) {
1575 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1578 if (ret == LDB_SUCCESS) {
1579 ret = ldb_transaction_commit(ldb_ctx);
1581 ldb_transaction_cancel(ldb_ctx);
1584 talloc_free(mem_ctx);
1585 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1590 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1593 if (!PyArg_ParseTuple(args, "s", &name))
1596 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1601 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1603 char *attribute, *syntax;
1606 struct ldb_context *ldb_ctx;
1608 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1611 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1612 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1614 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1619 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1624 /* We don't want this attached to the 'ldb' any more */
1625 return Py_BuildValue(discard_const_p(char, "(iO)"),
1627 PyLdbMessage_FromMessage(ldif->msg));
1632 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1636 struct ldb_ldif ldif;
1639 TALLOC_CTX *mem_ctx;
1641 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1644 if (!PyLdbMessage_Check(py_msg)) {
1645 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1649 ldif.msg = pyldb_Message_AsMessage(py_msg);
1650 ldif.changetype = changetype;
1652 mem_ctx = talloc_new(NULL);
1654 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1656 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1660 ret = PyStr_FromString(string);
1662 talloc_free(mem_ctx);
1667 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1669 PyObject *list, *ret;
1670 struct ldb_ldif *ldif;
1673 TALLOC_CTX *mem_ctx;
1675 if (!PyArg_ParseTuple(args, "s", &s))
1678 mem_ctx = talloc_new(NULL);
1683 list = PyList_New(0);
1684 while (s && *s != '\0') {
1685 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1686 talloc_steal(mem_ctx, ldif);
1688 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1690 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1691 talloc_free(mem_ctx);
1695 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1696 ret = PyObject_GetIter(list);
1701 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1704 PyObject *py_msg_old;
1705 PyObject *py_msg_new;
1706 struct ldb_message *diff;
1707 struct ldb_context *ldb;
1710 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1713 if (!PyLdbMessage_Check(py_msg_old)) {
1714 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1718 if (!PyLdbMessage_Check(py_msg_new)) {
1719 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1723 ldb = pyldb_Ldb_AsLdbContext(self);
1724 ldb_ret = ldb_msg_difference(ldb, ldb,
1725 pyldb_Message_AsMessage(py_msg_old),
1726 pyldb_Message_AsMessage(py_msg_new),
1728 if (ldb_ret != LDB_SUCCESS) {
1729 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1733 py_ret = PyLdbMessage_FromMessage(diff);
1735 talloc_unlink(ldb, diff);
1740 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1742 const struct ldb_schema_attribute *a;
1743 struct ldb_val old_val;
1744 struct ldb_val new_val;
1745 TALLOC_CTX *mem_ctx;
1752 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1755 result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1756 old_val.length = size;
1759 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1763 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1769 mem_ctx = talloc_new(NULL);
1770 if (mem_ctx == NULL) {
1775 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1776 talloc_free(mem_ctx);
1780 ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1782 talloc_free(mem_ctx);
1787 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1789 PyObject *py_base = Py_None;
1790 int scope = LDB_SCOPE_DEFAULT;
1792 PyObject *py_attrs = Py_None;
1793 PyObject *py_controls = Py_None;
1794 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1796 struct ldb_result *res;
1797 struct ldb_request *req;
1799 struct ldb_context *ldb_ctx;
1800 struct ldb_control **parsed_controls;
1801 struct ldb_dn *base;
1803 TALLOC_CTX *mem_ctx;
1805 /* type "int" rather than "enum" for "scope" is intentional */
1806 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1807 discard_const_p(char *, kwnames),
1808 &py_base, &scope, &expr, &py_attrs, &py_controls))
1812 mem_ctx = talloc_new(NULL);
1813 if (mem_ctx == NULL) {
1817 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1819 if (py_attrs == Py_None) {
1822 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1823 if (attrs == NULL) {
1824 talloc_free(mem_ctx);
1829 if (py_base == Py_None) {
1830 base = ldb_get_default_basedn(ldb_ctx);
1832 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1833 talloc_free(mem_ctx);
1838 if (py_controls == Py_None) {
1839 parsed_controls = NULL;
1841 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1842 if (controls == NULL) {
1843 talloc_free(mem_ctx);
1846 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1847 talloc_free(controls);
1850 res = talloc_zero(mem_ctx, struct ldb_result);
1853 talloc_free(mem_ctx);
1857 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1864 ldb_search_default_callback,
1867 if (ret != LDB_SUCCESS) {
1868 talloc_free(mem_ctx);
1869 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1873 talloc_steal(req, attrs);
1875 ret = ldb_request(ldb_ctx, req);
1877 if (ret == LDB_SUCCESS) {
1878 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1881 if (ret != LDB_SUCCESS) {
1882 talloc_free(mem_ctx);
1883 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1887 py_ret = PyLdbResult_FromResult(res);
1889 talloc_free(mem_ctx);
1894 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
1896 if (reply->py_iter != NULL) {
1897 DLIST_REMOVE(reply->py_iter->state.next, reply);
1898 if (reply->py_iter->state.result == reply) {
1899 reply->py_iter->state.result = NULL;
1901 reply->py_iter = NULL;
1904 if (reply->obj != NULL) {
1905 Py_DECREF(reply->obj);
1912 static int py_ldb_search_iterator_callback(struct ldb_request *req,
1913 struct ldb_reply *ares)
1915 PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
1916 struct ldb_result result = { .msgs = NULL };
1917 struct py_ldb_search_iterator_reply *reply = NULL;
1920 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1923 if (ares->error != LDB_SUCCESS) {
1924 int ret = ares->error;
1926 return ldb_request_done(req, ret);
1929 reply = talloc_zero(py_iter->mem_ctx,
1930 struct py_ldb_search_iterator_reply);
1931 if (reply == NULL) {
1933 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1935 reply->py_iter = py_iter;
1936 talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
1938 switch (ares->type) {
1939 case LDB_REPLY_ENTRY:
1940 reply->obj = PyLdbMessage_FromMessage(ares->message);
1941 if (reply->obj == NULL) {
1943 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1945 DLIST_ADD_END(py_iter->state.next, reply);
1949 case LDB_REPLY_REFERRAL:
1950 reply->obj = PyStr_FromString(ares->referral);
1951 if (reply->obj == NULL) {
1953 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1955 DLIST_ADD_END(py_iter->state.next, reply);
1959 case LDB_REPLY_DONE:
1960 result = (struct ldb_result) { .controls = ares->controls };
1961 reply->obj = PyLdbResult_FromResult(&result);
1962 if (reply->obj == NULL) {
1964 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1966 py_iter->state.result = reply;
1968 return ldb_request_done(req, LDB_SUCCESS);
1972 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1975 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1977 PyObject *py_base = Py_None;
1978 int scope = LDB_SCOPE_DEFAULT;
1981 PyObject *py_attrs = Py_None;
1982 PyObject *py_controls = Py_None;
1983 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
1986 struct ldb_context *ldb_ctx;
1987 struct ldb_control **parsed_controls;
1988 struct ldb_dn *base;
1989 PyLdbSearchIteratorObject *py_iter;
1991 /* type "int" rather than "enum" for "scope" is intentional */
1992 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
1993 discard_const_p(char *, kwnames),
1994 &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
1997 py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
1998 if (py_iter == NULL) {
2002 py_iter->ldb = self;
2004 ZERO_STRUCT(py_iter->state);
2005 py_iter->mem_ctx = talloc_new(NULL);
2006 if (py_iter->mem_ctx == NULL) {
2012 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2014 if (py_attrs == Py_None) {
2017 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2018 if (attrs == NULL) {
2025 if (py_base == Py_None) {
2026 base = ldb_get_default_basedn(ldb_ctx);
2028 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2035 if (py_controls == Py_None) {
2036 parsed_controls = NULL;
2038 const char **controls = NULL;
2040 controls = PyList_AsStrList(py_iter->mem_ctx,
2041 py_controls, "controls");
2042 if (controls == NULL) {
2048 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2051 if (controls[0] != NULL && parsed_controls == NULL) {
2056 talloc_free(controls);
2059 ret = ldb_build_search_req(&py_iter->state.req,
2068 py_ldb_search_iterator_callback,
2070 if (ret != LDB_SUCCESS) {
2072 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2076 ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2078 ret = ldb_request(ldb_ctx, py_iter->state.req);
2079 if (ret != LDB_SUCCESS) {
2081 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2085 return (PyObject *)py_iter;
2088 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2093 if (!PyArg_ParseTuple(args, "s", &name))
2096 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
2101 /* FIXME: More interpretation */
2106 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2111 if (!PyArg_ParseTuple(args, "sO", &name, &data))
2114 /* FIXME: More interpretation */
2116 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
2121 static PyObject *py_ldb_modules(PyLdbObject *self)
2123 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2124 PyObject *ret = PyList_New(0);
2125 struct ldb_module *mod;
2127 for (mod = ldb->modules; mod; mod = mod->next) {
2128 PyList_Append(ret, PyLdbModule_FromModule(mod));
2134 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2136 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2140 if (!PyArg_ParseTuple(args, "i", &type))
2143 /* FIXME: More interpretation */
2145 ret = ldb_sequence_number(ldb, type, &value);
2147 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2149 return PyLong_FromLongLong(value);
2153 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2155 .read_fn = ldb_handler_copy,
2156 .write_clear_fn = ldb_handler_copy,
2157 .write_hex_fn = ldb_handler_copy,
2160 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self)
2162 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2165 ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2167 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2173 static PyMethodDef py_ldb_methods[] = {
2174 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
2175 "S.set_debug(callback) -> None\n"
2176 "Set callback for LDB debug messages.\n"
2177 "The callback should accept a debug level and debug text." },
2178 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
2179 "S.set_create_perms(mode) -> None\n"
2180 "Set mode to use when creating new LDB files." },
2181 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2182 "S.set_modules_dir(path) -> None\n"
2183 "Set path LDB should search for modules" },
2184 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
2185 "S.transaction_start() -> None\n"
2186 "Start a new transaction." },
2187 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2188 "S.transaction_prepare_commit() -> None\n"
2189 "prepare to commit a new transaction (2-stage commit)." },
2190 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
2191 "S.transaction_commit() -> None\n"
2192 "commit a new transaction." },
2193 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
2194 "S.transaction_cancel() -> None\n"
2195 "cancel a new transaction." },
2196 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
2198 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2200 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2202 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2204 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2206 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
2207 "S.connect(url, flags=0, options=None) -> None\n"
2208 "Connect to a LDB URL." },
2209 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
2210 "S.modify(message, controls=None, validate=False) -> None\n"
2211 "Modify an entry." },
2212 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
2213 "S.add(message, controls=None) -> None\n"
2215 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
2216 "S.delete(dn, controls=None) -> None\n"
2217 "Remove an entry." },
2218 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
2219 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2220 "Rename an entry." },
2221 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
2222 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2223 "Search in a database.\n"
2225 ":param base: Optional base DN to search\n"
2226 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2227 ":param expression: Optional search expression\n"
2228 ":param attrs: Attributes to return (defaults to all)\n"
2229 ":param controls: Optional list of controls\n"
2230 ":return: ldb.Result object\n"
2232 { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS,
2233 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2234 "Search in a database.\n"
2236 ":param base: Optional base DN to search\n"
2237 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2238 ":param expression: Optional search expression\n"
2239 ":param attrs: Attributes to return (defaults to all)\n"
2240 ":param controls: Optional list of controls\n"
2241 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2242 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2244 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2246 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2248 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2250 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2251 "S.parse_ldif(ldif) -> iter(messages)\n"
2252 "Parse a string formatted using LDIF." },
2253 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2254 "S.write_ldif(message, changetype) -> ldif\n"
2255 "Print the message as a string formatted using LDIF." },
2256 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2257 "S.msg_diff(Message) -> Message\n"
2258 "Return an LDB Message of the difference between two Message objects." },
2259 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2260 "S.get_opaque(name) -> value\n"
2261 "Get an opaque value set on this LDB connection. \n"
2262 ":note: The returned value may not be useful in Python."
2264 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2265 "S.set_opaque(name, value) -> None\n"
2266 "Set an opaque value on this LDB connection. \n"
2267 ":note: Passing incorrect values may cause crashes." },
2268 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2269 "S.modules() -> list\n"
2270 "Return the list of modules on this LDB connection " },
2271 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2272 "S.sequence_number(type) -> value\n"
2273 "Return the value of the sequence according to the requested type" },
2274 { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2275 "S._register_test_extensions() -> None\n"
2276 "Register internal extensions used in testing" },
2280 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2282 PyLdbModuleObject *ret;
2284 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2289 ret->mem_ctx = talloc_new(NULL);
2290 ret->mod = talloc_reference(ret->mem_ctx, mod);
2291 return (PyObject *)ret;
2294 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2296 struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2300 return PyLdbModule_FromModule(mod);
2303 static PyGetSetDef py_ldb_getset[] = {
2304 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
2308 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2310 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2312 struct ldb_result *result;
2316 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2320 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2322 if (ret != LDB_SUCCESS) {
2323 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2327 count = result->count;
2329 talloc_free(result);
2332 PyErr_Format(PyExc_RuntimeError,
2333 "Searching for [%s] dn gave %u results!",
2334 ldb_dn_get_linearized(dn),
2342 static PySequenceMethods py_ldb_seq = {
2343 .sq_contains = (objobjproc)py_ldb_contains,
2346 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2350 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2355 ret->mem_ctx = talloc_new(NULL);
2356 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2357 return (PyObject *)ret;
2360 static void py_ldb_dealloc(PyLdbObject *self)
2362 talloc_free(self->mem_ctx);
2363 Py_TYPE(self)->tp_free(self);
2366 static PyTypeObject PyLdb = {
2367 .tp_name = "ldb.Ldb",
2368 .tp_methods = py_ldb_methods,
2369 .tp_repr = (reprfunc)py_ldb_repr,
2370 .tp_new = py_ldb_new,
2371 .tp_init = (initproc)py_ldb_init,
2372 .tp_dealloc = (destructor)py_ldb_dealloc,
2373 .tp_getset = py_ldb_getset,
2374 .tp_getattro = PyObject_GenericGetAttr,
2375 .tp_basicsize = sizeof(PyLdbObject),
2376 .tp_doc = "Connection to a LDB database.",
2377 .tp_as_sequence = &py_ldb_seq,
2378 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2381 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2383 talloc_free(self->mem_ctx);
2384 Py_DECREF(self->msgs);
2385 Py_DECREF(self->referals);
2386 Py_DECREF(self->controls);
2387 Py_TYPE(self)->tp_free(self);
2390 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2392 Py_INCREF(self->msgs);
2396 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2398 Py_INCREF(self->controls);
2399 return self->controls;
2402 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2404 Py_INCREF(self->referals);
2405 return self->referals;
2408 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2411 if (self->msgs == NULL) {
2412 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2415 size = PyList_Size(self->msgs);
2416 return PyInt_FromLong(size);
2419 static PyGetSetDef py_ldb_result_getset[] = {
2420 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2421 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2422 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2423 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2427 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2429 return PyObject_GetIter(self->msgs);
2432 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2434 return PySequence_Size(self->msgs);
2437 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2439 return PySequence_GetItem(self->msgs, idx);
2442 static PySequenceMethods py_ldb_result_seq = {
2443 .sq_length = (lenfunc)py_ldb_result_len,
2444 .sq_item = (ssizeargfunc)py_ldb_result_find,
2447 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2449 return PyStr_FromString("<ldb result>");
2453 static PyTypeObject PyLdbResult = {
2454 .tp_name = "ldb.Result",
2455 .tp_repr = (reprfunc)py_ldb_result_repr,
2456 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2457 .tp_iter = (getiterfunc)py_ldb_result_iter,
2458 .tp_getset = py_ldb_result_getset,
2459 .tp_getattro = PyObject_GenericGetAttr,
2460 .tp_basicsize = sizeof(PyLdbResultObject),
2461 .tp_as_sequence = &py_ldb_result_seq,
2462 .tp_doc = "LDB result.",
2463 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2466 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2468 Py_XDECREF(self->state.exception);
2469 TALLOC_FREE(self->mem_ctx);
2470 ZERO_STRUCT(self->state);
2471 Py_DECREF(self->ldb);
2472 Py_TYPE(self)->tp_free(self);
2475 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2477 PyObject *py_ret = NULL;
2479 if (self->state.req == NULL) {
2480 PyErr_SetString(PyExc_RuntimeError,
2481 "ldb.SearchIterator request already finished");
2486 * TODO: do we want a non-blocking mode?
2487 * In future we may add an optional 'nonblocking'
2488 * argument to search_iterator().
2490 * For now we keep it simple and wait for at
2494 while (self->state.next == NULL) {
2497 if (self->state.result != NULL) {
2499 * We (already) got a final result from the server.
2501 * We stop the iteration and let
2502 * py_ldb_search_iterator_result() will deliver
2503 * the result details.
2505 TALLOC_FREE(self->state.req);
2506 PyErr_SetNone(PyExc_StopIteration);
2510 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2511 if (ret != LDB_SUCCESS) {
2512 struct ldb_context *ldb_ctx;
2513 TALLOC_FREE(self->state.req);
2514 ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb);
2516 * We stop the iteration and let
2517 * py_ldb_search_iterator_result() will deliver
2520 self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2521 ret, ldb_errstring(ldb_ctx));
2522 PyErr_SetNone(PyExc_StopIteration);
2527 py_ret = self->state.next->obj;
2528 self->state.next->obj = NULL;
2529 /* no TALLOC_FREE() as self->state.next is a list */
2530 talloc_free(self->state.next);
2534 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self)
2536 PyObject *py_ret = NULL;
2538 if (self->state.req != NULL) {
2539 PyErr_SetString(PyExc_RuntimeError,
2540 "ldb.SearchIterator request running");
2544 if (self->state.next != NULL) {
2545 PyErr_SetString(PyExc_RuntimeError,
2546 "ldb.SearchIterator not fully consumed.");
2550 if (self->state.exception != NULL) {
2551 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2552 self->state.exception = NULL;
2556 if (self->state.result == NULL) {
2557 PyErr_SetString(PyExc_RuntimeError,
2558 "ldb.SearchIterator result already consumed");
2562 py_ret = self->state.result->obj;
2563 self->state.result->obj = NULL;
2564 TALLOC_FREE(self->state.result);
2568 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self)
2570 if (self->state.req == NULL) {
2571 PyErr_SetString(PyExc_RuntimeError,
2572 "ldb.SearchIterator request already finished");
2576 Py_XDECREF(self->state.exception);
2577 TALLOC_FREE(self->mem_ctx);
2578 ZERO_STRUCT(self->state);
2582 static PyMethodDef py_ldb_search_iterator_methods[] = {
2583 { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2584 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2585 { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2590 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2592 return PyStr_FromString("<ldb search iterator>");
2595 static PyTypeObject PyLdbSearchIterator = {
2596 .tp_name = "ldb.SearchIterator",
2597 .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2598 .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2599 .tp_iter = PyObject_SelfIter,
2600 .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2601 .tp_methods = py_ldb_search_iterator_methods,
2602 .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2603 .tp_doc = "LDB search_iterator.",
2604 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2607 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2609 return PyStr_FromFormat("<ldb module '%s'>",
2610 pyldb_Module_AsModule(self)->ops->name);
2613 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2615 return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
2618 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2620 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2624 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2626 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2630 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2632 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2636 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2638 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2640 struct ldb_request *req;
2641 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2642 struct ldb_module *mod;
2643 const char * const*attrs;
2645 /* type "int" rather than "enum" for "scope" is intentional */
2646 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2647 discard_const_p(char *, kwnames),
2648 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2653 if (py_attrs == Py_None) {
2656 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2661 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2662 scope, NULL /* expr */, attrs,
2663 NULL /* controls */, NULL, NULL, NULL);
2665 talloc_steal(req, attrs);
2667 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2669 req->op.search.res = NULL;
2671 ret = mod->ops->search(mod, req);
2673 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2675 py_ret = PyLdbResult_FromResult(req->op.search.res);
2683 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2685 struct ldb_request *req;
2686 PyObject *py_message;
2688 struct ldb_module *mod;
2690 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2693 req = talloc_zero(NULL, struct ldb_request);
2694 req->operation = LDB_ADD;
2695 req->op.add.message = pyldb_Message_AsMessage(py_message);
2697 mod = pyldb_Module_AsModule(self);
2698 ret = mod->ops->add(mod, req);
2700 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2705 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2708 struct ldb_request *req;
2709 PyObject *py_message;
2710 struct ldb_module *mod;
2712 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2715 req = talloc_zero(NULL, struct ldb_request);
2716 req->operation = LDB_MODIFY;
2717 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2719 mod = pyldb_Module_AsModule(self);
2720 ret = mod->ops->modify(mod, req);
2722 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2727 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2730 struct ldb_request *req;
2733 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2736 req = talloc_zero(NULL, struct ldb_request);
2737 req->operation = LDB_DELETE;
2738 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2740 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2742 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2747 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2750 struct ldb_request *req;
2751 PyObject *py_dn1, *py_dn2;
2753 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2756 req = talloc_zero(NULL, struct ldb_request);
2758 req->operation = LDB_RENAME;
2759 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2760 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2762 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2764 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2769 static PyMethodDef py_ldb_module_methods[] = {
2770 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2771 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2772 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2773 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2774 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2775 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2776 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2777 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2781 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2783 talloc_free(self->mem_ctx);
2787 static PyTypeObject PyLdbModule = {
2788 .tp_name = "ldb.LdbModule",
2789 .tp_methods = py_ldb_module_methods,
2790 .tp_repr = (reprfunc)py_ldb_module_repr,
2791 .tp_str = (reprfunc)py_ldb_module_str,
2792 .tp_basicsize = sizeof(PyLdbModuleObject),
2793 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2794 .tp_flags = Py_TPFLAGS_DEFAULT,
2795 .tp_doc = "LDB module (extension)",
2800 * Create a ldb_message_element from a Python object.
2802 * This will accept any sequence objects that contains strings, or
2805 * A reference to set_obj will be borrowed.
2807 * @param mem_ctx Memory context
2808 * @param set_obj Python object to convert
2809 * @param flags ldb_message_element flags to set
2810 * @param attr_name Name of the attribute
2811 * @return New ldb_message_element, allocated as child of mem_ctx
2813 static struct ldb_message_element *PyObject_AsMessageElement(
2814 TALLOC_CTX *mem_ctx,
2817 const char *attr_name)
2819 struct ldb_message_element *me;
2820 const char *msg = NULL;
2824 if (pyldb_MessageElement_Check(set_obj)) {
2825 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2826 /* We have to talloc_reference() the memory context, not the pointer
2827 * which may not actually be it's own context */
2828 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2829 return pyldb_MessageElement_AsMessageElement(set_obj);
2834 me = talloc(mem_ctx, struct ldb_message_element);
2840 me->name = talloc_strdup(me, attr_name);
2842 if (PyBytes_Check(set_obj) || PyStr_Check(set_obj)) {
2844 me->values = talloc_array(me, struct ldb_val, me->num_values);
2845 if (PyBytes_Check(set_obj)) {
2847 result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
2854 msg = PyStr_AsUTF8AndSize(set_obj, &size);
2860 me->values[0].data = talloc_memdup(me,
2861 (const uint8_t *)msg,
2863 me->values[0].length = size;
2864 } else if (PySequence_Check(set_obj)) {
2866 me->num_values = PySequence_Size(set_obj);
2867 me->values = talloc_array(me, struct ldb_val, me->num_values);
2868 for (i = 0; i < me->num_values; i++) {
2869 PyObject *obj = PySequence_GetItem(set_obj, i);
2870 if (PyBytes_Check(obj)) {
2872 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
2878 } else if (PyStr_Check(obj)) {
2879 msg = PyStr_AsUTF8AndSize(obj, &size);
2885 PyErr_Format(PyExc_TypeError,
2886 "Expected string as element %zd in list", i);
2890 me->values[i].data = talloc_memdup(me,
2891 (const uint8_t *)msg,
2893 me->values[i].length = size;
2896 PyErr_Format(PyExc_TypeError,
2897 "String or List type expected for '%s' attribute", attr_name);
2906 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2907 struct ldb_message_element *me)
2912 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2913 result = PyList_New(me->num_values);
2915 for (i = 0; i < me->num_values; i++) {
2916 PyList_SetItem(result, i,
2917 PyObject_FromLdbValue(&me->values[i]));
2923 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2926 if (!PyArg_ParseTuple(args, "I", &i))
2928 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2931 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2934 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2936 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2937 return PyInt_FromLong(el->flags);
2940 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2943 struct ldb_message_element *el;
2944 if (!PyArg_ParseTuple(args, "I", &flags))
2947 el = pyldb_MessageElement_AsMessageElement(self);
2952 static PyMethodDef py_ldb_msg_element_methods[] = {
2953 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2954 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2955 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2959 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2961 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2964 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2966 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2967 if (idx < 0 || idx >= el->num_values) {
2968 PyErr_SetString(PyExc_IndexError, "Out of range");
2971 return PyBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2974 static PySequenceMethods py_ldb_msg_element_seq = {
2975 .sq_length = (lenfunc)py_ldb_msg_element_len,
2976 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2979 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
2982 if (!pyldb_MessageElement_Check(other)) {
2983 Py_INCREF(Py_NotImplemented);
2984 return Py_NotImplemented;
2986 ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2987 pyldb_MessageElement_AsMessageElement(other));
2988 return richcmp(ret, op);
2991 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2993 PyObject *el = ldb_msg_element_to_set(NULL,
2994 pyldb_MessageElement_AsMessageElement(self));
2995 PyObject *ret = PyObject_GetIter(el);
3000 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3002 PyLdbMessageElementObject *ret;
3003 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3008 ret->mem_ctx = talloc_new(NULL);
3009 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
3014 return (PyObject *)ret;
3017 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3019 PyObject *py_elements = NULL;
3020 struct ldb_message_element *el;
3021 unsigned int flags = 0;
3023 const char * const kwnames[] = { "elements", "flags", "name", NULL };
3024 PyLdbMessageElementObject *ret;
3025 TALLOC_CTX *mem_ctx;
3026 const char *msg = NULL;
3030 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3031 discard_const_p(char *, kwnames),
3032 &py_elements, &flags, &name))
3035 mem_ctx = talloc_new(NULL);
3036 if (mem_ctx == NULL) {
3041 el = talloc_zero(mem_ctx, struct ldb_message_element);
3044 talloc_free(mem_ctx);
3048 if (py_elements != NULL) {
3050 if (PyBytes_Check(py_elements) || PyStr_Check(py_elements)) {
3053 el->values = talloc_array(el, struct ldb_val, 1);
3054 if (el->values == NULL) {
3055 talloc_free(mem_ctx);
3059 if (PyBytes_Check(py_elements)) {
3060 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3063 msg = PyStr_AsUTF8AndSize(py_elements, &size);
3064 result = (msg == NULL) ? -1 : 0;
3067 talloc_free(mem_ctx);
3070 el->values[0].data = talloc_memdup(el->values,
3071 (const uint8_t *)msg, size + 1);
3072 el->values[0].length = size;
3073 } else if (PySequence_Check(py_elements)) {
3074 el->num_values = PySequence_Size(py_elements);
3075 el->values = talloc_array(el, struct ldb_val, el->num_values);
3076 if (el->values == NULL) {
3077 talloc_free(mem_ctx);
3081 for (i = 0; i < el->num_values; i++) {
3082 PyObject *item = PySequence_GetItem(py_elements, i);
3084 talloc_free(mem_ctx);
3087 if (PyBytes_Check(item)) {
3089 result = PyBytes_AsStringAndSize(item, &_msg, &size);
3091 } else if (PyStr_Check(item)) {
3092 msg = PyStr_AsUTF8AndSize(item, &size);
3093 result = (msg == NULL) ? -1 : 0;
3095 PyErr_Format(PyExc_TypeError,
3096 "Expected string as element %zd in list", i);
3100 talloc_free(mem_ctx);
3103 el->values[i].data = talloc_memdup(el,
3104 (const uint8_t *)msg, size+1);
3105 el->values[i].length = size;
3108 PyErr_SetString(PyExc_TypeError,
3109 "Expected string or list");
3110 talloc_free(mem_ctx);
3116 el->name = talloc_strdup(el, name);
3118 ret = PyObject_New(PyLdbMessageElementObject, type);
3120 talloc_free(mem_ctx);
3124 ret->mem_ctx = mem_ctx;
3126 return (PyObject *)ret;
3129 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3131 char *element_str = NULL;
3133 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3134 PyObject *ret, *repr;
3136 for (i = 0; i < el->num_values; i++) {
3137 PyObject *o = py_ldb_msg_element_find(self, i);
3138 repr = PyObject_Repr(o);
3139 if (element_str == NULL)
3140 element_str = talloc_strdup(NULL, PyStr_AsUTF8(repr));
3142 element_str = talloc_asprintf_append(element_str, ",%s", PyStr_AsUTF8(repr));
3146 if (element_str != NULL) {
3147 ret = PyStr_FromFormat("MessageElement([%s])", element_str);
3148 talloc_free(element_str);
3150 ret = PyStr_FromString("MessageElement([])");
3156 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3158 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3160 if (el->num_values == 1)
3161 return PyStr_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3166 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3168 talloc_free(self->mem_ctx);
3172 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3174 return wrap_text("MessageElementTextWrapper", self);
3177 static PyGetSetDef py_ldb_msg_element_getset[] = {
3178 { discard_const_p(char, "text"), (getter)py_ldb_msg_element_get_text, NULL, NULL },
3182 static PyTypeObject PyLdbMessageElement = {
3183 .tp_name = "ldb.MessageElement",
3184 .tp_basicsize = sizeof(PyLdbMessageElementObject),
3185 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3186 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3187 .tp_str = (reprfunc)py_ldb_msg_element_str,
3188 .tp_methods = py_ldb_msg_element_methods,
3189 .tp_getset = py_ldb_msg_element_getset,
3190 .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3191 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3192 .tp_as_sequence = &py_ldb_msg_element_seq,
3193 .tp_new = py_ldb_msg_element_new,
3194 .tp_flags = Py_TPFLAGS_DEFAULT,
3195 .tp_doc = "An element of a Message",
3199 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3204 struct ldb_message *msg;
3205 struct ldb_context *ldb_ctx;
3206 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3208 if (!PyArg_ParseTuple(args, "O!O!|I",
3209 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3214 if (!PyLdb_Check(py_ldb)) {
3215 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
3219 /* mask only flags we are going to use */
3220 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3222 PyErr_SetString(PyExc_ValueError,
3223 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3224 " expected as mod_flag value");
3228 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
3230 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3235 py_ret = PyLdbMessage_FromMessage(msg);
3237 talloc_unlink(ldb_ctx, msg);
3242 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3245 if (!PyArg_ParseTuple(args, "s", &name))
3248 ldb_msg_remove_attr(self->msg, name);
3253 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
3255 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3256 Py_ssize_t i, j = 0;
3257 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3258 if (msg->dn != NULL) {
3259 PyList_SetItem(obj, j, PyStr_FromString("dn"));
3262 for (i = 0; i < msg->num_elements; i++) {
3263 PyList_SetItem(obj, j, PyStr_FromString(msg->elements[i].name));
3269 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
3271 struct ldb_message_element *el;
3273 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3274 name = PyStr_AsUTF8(py_name);
3276 PyErr_SetNone(PyExc_TypeError);
3279 if (!ldb_attr_cmp(name, "dn"))
3280 return pyldb_Dn_FromDn(msg->dn);
3281 el = ldb_msg_find_element(msg, name);
3285 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3288 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3290 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
3292 PyErr_SetString(PyExc_KeyError, "No such element");
3298 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3300 PyObject *def = NULL;
3301 const char *kwnames[] = { "name", "default", "idx", NULL };
3302 const char *name = NULL;
3304 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3305 struct ldb_message_element *el;
3307 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3308 discard_const_p(char *, kwnames), &name, &def, &idx)) {
3312 if (strcasecmp(name, "dn") == 0) {
3313 return pyldb_Dn_FromDn(msg->dn);
3316 el = ldb_msg_find_element(msg, name);
3318 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3327 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3330 return PyObject_FromLdbValue(&el->values[idx]);
3333 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
3335 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3336 Py_ssize_t i, j = 0;
3337 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3338 if (msg->dn != NULL) {
3339 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
3342 for (i = 0; i < msg->num_elements; i++, j++) {
3343 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3344 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3345 PyList_SetItem(l, j, value);
3350 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
3352 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3354 PyObject *l = PyList_New(msg->num_elements);
3355 for (i = 0; i < msg->num_elements; i++) {
3356 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
3361 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3363 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3364 PyLdbMessageElementObject *py_element;
3366 struct ldb_message_element *el;
3367 struct ldb_message_element *el_new;
3369 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
3372 el = py_element->el;
3374 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3378 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3379 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3381 /* now deep copy all attribute values */
3382 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3383 if (el_new->values == NULL) {
3387 el_new->num_values = el->num_values;
3389 for (i = 0; i < el->num_values; i++) {
3390 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
3391 if (el_new->values[i].data == NULL
3392 && el->values[i].length != 0) {
3401 static PyMethodDef py_ldb_msg_methods[] = {
3402 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
3403 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3404 "Class method to create ldb.Message object from Dictionary.\n"
3405 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3406 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
3407 "S.keys() -> list\n\n"
3408 "Return sequence of all attribute names." },
3409 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
3410 "S.remove(name)\n\n"
3411 "Remove all entries for attributes with the specified name."},
3412 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
3413 "msg.get(name,default=None,idx=None) -> string\n"
3414 "idx is the index into the values array\n"
3415 "if idx is None, then a list is returned\n"
3416 "if idx is not None, then the element with that index is returned\n"
3417 "if you pass the special name 'dn' then the DN object is returned\n"},
3418 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
3419 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
3420 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
3421 "S.add(element)\n\n"
3422 "Add an element to this message." },
3426 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
3428 PyObject *list, *iter;
3430 list = py_ldb_msg_keys(self);
3431 iter = PyObject_GetIter(list);
3436 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
3440 attr_name = PyStr_AsUTF8(name);
3441 if (attr_name == NULL) {
3442 PyErr_SetNone(PyExc_TypeError);
3446 if (value == NULL) {
3448 ldb_msg_remove_attr(self->msg, attr_name);
3451 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
3452 value, 0, attr_name);
3456 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
3457 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
3458 if (ret != LDB_SUCCESS) {
3459 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
3466 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
3468 return pyldb_Message_AsMessage(self)->num_elements;
3471 static PyMappingMethods py_ldb_msg_mapping = {
3472 .mp_length = (lenfunc)py_ldb_msg_length,
3473 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
3474 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
3477 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3479 const char * const kwnames[] = { "dn", NULL };
3480 struct ldb_message *ret;
3481 TALLOC_CTX *mem_ctx;
3482 PyObject *pydn = NULL;
3483 PyLdbMessageObject *py_ret;
3485 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
3486 discard_const_p(char *, kwnames),
3490 mem_ctx = talloc_new(NULL);
3491 if (mem_ctx == NULL) {
3496 ret = ldb_msg_new(mem_ctx);
3498 talloc_free(mem_ctx);
3505 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
3506 talloc_free(mem_ctx);
3509 ret->dn = talloc_reference(ret, dn);
3512 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
3513 if (py_ret == NULL) {
3515 talloc_free(mem_ctx);
3519 py_ret->mem_ctx = mem_ctx;
3521 return (PyObject *)py_ret;
3524 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
3526 PyLdbMessageObject *ret;
3528 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3533 ret->mem_ctx = talloc_new(NULL);
3534 ret->msg = talloc_reference(ret->mem_ctx, msg);
3535 return (PyObject *)ret;
3538 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3540 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3541 return pyldb_Dn_FromDn(msg->dn);
3544 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3546 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3547 if (!pyldb_Dn_Check(value)) {
3548 PyErr_SetString(PyExc_TypeError, "expected dn");
3552 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3556 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
3558 return wrap_text("MessageTextWrapper", self);
3561 static PyGetSetDef py_ldb_msg_getset[] = {
3562 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
3563 { discard_const_p(char, "text"), (getter)py_ldb_msg_get_text, NULL, NULL },
3567 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3569 PyObject *dict = PyDict_New(), *ret, *repr;
3570 if (PyDict_Update(dict, (PyObject *)self) != 0)
3572 repr = PyObject_Repr(dict);
3577 ret = PyStr_FromFormat("Message(%s)", PyStr_AsUTF8(repr));
3583 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3585 talloc_free(self->mem_ctx);
3589 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3590 PyLdbMessageObject *py_msg2, int op)
3592 struct ldb_message *msg1, *msg2;
3596 if (!PyLdbMessage_Check(py_msg2)) {
3597 Py_INCREF(Py_NotImplemented);
3598 return Py_NotImplemented;
3601 msg1 = pyldb_Message_AsMessage(py_msg1),
3602 msg2 = pyldb_Message_AsMessage(py_msg2);
3604 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3605 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3607 return richcmp(ret, op);
3611 ret = msg1->num_elements - msg2->num_elements;
3613 return richcmp(ret, op);
3616 for (i = 0; i < msg1->num_elements; i++) {
3617 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3618 &msg2->elements[i]);
3620 return richcmp(ret, op);
3623 ret = ldb_msg_element_compare(&msg1->elements[i],
3624 &msg2->elements[i]);
3626 return richcmp(ret, op);
3630 return richcmp(0, op);
3633 static PyTypeObject PyLdbMessage = {
3634 .tp_name = "ldb.Message",
3635 .tp_methods = py_ldb_msg_methods,
3636 .tp_getset = py_ldb_msg_getset,
3637 .tp_as_mapping = &py_ldb_msg_mapping,
3638 .tp_basicsize = sizeof(PyLdbMessageObject),
3639 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3640 .tp_new = py_ldb_msg_new,
3641 .tp_repr = (reprfunc)py_ldb_msg_repr,
3642 .tp_flags = Py_TPFLAGS_DEFAULT,
3643 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3644 .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3645 .tp_doc = "A LDB Message",
3648 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3650 PyLdbTreeObject *ret;
3652 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3658 ret->mem_ctx = talloc_new(NULL);
3659 ret->tree = talloc_reference(ret->mem_ctx, tree);
3660 return (PyObject *)ret;
3663 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3665 talloc_free(self->mem_ctx);
3669 static PyTypeObject PyLdbTree = {
3670 .tp_name = "ldb.Tree",
3671 .tp_basicsize = sizeof(PyLdbTreeObject),
3672 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3673 .tp_flags = Py_TPFLAGS_DEFAULT,
3674 .tp_doc = "A search tree",
3678 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3680 PyObject *py_ldb = (PyObject *)mod->private_data;
3681 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3683 py_base = pyldb_Dn_FromDn(req->op.search.base);
3685 if (py_base == NULL)
3686 return LDB_ERR_OPERATIONS_ERROR;
3688 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3690 if (py_tree == NULL)
3691 return LDB_ERR_OPERATIONS_ERROR;
3693 if (req->op.search.attrs == NULL) {
3697 for (len = 0; req->op.search.attrs[len]; len++);
3698 py_attrs = PyList_New(len);
3699 for (i = 0; i < len; i++)
3700 PyList_SetItem(py_attrs, i, PyStr_FromString(req->op.search.attrs[i]));
3703 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3704 discard_const_p(char, "OiOO"),
3705 py_base, req->op.search.scope, py_tree, py_attrs);
3707 Py_DECREF(py_attrs);
3711 if (py_result == NULL) {
3712 return LDB_ERR_PYTHON_EXCEPTION;
3715 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3716 if (req->op.search.res == NULL) {
3717 return LDB_ERR_PYTHON_EXCEPTION;
3720 Py_DECREF(py_result);
3725 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3727 PyObject *py_ldb = (PyObject *)mod->private_data;
3728 PyObject *py_result, *py_msg;
3730 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3732 if (py_msg == NULL) {
3733 return LDB_ERR_OPERATIONS_ERROR;
3736 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3737 discard_const_p(char, "O"),
3742 if (py_result == NULL) {
3743 return LDB_ERR_PYTHON_EXCEPTION;
3746 Py_DECREF(py_result);
3751 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3753 PyObject *py_ldb = (PyObject *)mod->private_data;
3754 PyObject *py_result, *py_msg;
3756 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3758 if (py_msg == NULL) {
3759 return LDB_ERR_OPERATIONS_ERROR;
3762 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3763 discard_const_p(char, "O"),
3768 if (py_result == NULL) {
3769 return LDB_ERR_PYTHON_EXCEPTION;
3772 Py_DECREF(py_result);
3777 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3779 PyObject *py_ldb = (PyObject *)mod->private_data;
3780 PyObject *py_result, *py_dn;
3782 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3785 return LDB_ERR_OPERATIONS_ERROR;
3787 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3788 discard_const_p(char, "O"),
3791 if (py_result == NULL) {
3792 return LDB_ERR_PYTHON_EXCEPTION;
3795 Py_DECREF(py_result);
3800 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3802 PyObject *py_ldb = (PyObject *)mod->private_data;
3803 PyObject *py_result, *py_olddn, *py_newdn;
3805 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3807 if (py_olddn == NULL)
3808 return LDB_ERR_OPERATIONS_ERROR;
3810 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3812 if (py_newdn == NULL)
3813 return LDB_ERR_OPERATIONS_ERROR;
3815 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3816 discard_const_p(char, "OO"),
3817 py_olddn, py_newdn);
3819 Py_DECREF(py_olddn);
3820 Py_DECREF(py_newdn);
3822 if (py_result == NULL) {
3823 return LDB_ERR_PYTHON_EXCEPTION;
3826 Py_DECREF(py_result);
3831 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3833 PyObject *py_ldb = (PyObject *)mod->private_data;
3834 PyObject *py_result;
3836 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3837 discard_const_p(char, ""));
3839 Py_XDECREF(py_result);
3841 return LDB_ERR_OPERATIONS_ERROR;
3844 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3846 PyObject *py_ldb = (PyObject *)mod->private_data;
3847 PyObject *py_result;
3849 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3850 discard_const_p(char, ""));
3852 Py_XDECREF(py_result);
3854 return LDB_ERR_OPERATIONS_ERROR;
3857 static int py_module_start_transaction(struct ldb_module *mod)
3859 PyObject *py_ldb = (PyObject *)mod->private_data;
3860 PyObject *py_result;
3862 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3863 discard_const_p(char, ""));
3865 if (py_result == NULL) {
3866 return LDB_ERR_PYTHON_EXCEPTION;
3869 Py_DECREF(py_result);
3874 static int py_module_end_transaction(struct ldb_module *mod)
3876 PyObject *py_ldb = (PyObject *)mod->private_data;
3877 PyObject *py_result;
3879 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3880 discard_const_p(char, ""));
3882 if (py_result == NULL) {
3883 return LDB_ERR_PYTHON_EXCEPTION;
3886 Py_DECREF(py_result);
3891 static int py_module_del_transaction(struct ldb_module *mod)
3893 PyObject *py_ldb = (PyObject *)mod->private_data;
3894 PyObject *py_result;
3896 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3897 discard_const_p(char, ""));
3899 if (py_result == NULL) {
3900 return LDB_ERR_PYTHON_EXCEPTION;
3903 Py_DECREF(py_result);
3908 static int py_module_destructor(struct ldb_module *mod)
3910 Py_DECREF((PyObject *)mod->private_data);
3914 static int py_module_init(struct ldb_module *mod)
3916 PyObject *py_class = (PyObject *)mod->ops->private_data;
3917 PyObject *py_result, *py_next, *py_ldb;
3919 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3922 return LDB_ERR_OPERATIONS_ERROR;
3924 py_next = PyLdbModule_FromModule(mod->next);
3926 if (py_next == NULL)
3927 return LDB_ERR_OPERATIONS_ERROR;
3929 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3932 if (py_result == NULL) {
3933 return LDB_ERR_PYTHON_EXCEPTION;
3936 mod->private_data = py_result;
3938 talloc_set_destructor(mod, py_module_destructor);
3940 return ldb_next_init(mod);
3943 static PyObject *py_register_module(PyObject *module, PyObject *args)
3946 struct ldb_module_ops *ops;
3949 if (!PyArg_ParseTuple(args, "O", &input))
3952 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3958 ops->name = talloc_strdup(ops, PyStr_AsUTF8(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3961 ops->private_data = input;
3962 ops->init_context = py_module_init;
3963 ops->search = py_module_search;
3964 ops->add = py_module_add;
3965 ops->modify = py_module_modify;
3966 ops->del = py_module_del;
3967 ops->rename = py_module_rename;
3968 ops->request = py_module_request;
3969 ops->extended = py_module_extended;
3970 ops->start_transaction = py_module_start_transaction;
3971 ops->end_transaction = py_module_end_transaction;
3972 ops->del_transaction = py_module_del_transaction;
3974 ret = ldb_register_module(ops);
3976 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3981 static PyObject *py_timestring(PyObject *module, PyObject *args)
3983 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3984 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3988 if (!PyArg_ParseTuple(args, "l", &t_val))
3990 tresult = ldb_timestring(NULL, (time_t) t_val);
3991 ret = PyStr_FromString(tresult);
3992 talloc_free(tresult);
3996 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3999 if (!PyArg_ParseTuple(args, "s", &str))
4002 return PyInt_FromLong(ldb_string_to_time(str));
4005 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4008 if (!PyArg_ParseTuple(args, "s", &name))
4010 return PyBool_FromLong(ldb_valid_attr_name(name));
4014 encode a string using RFC2254 rules
4016 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4018 char *str, *encoded;
4019 Py_ssize_t size = 0;
4023 if (!PyArg_ParseTuple(args, "s#", &str, &size))
4025 val.data = (uint8_t *)str;
4028 encoded = ldb_binary_encode(NULL, val);
4029 if (encoded == NULL) {
4030 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4033 ret = PyStr_FromString(encoded);
4034 talloc_free(encoded);
4039 decode a string using RFC2254 rules
4041 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4047 if (!PyArg_ParseTuple(args, "s", &str))
4050 val = ldb_binary_decode(NULL, str);
4051 if (val.data == NULL) {
4052 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4055 ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4056 talloc_free(val.data);
4060 static PyMethodDef py_ldb_global_methods[] = {
4061 { "register_module", py_register_module, METH_VARARGS,
4062 "S.register_module(module) -> None\n\n"
4063 "Register a LDB module."},
4064 { "timestring", py_timestring, METH_VARARGS,
4065 "S.timestring(int) -> string\n\n"
4066 "Generate a LDAP time string from a UNIX timestamp" },
4067 { "string_to_time", py_string_to_time, METH_VARARGS,
4068 "S.string_to_time(string) -> int\n\n"
4069 "Parse a LDAP time string into a UNIX timestamp." },
4070 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4071 "S.valid_attr_name(name) -> bool\n\nn"
4072 "Check whether the supplied name is a valid attribute name." },
4073 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
4074 "S.open() -> Ldb\n\n"
4075 "Open a new LDB context." },
4076 { "binary_encode", py_binary_encode, METH_VARARGS,
4077 "S.binary_encode(string) -> string\n\n"
4078 "Perform a RFC2254 binary encoding on a string" },
4079 { "binary_decode", py_binary_decode, METH_VARARGS,
4080 "S.binary_decode(string) -> string\n\n"
4081 "Perform a RFC2254 binary decode on a string" },
4085 #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."
4087 #if PY_MAJOR_VERSION >= 3
4088 static struct PyModuleDef moduledef = {
4089 PyModuleDef_HEAD_INIT,
4091 .m_doc = MODULE_DOC,
4093 .m_methods = py_ldb_global_methods,
4097 static PyObject* module_init(void)
4101 if (PyType_Ready(&PyLdbDn) < 0)
4104 if (PyType_Ready(&PyLdbMessage) < 0)
4107 if (PyType_Ready(&PyLdbMessageElement) < 0)
4110 if (PyType_Ready(&PyLdb) < 0)
4113 if (PyType_Ready(&PyLdbModule) < 0)
4116 if (PyType_Ready(&PyLdbTree) < 0)
4119 if (PyType_Ready(&PyLdbResult) < 0)
4122 if (PyType_Ready(&PyLdbSearchIterator) < 0)
4125 if (PyType_Ready(&PyLdbControl) < 0)
4128 #if PY_MAJOR_VERSION >= 3
4129 m = PyModule_Create(&moduledef);
4131 m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC);
4136 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4138 ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4139 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4140 ADD_LDB_INT(SEQ_NEXT);
4141 ADD_LDB_INT(SCOPE_DEFAULT);
4142 ADD_LDB_INT(SCOPE_BASE);
4143 ADD_LDB_INT(SCOPE_ONELEVEL);
4144 ADD_LDB_INT(SCOPE_SUBTREE);
4146 ADD_LDB_INT(CHANGETYPE_NONE);
4147 ADD_LDB_INT(CHANGETYPE_ADD);
4148 ADD_LDB_INT(CHANGETYPE_DELETE);
4149 ADD_LDB_INT(CHANGETYPE_MODIFY);
4151 ADD_LDB_INT(FLAG_MOD_ADD);
4152 ADD_LDB_INT(FLAG_MOD_REPLACE);
4153 ADD_LDB_INT(FLAG_MOD_DELETE);
4155 ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4156 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4157 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4158 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4160 ADD_LDB_INT(SUCCESS);
4161 ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4162 ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4163 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4164 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4165 ADD_LDB_INT(ERR_COMPARE_FALSE);
4166 ADD_LDB_INT(ERR_COMPARE_TRUE);
4167 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4168 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4169 ADD_LDB_INT(ERR_REFERRAL);
4170 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4171 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4172 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4173 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4174 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4175 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4176 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4177 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4178 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4179 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4180 ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4181 ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4182 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4183 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4184 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4185 ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4186 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4187 ADD_LDB_INT(ERR_BUSY);
4188 ADD_LDB_INT(ERR_UNAVAILABLE);
4189 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4190 ADD_LDB_INT(ERR_LOOP_DETECT);
4191 ADD_LDB_INT(ERR_NAMING_VIOLATION);
4192 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4193 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4194 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4195 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4196 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4197 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4198 ADD_LDB_INT(ERR_OTHER);
4200 ADD_LDB_INT(FLG_RDONLY);
4201 ADD_LDB_INT(FLG_NOSYNC);
4202 ADD_LDB_INT(FLG_RECONNECT);
4203 ADD_LDB_INT(FLG_NOMMAP);
4205 /* Historical misspelling */
4206 PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
4208 PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
4210 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
4211 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
4214 Py_INCREF(&PyLdbDn);
4215 Py_INCREF(&PyLdbModule);
4216 Py_INCREF(&PyLdbMessage);
4217 Py_INCREF(&PyLdbMessageElement);
4218 Py_INCREF(&PyLdbTree);
4219 Py_INCREF(&PyLdbResult);
4220 Py_INCREF(&PyLdbControl);
4222 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
4223 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
4224 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
4225 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
4226 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
4227 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
4228 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
4230 PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
4232 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4234 ADD_LDB_STRING(SYNTAX_DN);
4235 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
4236 ADD_LDB_STRING(SYNTAX_INTEGER);
4237 ADD_LDB_STRING(SYNTAX_BOOLEAN);
4238 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
4239 ADD_LDB_STRING(SYNTAX_UTC_TIME);
4240 ADD_LDB_STRING(OID_COMPARATOR_AND);
4241 ADD_LDB_STRING(OID_COMPARATOR_OR);
4246 #if PY_MAJOR_VERSION >= 3
4247 PyMODINIT_FUNC PyInit_ldb(void);
4248 PyMODINIT_FUNC PyInit_ldb(void)
4250 return module_init();