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