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)
513 uint8_t *value = NULL;
516 if (!PyArg_ParseTuple(args, "sz#", &name, (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;
1672 struct ldb_dn *last_dn = NULL;
1674 TALLOC_CTX *mem_ctx;
1676 if (!PyArg_ParseTuple(args, "s", &s))
1679 mem_ctx = talloc_new(NULL);
1684 list = PyList_New(0);
1685 while (s && *s != '\0') {
1686 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1687 talloc_steal(mem_ctx, ldif);
1689 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1690 last_dn = ldif->msg->dn;
1692 const char *last_dn_str = NULL;
1693 const char *err_string = NULL;
1694 if (last_dn == NULL) {
1695 PyErr_SetString(PyExc_ValueError,
1696 "unable to parse LDIF "
1697 "string at first chunk");
1698 talloc_free(mem_ctx);
1703 = ldb_dn_get_linearized(last_dn);
1706 = talloc_asprintf(mem_ctx,
1707 "unable to parse ldif "
1711 PyErr_SetString(PyExc_ValueError,
1713 talloc_free(mem_ctx);
1717 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1718 ret = PyObject_GetIter(list);
1723 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1726 PyObject *py_msg_old;
1727 PyObject *py_msg_new;
1728 struct ldb_message *diff;
1729 struct ldb_context *ldb;
1732 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1735 if (!PyLdbMessage_Check(py_msg_old)) {
1736 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1740 if (!PyLdbMessage_Check(py_msg_new)) {
1741 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1745 ldb = pyldb_Ldb_AsLdbContext(self);
1746 ldb_ret = ldb_msg_difference(ldb, ldb,
1747 pyldb_Message_AsMessage(py_msg_old),
1748 pyldb_Message_AsMessage(py_msg_new),
1750 if (ldb_ret != LDB_SUCCESS) {
1751 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1755 py_ret = PyLdbMessage_FromMessage(diff);
1757 talloc_unlink(ldb, diff);
1762 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1764 const struct ldb_schema_attribute *a;
1765 struct ldb_val old_val;
1766 struct ldb_val new_val;
1767 TALLOC_CTX *mem_ctx;
1774 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1777 result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1778 old_val.length = size;
1781 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1785 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1791 mem_ctx = talloc_new(NULL);
1792 if (mem_ctx == NULL) {
1797 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1798 talloc_free(mem_ctx);
1802 ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1804 talloc_free(mem_ctx);
1809 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1811 PyObject *py_base = Py_None;
1812 int scope = LDB_SCOPE_DEFAULT;
1814 PyObject *py_attrs = Py_None;
1815 PyObject *py_controls = Py_None;
1816 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1818 struct ldb_result *res;
1819 struct ldb_request *req;
1821 struct ldb_context *ldb_ctx;
1822 struct ldb_control **parsed_controls;
1823 struct ldb_dn *base;
1825 TALLOC_CTX *mem_ctx;
1827 /* type "int" rather than "enum" for "scope" is intentional */
1828 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1829 discard_const_p(char *, kwnames),
1830 &py_base, &scope, &expr, &py_attrs, &py_controls))
1834 mem_ctx = talloc_new(NULL);
1835 if (mem_ctx == NULL) {
1839 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1841 if (py_attrs == Py_None) {
1844 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1845 if (attrs == NULL) {
1846 talloc_free(mem_ctx);
1851 if (py_base == Py_None) {
1852 base = ldb_get_default_basedn(ldb_ctx);
1854 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1855 talloc_free(mem_ctx);
1860 if (py_controls == Py_None) {
1861 parsed_controls = NULL;
1863 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1864 if (controls == NULL) {
1865 talloc_free(mem_ctx);
1868 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1869 talloc_free(controls);
1872 res = talloc_zero(mem_ctx, struct ldb_result);
1875 talloc_free(mem_ctx);
1879 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1886 ldb_search_default_callback,
1889 if (ret != LDB_SUCCESS) {
1890 talloc_free(mem_ctx);
1891 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1895 talloc_steal(req, attrs);
1897 ret = ldb_request(ldb_ctx, req);
1899 if (ret == LDB_SUCCESS) {
1900 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1903 if (ret != LDB_SUCCESS) {
1904 talloc_free(mem_ctx);
1905 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1909 py_ret = PyLdbResult_FromResult(res);
1911 talloc_free(mem_ctx);
1916 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
1918 if (reply->py_iter != NULL) {
1919 DLIST_REMOVE(reply->py_iter->state.next, reply);
1920 if (reply->py_iter->state.result == reply) {
1921 reply->py_iter->state.result = NULL;
1923 reply->py_iter = NULL;
1926 if (reply->obj != NULL) {
1927 Py_DECREF(reply->obj);
1934 static int py_ldb_search_iterator_callback(struct ldb_request *req,
1935 struct ldb_reply *ares)
1937 PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
1938 struct ldb_result result = { .msgs = NULL };
1939 struct py_ldb_search_iterator_reply *reply = NULL;
1942 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1945 if (ares->error != LDB_SUCCESS) {
1946 int ret = ares->error;
1948 return ldb_request_done(req, ret);
1951 reply = talloc_zero(py_iter->mem_ctx,
1952 struct py_ldb_search_iterator_reply);
1953 if (reply == NULL) {
1955 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1957 reply->py_iter = py_iter;
1958 talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
1960 switch (ares->type) {
1961 case LDB_REPLY_ENTRY:
1962 reply->obj = PyLdbMessage_FromMessage(ares->message);
1963 if (reply->obj == NULL) {
1965 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1967 DLIST_ADD_END(py_iter->state.next, reply);
1971 case LDB_REPLY_REFERRAL:
1972 reply->obj = PyStr_FromString(ares->referral);
1973 if (reply->obj == NULL) {
1975 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1977 DLIST_ADD_END(py_iter->state.next, reply);
1981 case LDB_REPLY_DONE:
1982 result = (struct ldb_result) { .controls = ares->controls };
1983 reply->obj = PyLdbResult_FromResult(&result);
1984 if (reply->obj == NULL) {
1986 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1988 py_iter->state.result = reply;
1990 return ldb_request_done(req, LDB_SUCCESS);
1994 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1997 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1999 PyObject *py_base = Py_None;
2000 int scope = LDB_SCOPE_DEFAULT;
2003 PyObject *py_attrs = Py_None;
2004 PyObject *py_controls = Py_None;
2005 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
2008 struct ldb_context *ldb_ctx;
2009 struct ldb_control **parsed_controls;
2010 struct ldb_dn *base;
2011 PyLdbSearchIteratorObject *py_iter;
2013 /* type "int" rather than "enum" for "scope" is intentional */
2014 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
2015 discard_const_p(char *, kwnames),
2016 &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
2019 py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
2020 if (py_iter == NULL) {
2024 py_iter->ldb = self;
2026 ZERO_STRUCT(py_iter->state);
2027 py_iter->mem_ctx = talloc_new(NULL);
2028 if (py_iter->mem_ctx == NULL) {
2034 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2036 if (py_attrs == Py_None) {
2039 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2040 if (attrs == NULL) {
2047 if (py_base == Py_None) {
2048 base = ldb_get_default_basedn(ldb_ctx);
2050 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2057 if (py_controls == Py_None) {
2058 parsed_controls = NULL;
2060 const char **controls = NULL;
2062 controls = PyList_AsStrList(py_iter->mem_ctx,
2063 py_controls, "controls");
2064 if (controls == NULL) {
2070 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2073 if (controls[0] != NULL && parsed_controls == NULL) {
2078 talloc_free(controls);
2081 ret = ldb_build_search_req(&py_iter->state.req,
2090 py_ldb_search_iterator_callback,
2092 if (ret != LDB_SUCCESS) {
2094 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2098 ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2100 ret = ldb_request(ldb_ctx, py_iter->state.req);
2101 if (ret != LDB_SUCCESS) {
2103 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2107 return (PyObject *)py_iter;
2110 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2115 if (!PyArg_ParseTuple(args, "s", &name))
2118 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
2123 /* FIXME: More interpretation */
2128 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2133 if (!PyArg_ParseTuple(args, "sO", &name, &data))
2136 /* FIXME: More interpretation */
2138 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
2143 static PyObject *py_ldb_modules(PyLdbObject *self)
2145 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2146 PyObject *ret = PyList_New(0);
2147 struct ldb_module *mod;
2149 for (mod = ldb->modules; mod; mod = mod->next) {
2150 PyList_Append(ret, PyLdbModule_FromModule(mod));
2156 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2158 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2162 if (!PyArg_ParseTuple(args, "i", &type))
2165 /* FIXME: More interpretation */
2167 ret = ldb_sequence_number(ldb, type, &value);
2169 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2171 return PyLong_FromLongLong(value);
2175 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2177 .read_fn = ldb_handler_copy,
2178 .write_clear_fn = ldb_handler_copy,
2179 .write_hex_fn = ldb_handler_copy,
2182 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self)
2184 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2187 ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2189 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2195 static PyMethodDef py_ldb_methods[] = {
2196 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
2197 "S.set_debug(callback) -> None\n"
2198 "Set callback for LDB debug messages.\n"
2199 "The callback should accept a debug level and debug text." },
2200 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
2201 "S.set_create_perms(mode) -> None\n"
2202 "Set mode to use when creating new LDB files." },
2203 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2204 "S.set_modules_dir(path) -> None\n"
2205 "Set path LDB should search for modules" },
2206 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
2207 "S.transaction_start() -> None\n"
2208 "Start a new transaction." },
2209 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2210 "S.transaction_prepare_commit() -> None\n"
2211 "prepare to commit a new transaction (2-stage commit)." },
2212 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
2213 "S.transaction_commit() -> None\n"
2214 "commit a new transaction." },
2215 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
2216 "S.transaction_cancel() -> None\n"
2217 "cancel a new transaction." },
2218 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
2220 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2222 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2224 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2226 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2228 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
2229 "S.connect(url, flags=0, options=None) -> None\n"
2230 "Connect to a LDB URL." },
2231 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
2232 "S.modify(message, controls=None, validate=False) -> None\n"
2233 "Modify an entry." },
2234 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
2235 "S.add(message, controls=None) -> None\n"
2237 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
2238 "S.delete(dn, controls=None) -> None\n"
2239 "Remove an entry." },
2240 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
2241 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2242 "Rename an entry." },
2243 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
2244 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2245 "Search in a database.\n"
2247 ":param base: Optional base DN to search\n"
2248 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2249 ":param expression: Optional search expression\n"
2250 ":param attrs: Attributes to return (defaults to all)\n"
2251 ":param controls: Optional list of controls\n"
2252 ":return: ldb.Result object\n"
2254 { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS,
2255 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2256 "Search in a database.\n"
2258 ":param base: Optional base DN to search\n"
2259 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2260 ":param expression: Optional search expression\n"
2261 ":param attrs: Attributes to return (defaults to all)\n"
2262 ":param controls: Optional list of controls\n"
2263 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2264 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2266 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2268 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2270 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2272 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2273 "S.parse_ldif(ldif) -> iter(messages)\n"
2274 "Parse a string formatted using LDIF." },
2275 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2276 "S.write_ldif(message, changetype) -> ldif\n"
2277 "Print the message as a string formatted using LDIF." },
2278 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2279 "S.msg_diff(Message) -> Message\n"
2280 "Return an LDB Message of the difference between two Message objects." },
2281 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2282 "S.get_opaque(name) -> value\n"
2283 "Get an opaque value set on this LDB connection. \n"
2284 ":note: The returned value may not be useful in Python."
2286 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2287 "S.set_opaque(name, value) -> None\n"
2288 "Set an opaque value on this LDB connection. \n"
2289 ":note: Passing incorrect values may cause crashes." },
2290 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2291 "S.modules() -> list\n"
2292 "Return the list of modules on this LDB connection " },
2293 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2294 "S.sequence_number(type) -> value\n"
2295 "Return the value of the sequence according to the requested type" },
2296 { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2297 "S._register_test_extensions() -> None\n"
2298 "Register internal extensions used in testing" },
2302 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2304 PyLdbModuleObject *ret;
2306 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2311 ret->mem_ctx = talloc_new(NULL);
2312 ret->mod = talloc_reference(ret->mem_ctx, mod);
2313 return (PyObject *)ret;
2316 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2318 struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2322 return PyLdbModule_FromModule(mod);
2325 static PyGetSetDef py_ldb_getset[] = {
2326 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
2330 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2332 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2334 struct ldb_result *result;
2338 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2342 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2344 if (ret != LDB_SUCCESS) {
2345 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2349 count = result->count;
2351 talloc_free(result);
2354 PyErr_Format(PyExc_RuntimeError,
2355 "Searching for [%s] dn gave %u results!",
2356 ldb_dn_get_linearized(dn),
2364 static PySequenceMethods py_ldb_seq = {
2365 .sq_contains = (objobjproc)py_ldb_contains,
2368 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2372 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2377 ret->mem_ctx = talloc_new(NULL);
2378 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2379 return (PyObject *)ret;
2382 static void py_ldb_dealloc(PyLdbObject *self)
2384 talloc_free(self->mem_ctx);
2385 Py_TYPE(self)->tp_free(self);
2388 static PyTypeObject PyLdb = {
2389 .tp_name = "ldb.Ldb",
2390 .tp_methods = py_ldb_methods,
2391 .tp_repr = (reprfunc)py_ldb_repr,
2392 .tp_new = py_ldb_new,
2393 .tp_init = (initproc)py_ldb_init,
2394 .tp_dealloc = (destructor)py_ldb_dealloc,
2395 .tp_getset = py_ldb_getset,
2396 .tp_getattro = PyObject_GenericGetAttr,
2397 .tp_basicsize = sizeof(PyLdbObject),
2398 .tp_doc = "Connection to a LDB database.",
2399 .tp_as_sequence = &py_ldb_seq,
2400 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2403 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2405 talloc_free(self->mem_ctx);
2406 Py_DECREF(self->msgs);
2407 Py_DECREF(self->referals);
2408 Py_DECREF(self->controls);
2409 Py_TYPE(self)->tp_free(self);
2412 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2414 Py_INCREF(self->msgs);
2418 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2420 Py_INCREF(self->controls);
2421 return self->controls;
2424 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2426 Py_INCREF(self->referals);
2427 return self->referals;
2430 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2433 if (self->msgs == NULL) {
2434 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2437 size = PyList_Size(self->msgs);
2438 return PyInt_FromLong(size);
2441 static PyGetSetDef py_ldb_result_getset[] = {
2442 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2443 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2444 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2445 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2449 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2451 return PyObject_GetIter(self->msgs);
2454 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2456 return PySequence_Size(self->msgs);
2459 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2461 return PySequence_GetItem(self->msgs, idx);
2464 static PySequenceMethods py_ldb_result_seq = {
2465 .sq_length = (lenfunc)py_ldb_result_len,
2466 .sq_item = (ssizeargfunc)py_ldb_result_find,
2469 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2471 return PyStr_FromString("<ldb result>");
2475 static PyTypeObject PyLdbResult = {
2476 .tp_name = "ldb.Result",
2477 .tp_repr = (reprfunc)py_ldb_result_repr,
2478 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2479 .tp_iter = (getiterfunc)py_ldb_result_iter,
2480 .tp_getset = py_ldb_result_getset,
2481 .tp_getattro = PyObject_GenericGetAttr,
2482 .tp_basicsize = sizeof(PyLdbResultObject),
2483 .tp_as_sequence = &py_ldb_result_seq,
2484 .tp_doc = "LDB result.",
2485 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2488 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2490 Py_XDECREF(self->state.exception);
2491 TALLOC_FREE(self->mem_ctx);
2492 ZERO_STRUCT(self->state);
2493 Py_DECREF(self->ldb);
2494 Py_TYPE(self)->tp_free(self);
2497 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2499 PyObject *py_ret = NULL;
2501 if (self->state.req == NULL) {
2502 PyErr_SetString(PyExc_RuntimeError,
2503 "ldb.SearchIterator request already finished");
2508 * TODO: do we want a non-blocking mode?
2509 * In future we may add an optional 'nonblocking'
2510 * argument to search_iterator().
2512 * For now we keep it simple and wait for at
2516 while (self->state.next == NULL) {
2519 if (self->state.result != NULL) {
2521 * We (already) got a final result from the server.
2523 * We stop the iteration and let
2524 * py_ldb_search_iterator_result() will deliver
2525 * the result details.
2527 TALLOC_FREE(self->state.req);
2528 PyErr_SetNone(PyExc_StopIteration);
2532 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2533 if (ret != LDB_SUCCESS) {
2534 struct ldb_context *ldb_ctx;
2535 TALLOC_FREE(self->state.req);
2536 ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb);
2538 * We stop the iteration and let
2539 * py_ldb_search_iterator_result() will deliver
2542 self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2543 ret, ldb_errstring(ldb_ctx));
2544 PyErr_SetNone(PyExc_StopIteration);
2549 py_ret = self->state.next->obj;
2550 self->state.next->obj = NULL;
2551 /* no TALLOC_FREE() as self->state.next is a list */
2552 talloc_free(self->state.next);
2556 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self)
2558 PyObject *py_ret = NULL;
2560 if (self->state.req != NULL) {
2561 PyErr_SetString(PyExc_RuntimeError,
2562 "ldb.SearchIterator request running");
2566 if (self->state.next != NULL) {
2567 PyErr_SetString(PyExc_RuntimeError,
2568 "ldb.SearchIterator not fully consumed.");
2572 if (self->state.exception != NULL) {
2573 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2574 self->state.exception = NULL;
2578 if (self->state.result == NULL) {
2579 PyErr_SetString(PyExc_RuntimeError,
2580 "ldb.SearchIterator result already consumed");
2584 py_ret = self->state.result->obj;
2585 self->state.result->obj = NULL;
2586 TALLOC_FREE(self->state.result);
2590 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self)
2592 if (self->state.req == NULL) {
2593 PyErr_SetString(PyExc_RuntimeError,
2594 "ldb.SearchIterator request already finished");
2598 Py_XDECREF(self->state.exception);
2599 TALLOC_FREE(self->mem_ctx);
2600 ZERO_STRUCT(self->state);
2604 static PyMethodDef py_ldb_search_iterator_methods[] = {
2605 { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2606 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2607 { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2612 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2614 return PyStr_FromString("<ldb search iterator>");
2617 static PyTypeObject PyLdbSearchIterator = {
2618 .tp_name = "ldb.SearchIterator",
2619 .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2620 .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2621 .tp_iter = PyObject_SelfIter,
2622 .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2623 .tp_methods = py_ldb_search_iterator_methods,
2624 .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2625 .tp_doc = "LDB search_iterator.",
2626 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2629 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2631 return PyStr_FromFormat("<ldb module '%s'>",
2632 pyldb_Module_AsModule(self)->ops->name);
2635 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2637 return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
2640 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2642 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2646 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2648 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2652 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2654 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2658 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2660 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2662 struct ldb_request *req;
2663 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2664 struct ldb_module *mod;
2665 const char * const*attrs;
2667 /* type "int" rather than "enum" for "scope" is intentional */
2668 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2669 discard_const_p(char *, kwnames),
2670 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2675 if (py_attrs == Py_None) {
2678 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2683 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2684 scope, NULL /* expr */, attrs,
2685 NULL /* controls */, NULL, NULL, NULL);
2687 talloc_steal(req, attrs);
2689 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2691 req->op.search.res = NULL;
2693 ret = mod->ops->search(mod, req);
2695 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2697 py_ret = PyLdbResult_FromResult(req->op.search.res);
2705 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2707 struct ldb_request *req;
2708 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_ADD;
2717 req->op.add.message = pyldb_Message_AsMessage(py_message);
2719 mod = pyldb_Module_AsModule(self);
2720 ret = mod->ops->add(mod, req);
2722 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2727 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2730 struct ldb_request *req;
2731 PyObject *py_message;
2732 struct ldb_module *mod;
2734 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2737 req = talloc_zero(NULL, struct ldb_request);
2738 req->operation = LDB_MODIFY;
2739 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2741 mod = pyldb_Module_AsModule(self);
2742 ret = mod->ops->modify(mod, req);
2744 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2749 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2752 struct ldb_request *req;
2755 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2758 req = talloc_zero(NULL, struct ldb_request);
2759 req->operation = LDB_DELETE;
2760 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2762 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2764 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2769 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2772 struct ldb_request *req;
2773 PyObject *py_dn1, *py_dn2;
2775 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2778 req = talloc_zero(NULL, struct ldb_request);
2780 req->operation = LDB_RENAME;
2781 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2782 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2784 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2786 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2791 static PyMethodDef py_ldb_module_methods[] = {
2792 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2793 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2794 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2795 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2796 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2797 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2798 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2799 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2803 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2805 talloc_free(self->mem_ctx);
2809 static PyTypeObject PyLdbModule = {
2810 .tp_name = "ldb.LdbModule",
2811 .tp_methods = py_ldb_module_methods,
2812 .tp_repr = (reprfunc)py_ldb_module_repr,
2813 .tp_str = (reprfunc)py_ldb_module_str,
2814 .tp_basicsize = sizeof(PyLdbModuleObject),
2815 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2816 .tp_flags = Py_TPFLAGS_DEFAULT,
2817 .tp_doc = "LDB module (extension)",
2822 * Create a ldb_message_element from a Python object.
2824 * This will accept any sequence objects that contains strings, or
2827 * A reference to set_obj will be borrowed.
2829 * @param mem_ctx Memory context
2830 * @param set_obj Python object to convert
2831 * @param flags ldb_message_element flags to set
2832 * @param attr_name Name of the attribute
2833 * @return New ldb_message_element, allocated as child of mem_ctx
2835 static struct ldb_message_element *PyObject_AsMessageElement(
2836 TALLOC_CTX *mem_ctx,
2839 const char *attr_name)
2841 struct ldb_message_element *me;
2842 const char *msg = NULL;
2846 if (pyldb_MessageElement_Check(set_obj)) {
2847 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2848 /* We have to talloc_reference() the memory context, not the pointer
2849 * which may not actually be it's own context */
2850 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2851 return pyldb_MessageElement_AsMessageElement(set_obj);
2856 me = talloc(mem_ctx, struct ldb_message_element);
2862 me->name = talloc_strdup(me, attr_name);
2864 if (PyBytes_Check(set_obj) || PyStr_Check(set_obj)) {
2866 me->values = talloc_array(me, struct ldb_val, me->num_values);
2867 if (PyBytes_Check(set_obj)) {
2869 result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
2876 msg = PyStr_AsUTF8AndSize(set_obj, &size);
2882 me->values[0].data = talloc_memdup(me,
2883 (const uint8_t *)msg,
2885 me->values[0].length = size;
2886 } else if (PySequence_Check(set_obj)) {
2888 me->num_values = PySequence_Size(set_obj);
2889 me->values = talloc_array(me, struct ldb_val, me->num_values);
2890 for (i = 0; i < me->num_values; i++) {
2891 PyObject *obj = PySequence_GetItem(set_obj, i);
2892 if (PyBytes_Check(obj)) {
2894 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
2900 } else if (PyStr_Check(obj)) {
2901 msg = PyStr_AsUTF8AndSize(obj, &size);
2907 PyErr_Format(PyExc_TypeError,
2908 "Expected string as element %zd in list", i);
2912 me->values[i].data = talloc_memdup(me,
2913 (const uint8_t *)msg,
2915 me->values[i].length = size;
2918 PyErr_Format(PyExc_TypeError,
2919 "String or List type expected for '%s' attribute", attr_name);
2928 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2929 struct ldb_message_element *me)
2934 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2935 result = PyList_New(me->num_values);
2937 for (i = 0; i < me->num_values; i++) {
2938 PyList_SetItem(result, i,
2939 PyObject_FromLdbValue(&me->values[i]));
2945 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2948 if (!PyArg_ParseTuple(args, "I", &i))
2950 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2953 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2956 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2958 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2959 return PyInt_FromLong(el->flags);
2962 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2965 struct ldb_message_element *el;
2966 if (!PyArg_ParseTuple(args, "I", &flags))
2969 el = pyldb_MessageElement_AsMessageElement(self);
2974 static PyMethodDef py_ldb_msg_element_methods[] = {
2975 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2976 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2977 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2981 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2983 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2986 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2988 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2989 if (idx < 0 || idx >= el->num_values) {
2990 PyErr_SetString(PyExc_IndexError, "Out of range");
2993 return PyBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2996 static PySequenceMethods py_ldb_msg_element_seq = {
2997 .sq_length = (lenfunc)py_ldb_msg_element_len,
2998 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
3001 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3004 if (!pyldb_MessageElement_Check(other)) {
3005 Py_INCREF(Py_NotImplemented);
3006 return Py_NotImplemented;
3008 ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3009 pyldb_MessageElement_AsMessageElement(other));
3010 return richcmp(ret, op);
3013 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3015 PyObject *el = ldb_msg_element_to_set(NULL,
3016 pyldb_MessageElement_AsMessageElement(self));
3017 PyObject *ret = PyObject_GetIter(el);
3022 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3024 PyLdbMessageElementObject *ret;
3025 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3030 ret->mem_ctx = talloc_new(NULL);
3031 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
3036 return (PyObject *)ret;
3039 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3041 PyObject *py_elements = NULL;
3042 struct ldb_message_element *el;
3043 unsigned int flags = 0;
3045 const char * const kwnames[] = { "elements", "flags", "name", NULL };
3046 PyLdbMessageElementObject *ret;
3047 TALLOC_CTX *mem_ctx;
3048 const char *msg = NULL;
3052 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3053 discard_const_p(char *, kwnames),
3054 &py_elements, &flags, &name))
3057 mem_ctx = talloc_new(NULL);
3058 if (mem_ctx == NULL) {
3063 el = talloc_zero(mem_ctx, struct ldb_message_element);
3066 talloc_free(mem_ctx);
3070 if (py_elements != NULL) {
3072 if (PyBytes_Check(py_elements) || PyStr_Check(py_elements)) {
3075 el->values = talloc_array(el, struct ldb_val, 1);
3076 if (el->values == NULL) {
3077 talloc_free(mem_ctx);
3081 if (PyBytes_Check(py_elements)) {
3082 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3085 msg = PyStr_AsUTF8AndSize(py_elements, &size);
3086 result = (msg == NULL) ? -1 : 0;
3089 talloc_free(mem_ctx);
3092 el->values[0].data = talloc_memdup(el->values,
3093 (const uint8_t *)msg, size + 1);
3094 el->values[0].length = size;
3095 } else if (PySequence_Check(py_elements)) {
3096 el->num_values = PySequence_Size(py_elements);
3097 el->values = talloc_array(el, struct ldb_val, el->num_values);
3098 if (el->values == NULL) {
3099 talloc_free(mem_ctx);
3103 for (i = 0; i < el->num_values; i++) {
3104 PyObject *item = PySequence_GetItem(py_elements, i);
3106 talloc_free(mem_ctx);
3109 if (PyBytes_Check(item)) {
3111 result = PyBytes_AsStringAndSize(item, &_msg, &size);
3113 } else if (PyStr_Check(item)) {
3114 msg = PyStr_AsUTF8AndSize(item, &size);
3115 result = (msg == NULL) ? -1 : 0;
3117 PyErr_Format(PyExc_TypeError,
3118 "Expected string as element %zd in list", i);
3122 talloc_free(mem_ctx);
3125 el->values[i].data = talloc_memdup(el,
3126 (const uint8_t *)msg, size+1);
3127 el->values[i].length = size;
3130 PyErr_SetString(PyExc_TypeError,
3131 "Expected string or list");
3132 talloc_free(mem_ctx);
3138 el->name = talloc_strdup(el, name);
3140 ret = PyObject_New(PyLdbMessageElementObject, type);
3142 talloc_free(mem_ctx);
3146 ret->mem_ctx = mem_ctx;
3148 return (PyObject *)ret;
3151 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3153 char *element_str = NULL;
3155 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3156 PyObject *ret, *repr;
3158 for (i = 0; i < el->num_values; i++) {
3159 PyObject *o = py_ldb_msg_element_find(self, i);
3160 repr = PyObject_Repr(o);
3161 if (element_str == NULL)
3162 element_str = talloc_strdup(NULL, PyStr_AsUTF8(repr));
3164 element_str = talloc_asprintf_append(element_str, ",%s", PyStr_AsUTF8(repr));
3168 if (element_str != NULL) {
3169 ret = PyStr_FromFormat("MessageElement([%s])", element_str);
3170 talloc_free(element_str);
3172 ret = PyStr_FromString("MessageElement([])");
3178 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3180 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3182 if (el->num_values == 1)
3183 return PyStr_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3188 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3190 talloc_free(self->mem_ctx);
3194 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3196 return wrap_text("MessageElementTextWrapper", self);
3199 static PyGetSetDef py_ldb_msg_element_getset[] = {
3200 { discard_const_p(char, "text"), (getter)py_ldb_msg_element_get_text, NULL, NULL },
3204 static PyTypeObject PyLdbMessageElement = {
3205 .tp_name = "ldb.MessageElement",
3206 .tp_basicsize = sizeof(PyLdbMessageElementObject),
3207 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3208 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3209 .tp_str = (reprfunc)py_ldb_msg_element_str,
3210 .tp_methods = py_ldb_msg_element_methods,
3211 .tp_getset = py_ldb_msg_element_getset,
3212 .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3213 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3214 .tp_as_sequence = &py_ldb_msg_element_seq,
3215 .tp_new = py_ldb_msg_element_new,
3216 .tp_flags = Py_TPFLAGS_DEFAULT,
3217 .tp_doc = "An element of a Message",
3221 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3226 struct ldb_message *msg;
3227 struct ldb_context *ldb_ctx;
3228 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3230 if (!PyArg_ParseTuple(args, "O!O!|I",
3231 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3236 if (!PyLdb_Check(py_ldb)) {
3237 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
3241 /* mask only flags we are going to use */
3242 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3244 PyErr_SetString(PyExc_ValueError,
3245 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3246 " expected as mod_flag value");
3250 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
3252 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3257 py_ret = PyLdbMessage_FromMessage(msg);
3259 talloc_unlink(ldb_ctx, msg);
3264 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3267 if (!PyArg_ParseTuple(args, "s", &name))
3270 ldb_msg_remove_attr(self->msg, name);
3275 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
3277 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3278 Py_ssize_t i, j = 0;
3279 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3280 if (msg->dn != NULL) {
3281 PyList_SetItem(obj, j, PyStr_FromString("dn"));
3284 for (i = 0; i < msg->num_elements; i++) {
3285 PyList_SetItem(obj, j, PyStr_FromString(msg->elements[i].name));
3291 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
3293 struct ldb_message_element *el;
3295 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3296 name = PyStr_AsUTF8(py_name);
3298 PyErr_SetNone(PyExc_TypeError);
3301 if (!ldb_attr_cmp(name, "dn"))
3302 return pyldb_Dn_FromDn(msg->dn);
3303 el = ldb_msg_find_element(msg, name);
3307 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3310 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3312 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
3314 PyErr_SetString(PyExc_KeyError, "No such element");
3320 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3322 PyObject *def = NULL;
3323 const char *kwnames[] = { "name", "default", "idx", NULL };
3324 const char *name = NULL;
3326 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3327 struct ldb_message_element *el;
3329 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3330 discard_const_p(char *, kwnames), &name, &def, &idx)) {
3334 if (strcasecmp(name, "dn") == 0) {
3335 return pyldb_Dn_FromDn(msg->dn);
3338 el = ldb_msg_find_element(msg, name);
3340 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3349 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3352 return PyObject_FromLdbValue(&el->values[idx]);
3355 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
3357 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3358 Py_ssize_t i, j = 0;
3359 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3360 if (msg->dn != NULL) {
3361 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
3364 for (i = 0; i < msg->num_elements; i++, j++) {
3365 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3366 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3367 PyList_SetItem(l, j, value);
3372 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
3374 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3376 PyObject *l = PyList_New(msg->num_elements);
3377 for (i = 0; i < msg->num_elements; i++) {
3378 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
3383 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3385 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3386 PyLdbMessageElementObject *py_element;
3388 struct ldb_message_element *el;
3389 struct ldb_message_element *el_new;
3391 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
3394 el = py_element->el;
3396 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3400 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3401 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3403 /* now deep copy all attribute values */
3404 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3405 if (el_new->values == NULL) {
3409 el_new->num_values = el->num_values;
3411 for (i = 0; i < el->num_values; i++) {
3412 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
3413 if (el_new->values[i].data == NULL
3414 && el->values[i].length != 0) {
3423 static PyMethodDef py_ldb_msg_methods[] = {
3424 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
3425 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3426 "Class method to create ldb.Message object from Dictionary.\n"
3427 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3428 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
3429 "S.keys() -> list\n\n"
3430 "Return sequence of all attribute names." },
3431 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
3432 "S.remove(name)\n\n"
3433 "Remove all entries for attributes with the specified name."},
3434 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
3435 "msg.get(name,default=None,idx=None) -> string\n"
3436 "idx is the index into the values array\n"
3437 "if idx is None, then a list is returned\n"
3438 "if idx is not None, then the element with that index is returned\n"
3439 "if you pass the special name 'dn' then the DN object is returned\n"},
3440 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
3441 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
3442 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
3443 "S.add(element)\n\n"
3444 "Add an element to this message." },
3448 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
3450 PyObject *list, *iter;
3452 list = py_ldb_msg_keys(self);
3453 iter = PyObject_GetIter(list);
3458 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
3462 attr_name = PyStr_AsUTF8(name);
3463 if (attr_name == NULL) {
3464 PyErr_SetNone(PyExc_TypeError);
3468 if (value == NULL) {
3470 ldb_msg_remove_attr(self->msg, attr_name);
3473 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
3474 value, 0, attr_name);
3478 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
3479 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
3480 if (ret != LDB_SUCCESS) {
3481 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
3488 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
3490 return pyldb_Message_AsMessage(self)->num_elements;
3493 static PyMappingMethods py_ldb_msg_mapping = {
3494 .mp_length = (lenfunc)py_ldb_msg_length,
3495 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
3496 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
3499 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3501 const char * const kwnames[] = { "dn", NULL };
3502 struct ldb_message *ret;
3503 TALLOC_CTX *mem_ctx;
3504 PyObject *pydn = NULL;
3505 PyLdbMessageObject *py_ret;
3507 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
3508 discard_const_p(char *, kwnames),
3512 mem_ctx = talloc_new(NULL);
3513 if (mem_ctx == NULL) {
3518 ret = ldb_msg_new(mem_ctx);
3520 talloc_free(mem_ctx);
3527 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
3528 talloc_free(mem_ctx);
3531 ret->dn = talloc_reference(ret, dn);
3534 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
3535 if (py_ret == NULL) {
3537 talloc_free(mem_ctx);
3541 py_ret->mem_ctx = mem_ctx;
3543 return (PyObject *)py_ret;
3546 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
3548 PyLdbMessageObject *ret;
3550 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3555 ret->mem_ctx = talloc_new(NULL);
3556 ret->msg = talloc_reference(ret->mem_ctx, msg);
3557 return (PyObject *)ret;
3560 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3562 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3563 return pyldb_Dn_FromDn(msg->dn);
3566 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3568 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3569 if (!pyldb_Dn_Check(value)) {
3570 PyErr_SetString(PyExc_TypeError, "expected dn");
3574 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3578 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
3580 return wrap_text("MessageTextWrapper", self);
3583 static PyGetSetDef py_ldb_msg_getset[] = {
3584 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
3585 { discard_const_p(char, "text"), (getter)py_ldb_msg_get_text, NULL, NULL },
3589 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3591 PyObject *dict = PyDict_New(), *ret, *repr;
3592 if (PyDict_Update(dict, (PyObject *)self) != 0)
3594 repr = PyObject_Repr(dict);
3599 ret = PyStr_FromFormat("Message(%s)", PyStr_AsUTF8(repr));
3605 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3607 talloc_free(self->mem_ctx);
3611 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3612 PyLdbMessageObject *py_msg2, int op)
3614 struct ldb_message *msg1, *msg2;
3618 if (!PyLdbMessage_Check(py_msg2)) {
3619 Py_INCREF(Py_NotImplemented);
3620 return Py_NotImplemented;
3623 msg1 = pyldb_Message_AsMessage(py_msg1),
3624 msg2 = pyldb_Message_AsMessage(py_msg2);
3626 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3627 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3629 return richcmp(ret, op);
3633 ret = msg1->num_elements - msg2->num_elements;
3635 return richcmp(ret, op);
3638 for (i = 0; i < msg1->num_elements; i++) {
3639 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3640 &msg2->elements[i]);
3642 return richcmp(ret, op);
3645 ret = ldb_msg_element_compare(&msg1->elements[i],
3646 &msg2->elements[i]);
3648 return richcmp(ret, op);
3652 return richcmp(0, op);
3655 static PyTypeObject PyLdbMessage = {
3656 .tp_name = "ldb.Message",
3657 .tp_methods = py_ldb_msg_methods,
3658 .tp_getset = py_ldb_msg_getset,
3659 .tp_as_mapping = &py_ldb_msg_mapping,
3660 .tp_basicsize = sizeof(PyLdbMessageObject),
3661 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3662 .tp_new = py_ldb_msg_new,
3663 .tp_repr = (reprfunc)py_ldb_msg_repr,
3664 .tp_flags = Py_TPFLAGS_DEFAULT,
3665 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3666 .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3667 .tp_doc = "A LDB Message",
3670 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3672 PyLdbTreeObject *ret;
3674 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3680 ret->mem_ctx = talloc_new(NULL);
3681 ret->tree = talloc_reference(ret->mem_ctx, tree);
3682 return (PyObject *)ret;
3685 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3687 talloc_free(self->mem_ctx);
3691 static PyTypeObject PyLdbTree = {
3692 .tp_name = "ldb.Tree",
3693 .tp_basicsize = sizeof(PyLdbTreeObject),
3694 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3695 .tp_flags = Py_TPFLAGS_DEFAULT,
3696 .tp_doc = "A search tree",
3700 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3702 PyObject *py_ldb = (PyObject *)mod->private_data;
3703 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3705 py_base = pyldb_Dn_FromDn(req->op.search.base);
3707 if (py_base == NULL)
3708 return LDB_ERR_OPERATIONS_ERROR;
3710 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3712 if (py_tree == NULL)
3713 return LDB_ERR_OPERATIONS_ERROR;
3715 if (req->op.search.attrs == NULL) {
3719 for (len = 0; req->op.search.attrs[len]; len++);
3720 py_attrs = PyList_New(len);
3721 for (i = 0; i < len; i++)
3722 PyList_SetItem(py_attrs, i, PyStr_FromString(req->op.search.attrs[i]));
3725 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3726 discard_const_p(char, "OiOO"),
3727 py_base, req->op.search.scope, py_tree, py_attrs);
3729 Py_DECREF(py_attrs);
3733 if (py_result == NULL) {
3734 return LDB_ERR_PYTHON_EXCEPTION;
3737 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3738 if (req->op.search.res == NULL) {
3739 return LDB_ERR_PYTHON_EXCEPTION;
3742 Py_DECREF(py_result);
3747 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3749 PyObject *py_ldb = (PyObject *)mod->private_data;
3750 PyObject *py_result, *py_msg;
3752 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3754 if (py_msg == NULL) {
3755 return LDB_ERR_OPERATIONS_ERROR;
3758 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3759 discard_const_p(char, "O"),
3764 if (py_result == NULL) {
3765 return LDB_ERR_PYTHON_EXCEPTION;
3768 Py_DECREF(py_result);
3773 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3775 PyObject *py_ldb = (PyObject *)mod->private_data;
3776 PyObject *py_result, *py_msg;
3778 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3780 if (py_msg == NULL) {
3781 return LDB_ERR_OPERATIONS_ERROR;
3784 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3785 discard_const_p(char, "O"),
3790 if (py_result == NULL) {
3791 return LDB_ERR_PYTHON_EXCEPTION;
3794 Py_DECREF(py_result);
3799 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3801 PyObject *py_ldb = (PyObject *)mod->private_data;
3802 PyObject *py_result, *py_dn;
3804 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3807 return LDB_ERR_OPERATIONS_ERROR;
3809 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3810 discard_const_p(char, "O"),
3813 if (py_result == NULL) {
3814 return LDB_ERR_PYTHON_EXCEPTION;
3817 Py_DECREF(py_result);
3822 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3824 PyObject *py_ldb = (PyObject *)mod->private_data;
3825 PyObject *py_result, *py_olddn, *py_newdn;
3827 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3829 if (py_olddn == NULL)
3830 return LDB_ERR_OPERATIONS_ERROR;
3832 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3834 if (py_newdn == NULL)
3835 return LDB_ERR_OPERATIONS_ERROR;
3837 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3838 discard_const_p(char, "OO"),
3839 py_olddn, py_newdn);
3841 Py_DECREF(py_olddn);
3842 Py_DECREF(py_newdn);
3844 if (py_result == NULL) {
3845 return LDB_ERR_PYTHON_EXCEPTION;
3848 Py_DECREF(py_result);
3853 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3855 PyObject *py_ldb = (PyObject *)mod->private_data;
3856 PyObject *py_result;
3858 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3859 discard_const_p(char, ""));
3861 Py_XDECREF(py_result);
3863 return LDB_ERR_OPERATIONS_ERROR;
3866 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3868 PyObject *py_ldb = (PyObject *)mod->private_data;
3869 PyObject *py_result;
3871 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3872 discard_const_p(char, ""));
3874 Py_XDECREF(py_result);
3876 return LDB_ERR_OPERATIONS_ERROR;
3879 static int py_module_start_transaction(struct ldb_module *mod)
3881 PyObject *py_ldb = (PyObject *)mod->private_data;
3882 PyObject *py_result;
3884 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3885 discard_const_p(char, ""));
3887 if (py_result == NULL) {
3888 return LDB_ERR_PYTHON_EXCEPTION;
3891 Py_DECREF(py_result);
3896 static int py_module_end_transaction(struct ldb_module *mod)
3898 PyObject *py_ldb = (PyObject *)mod->private_data;
3899 PyObject *py_result;
3901 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3902 discard_const_p(char, ""));
3904 if (py_result == NULL) {
3905 return LDB_ERR_PYTHON_EXCEPTION;
3908 Py_DECREF(py_result);
3913 static int py_module_del_transaction(struct ldb_module *mod)
3915 PyObject *py_ldb = (PyObject *)mod->private_data;
3916 PyObject *py_result;
3918 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3919 discard_const_p(char, ""));
3921 if (py_result == NULL) {
3922 return LDB_ERR_PYTHON_EXCEPTION;
3925 Py_DECREF(py_result);
3930 static int py_module_destructor(struct ldb_module *mod)
3932 Py_DECREF((PyObject *)mod->private_data);
3936 static int py_module_init(struct ldb_module *mod)
3938 PyObject *py_class = (PyObject *)mod->ops->private_data;
3939 PyObject *py_result, *py_next, *py_ldb;
3941 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3944 return LDB_ERR_OPERATIONS_ERROR;
3946 py_next = PyLdbModule_FromModule(mod->next);
3948 if (py_next == NULL)
3949 return LDB_ERR_OPERATIONS_ERROR;
3951 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3954 if (py_result == NULL) {
3955 return LDB_ERR_PYTHON_EXCEPTION;
3958 mod->private_data = py_result;
3960 talloc_set_destructor(mod, py_module_destructor);
3962 return ldb_next_init(mod);
3965 static PyObject *py_register_module(PyObject *module, PyObject *args)
3968 struct ldb_module_ops *ops;
3971 if (!PyArg_ParseTuple(args, "O", &input))
3974 ops = talloc_zero(NULL, struct ldb_module_ops);
3980 ops->name = talloc_strdup(ops, PyStr_AsUTF8(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3983 ops->private_data = input;
3984 ops->init_context = py_module_init;
3985 ops->search = py_module_search;
3986 ops->add = py_module_add;
3987 ops->modify = py_module_modify;
3988 ops->del = py_module_del;
3989 ops->rename = py_module_rename;
3990 ops->request = py_module_request;
3991 ops->extended = py_module_extended;
3992 ops->start_transaction = py_module_start_transaction;
3993 ops->end_transaction = py_module_end_transaction;
3994 ops->del_transaction = py_module_del_transaction;
3996 ret = ldb_register_module(ops);
3997 if (ret != LDB_SUCCESS) {
4001 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
4006 static PyObject *py_timestring(PyObject *module, PyObject *args)
4008 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4009 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4013 if (!PyArg_ParseTuple(args, "l", &t_val))
4015 tresult = ldb_timestring(NULL, (time_t) t_val);
4016 ret = PyStr_FromString(tresult);
4017 talloc_free(tresult);
4021 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
4024 if (!PyArg_ParseTuple(args, "s", &str))
4027 return PyInt_FromLong(ldb_string_to_time(str));
4030 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4033 if (!PyArg_ParseTuple(args, "s", &name))
4035 return PyBool_FromLong(ldb_valid_attr_name(name));
4039 encode a string using RFC2254 rules
4041 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4043 char *str, *encoded;
4044 Py_ssize_t size = 0;
4048 if (!PyArg_ParseTuple(args, "s#", &str, &size))
4050 val.data = (uint8_t *)str;
4053 encoded = ldb_binary_encode(NULL, val);
4054 if (encoded == NULL) {
4055 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4058 ret = PyStr_FromString(encoded);
4059 talloc_free(encoded);
4064 decode a string using RFC2254 rules
4066 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4072 if (!PyArg_ParseTuple(args, "s", &str))
4075 val = ldb_binary_decode(NULL, str);
4076 if (val.data == NULL) {
4077 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4080 ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4081 talloc_free(val.data);
4085 static PyMethodDef py_ldb_global_methods[] = {
4086 { "register_module", py_register_module, METH_VARARGS,
4087 "S.register_module(module) -> None\n\n"
4088 "Register a LDB module."},
4089 { "timestring", py_timestring, METH_VARARGS,
4090 "S.timestring(int) -> string\n\n"
4091 "Generate a LDAP time string from a UNIX timestamp" },
4092 { "string_to_time", py_string_to_time, METH_VARARGS,
4093 "S.string_to_time(string) -> int\n\n"
4094 "Parse a LDAP time string into a UNIX timestamp." },
4095 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4096 "S.valid_attr_name(name) -> bool\n\nn"
4097 "Check whether the supplied name is a valid attribute name." },
4098 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
4099 "S.open() -> Ldb\n\n"
4100 "Open a new LDB context." },
4101 { "binary_encode", py_binary_encode, METH_VARARGS,
4102 "S.binary_encode(string) -> string\n\n"
4103 "Perform a RFC2254 binary encoding on a string" },
4104 { "binary_decode", py_binary_decode, METH_VARARGS,
4105 "S.binary_decode(string) -> string\n\n"
4106 "Perform a RFC2254 binary decode on a string" },
4110 #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."
4112 #if PY_MAJOR_VERSION >= 3
4113 static struct PyModuleDef moduledef = {
4114 PyModuleDef_HEAD_INIT,
4116 .m_doc = MODULE_DOC,
4118 .m_methods = py_ldb_global_methods,
4122 static PyObject* module_init(void)
4126 if (PyType_Ready(&PyLdbDn) < 0)
4129 if (PyType_Ready(&PyLdbMessage) < 0)
4132 if (PyType_Ready(&PyLdbMessageElement) < 0)
4135 if (PyType_Ready(&PyLdb) < 0)
4138 if (PyType_Ready(&PyLdbModule) < 0)
4141 if (PyType_Ready(&PyLdbTree) < 0)
4144 if (PyType_Ready(&PyLdbResult) < 0)
4147 if (PyType_Ready(&PyLdbSearchIterator) < 0)
4150 if (PyType_Ready(&PyLdbControl) < 0)
4153 #if PY_MAJOR_VERSION >= 3
4154 m = PyModule_Create(&moduledef);
4156 m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC);
4161 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4163 ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4164 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4165 ADD_LDB_INT(SEQ_NEXT);
4166 ADD_LDB_INT(SCOPE_DEFAULT);
4167 ADD_LDB_INT(SCOPE_BASE);
4168 ADD_LDB_INT(SCOPE_ONELEVEL);
4169 ADD_LDB_INT(SCOPE_SUBTREE);
4171 ADD_LDB_INT(CHANGETYPE_NONE);
4172 ADD_LDB_INT(CHANGETYPE_ADD);
4173 ADD_LDB_INT(CHANGETYPE_DELETE);
4174 ADD_LDB_INT(CHANGETYPE_MODIFY);
4176 ADD_LDB_INT(FLAG_MOD_ADD);
4177 ADD_LDB_INT(FLAG_MOD_REPLACE);
4178 ADD_LDB_INT(FLAG_MOD_DELETE);
4180 ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4181 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4182 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4183 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4185 ADD_LDB_INT(SUCCESS);
4186 ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4187 ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4188 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4189 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4190 ADD_LDB_INT(ERR_COMPARE_FALSE);
4191 ADD_LDB_INT(ERR_COMPARE_TRUE);
4192 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4193 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4194 ADD_LDB_INT(ERR_REFERRAL);
4195 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4196 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4197 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4198 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4199 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4200 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4201 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4202 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4203 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4204 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4205 ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4206 ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4207 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4208 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4209 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4210 ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4211 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4212 ADD_LDB_INT(ERR_BUSY);
4213 ADD_LDB_INT(ERR_UNAVAILABLE);
4214 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4215 ADD_LDB_INT(ERR_LOOP_DETECT);
4216 ADD_LDB_INT(ERR_NAMING_VIOLATION);
4217 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4218 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4219 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4220 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4221 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4222 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4223 ADD_LDB_INT(ERR_OTHER);
4225 ADD_LDB_INT(FLG_RDONLY);
4226 ADD_LDB_INT(FLG_NOSYNC);
4227 ADD_LDB_INT(FLG_RECONNECT);
4228 ADD_LDB_INT(FLG_NOMMAP);
4230 /* Historical misspelling */
4231 PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
4233 PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
4235 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
4236 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
4239 Py_INCREF(&PyLdbDn);
4240 Py_INCREF(&PyLdbModule);
4241 Py_INCREF(&PyLdbMessage);
4242 Py_INCREF(&PyLdbMessageElement);
4243 Py_INCREF(&PyLdbTree);
4244 Py_INCREF(&PyLdbResult);
4245 Py_INCREF(&PyLdbControl);
4247 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
4248 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
4249 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
4250 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
4251 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
4252 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
4253 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
4255 PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
4257 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4259 ADD_LDB_STRING(SYNTAX_DN);
4260 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
4261 ADD_LDB_STRING(SYNTAX_INTEGER);
4262 ADD_LDB_STRING(SYNTAX_BOOLEAN);
4263 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
4264 ADD_LDB_STRING(SYNTAX_UTC_TIME);
4265 ADD_LDB_STRING(OID_COMPARATOR_AND);
4266 ADD_LDB_STRING(OID_COMPARATOR_OR);
4271 #if PY_MAJOR_VERSION >= 3
4272 PyMODINIT_FUNC PyInit_ldb(void);
4273 PyMODINIT_FUNC PyInit_ldb(void)
4275 return module_init();