2 Unix SMB/CIFS implementation.
4 Python interface to ldb.
6 Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7 Copyright (C) 2006 Simo Sorce <idra@samba.org>
8 Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9 Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10 Copyright (C) 2009-2011 Andrew Tridgell
11 Copyright (C) 2009-2011 Andrew Bartlett
13 ** NOTE! The following LGPL license applies to the ldb
14 ** library. This does NOT imply that all of Samba is released
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public
19 License as published by the Free Software Foundation; either
20 version 3 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 #include "ldb_private.h"
33 #include "ldb_handlers.h"
35 #include "dlinklist.h"
37 struct py_ldb_search_iterator_reply;
44 struct ldb_request *req;
45 struct py_ldb_search_iterator_reply *next;
46 struct py_ldb_search_iterator_reply *result;
49 } PyLdbSearchIteratorObject;
51 struct py_ldb_search_iterator_reply {
52 struct py_ldb_search_iterator_reply *prev, *next;
53 PyLdbSearchIteratorObject *py_iter;
58 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
59 static PyObject *PyExc_LdbError;
61 static PyTypeObject PyLdbControl;
62 static PyTypeObject PyLdbResult;
63 static PyTypeObject PyLdbSearchIterator;
64 static PyTypeObject PyLdbMessage;
65 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
66 static PyTypeObject PyLdbModule;
67 static PyTypeObject PyLdbDn;
68 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
69 static PyTypeObject PyLdb;
70 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
71 static PyTypeObject PyLdbMessageElement;
72 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
74 static PyTypeObject PyLdbTree;
75 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
76 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
77 static struct ldb_message_element *PyObject_AsMessageElement(
81 const char *attr_name);
82 static PyTypeObject PyLdbBytesType;
84 #if PY_MAJOR_VERSION >= 3
85 #define PyStr_Check PyUnicode_Check
86 #define PyStr_FromString PyUnicode_FromString
87 #define PyStr_FromStringAndSize PyUnicode_FromStringAndSize
88 #define PyStr_FromFormat PyUnicode_FromFormat
89 #define PyStr_FromFormatV PyUnicode_FromFormatV
90 #define PyStr_AsUTF8 PyUnicode_AsUTF8
91 #define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize
92 #define PyInt_FromLong PyLong_FromLong
94 static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size)
96 PyObject* result = NULL;
97 PyObject* args = NULL;
98 args = Py_BuildValue("(y#)", msg, size);
99 result = PyLdbBytesType.tp_new(&PyLdbBytesType, args, NULL);
104 #define PyStr_Check PyString_Check
105 #define PyStr_FromString PyString_FromString
106 #define PyStr_FromStringAndSize PyString_FromStringAndSize
107 #define PyStr_FromFormat PyString_FromFormat
108 #define PyStr_FromFormatV PyString_FromFormatV
109 #define PyStr_AsUTF8 PyString_AsString
110 #define PyLdbBytes_FromStringAndSize PyString_FromStringAndSize
112 const char *PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr);
114 PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr)
116 const char * ret = PyString_AsString(pystr);
119 *sizeptr = PyString_Size(pystr);
124 static PyObject *richcmp(int cmp_val, int op)
128 case Py_LT: ret = cmp_val < 0; break;
129 case Py_LE: ret = cmp_val <= 0; break;
130 case Py_EQ: ret = cmp_val == 0; break;
131 case Py_NE: ret = cmp_val != 0; break;
132 case Py_GT: ret = cmp_val > 0; break;
133 case Py_GE: ret = cmp_val >= 0; break;
135 Py_INCREF(Py_NotImplemented);
136 return Py_NotImplemented;
138 return PyBool_FromLong(ret);
142 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
144 if (self->data != NULL) {
145 char* control = ldb_control_to_string(self->mem_ctx, self->data);
146 if (control == NULL) {
150 return PyStr_FromString(control);
152 return PyStr_FromString("ldb control");
156 static void py_ldb_control_dealloc(PyLdbControlObject *self)
158 if (self->mem_ctx != NULL) {
159 talloc_free(self->mem_ctx);
162 Py_TYPE(self)->tp_free(self);
165 /* Create a text (rather than bytes) interface for a LDB result object */
166 static PyObject *wrap_text(const char *type, PyObject *wrapped)
168 PyObject *mod, *cls, *constructor, *inst;
169 mod = PyImport_ImportModule("_ldb_text");
172 cls = PyObject_GetAttrString(mod, type);
178 constructor = PyObject_GetAttrString(cls, "_wrap");
180 if (constructor == NULL) {
183 inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped);
184 Py_DECREF(constructor);
188 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
190 return PyStr_FromString(self->data->oid);
193 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
195 return PyBool_FromLong(self->data->critical);
198 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
200 if (PyObject_IsTrue(value)) {
201 self->data->critical = true;
203 self->data->critical = false;
208 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
211 const char * const kwnames[] = { "ldb", "data", NULL };
212 struct ldb_control *parsed_controls;
213 PyLdbControlObject *ret;
216 struct ldb_context *ldb_ctx;
218 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
219 discard_const_p(char *, kwnames),
220 &PyLdb, &py_ldb, &data))
223 mem_ctx = talloc_new(NULL);
224 if (mem_ctx == NULL) {
229 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
230 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
232 if (!parsed_controls) {
233 talloc_free(mem_ctx);
234 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
238 ret = PyObject_New(PyLdbControlObject, type);
241 talloc_free(mem_ctx);
245 ret->mem_ctx = mem_ctx;
247 ret->data = talloc_move(mem_ctx, &parsed_controls);
248 if (ret->data == NULL) {
251 talloc_free(mem_ctx);
255 return (PyObject *)ret;
258 static PyGetSetDef py_ldb_control_getset[] = {
259 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
260 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
264 static PyTypeObject PyLdbControl = {
265 .tp_name = "ldb.control",
266 .tp_dealloc = (destructor)py_ldb_control_dealloc,
267 .tp_getattro = PyObject_GenericGetAttr,
268 .tp_basicsize = sizeof(PyLdbControlObject),
269 .tp_getset = py_ldb_control_getset,
270 .tp_doc = "LDB control.",
271 .tp_str = (reprfunc)py_ldb_control_str,
272 .tp_new = py_ldb_control_new,
273 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
276 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
278 if (ret == LDB_ERR_PYTHON_EXCEPTION)
279 return; /* Python exception should already be set, just keep that */
281 PyErr_SetObject(error,
282 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
283 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
285 static PyObject *py_ldb_bytes_str(PyBytesObject *self)
290 if (!PyBytes_Check(self)) {
291 PyErr_Format(PyExc_TypeError,"Unexpected type");
294 result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size);
296 PyErr_Format(PyExc_TypeError, "Failed to extract bytes");
299 return PyUnicode_FromStringAndSize(msg, size);
302 static PyTypeObject PyLdbBytesType = {
303 PyVarObject_HEAD_INIT(NULL, 0)
304 .tp_name = "ldb.bytes",
305 .tp_doc = "str/bytes (with custom str)",
306 .tp_str = (reprfunc)py_ldb_bytes_str,
307 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
310 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
312 return PyLdbBytes_FromStringAndSize((const char *)val->data, val->length);
315 static PyObject *PyStr_FromLdbValue(const struct ldb_val *val)
317 return PyStr_FromStringAndSize((const char *)val->data, val->length);
321 * Create a Python object from a ldb_result.
323 * @param result LDB result to convert
324 * @return Python object with converted result (a list object)
326 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
328 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
329 PyLdbControlObject *ctrl;
330 if (ctl_ctx == NULL) {
335 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
337 talloc_free(ctl_ctx);
341 ctrl->mem_ctx = ctl_ctx;
342 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
343 if (ctrl->data == NULL) {
348 return (PyObject*) ctrl;
352 * Create a Python object from a ldb_result.
354 * @param result LDB result to convert
355 * @return Python object with converted result (a list object)
357 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
359 PyLdbResultObject *ret;
360 PyObject *list, *controls, *referals;
363 if (result == NULL) {
367 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
373 list = PyList_New(result->count);
380 for (i = 0; i < result->count; i++) {
381 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
384 ret->mem_ctx = talloc_new(NULL);
385 if (ret->mem_ctx == NULL) {
394 if (result->controls) {
396 while (result->controls[i]) {
399 controls = PyList_New(i);
400 if (controls == NULL) {
405 for (i=0; result->controls[i]; i++) {
406 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
413 PyList_SetItem(controls, i, ctrl);
417 * No controls so we keep an empty list
419 controls = PyList_New(0);
420 if (controls == NULL) {
427 ret->controls = controls;
431 while (result->refs && result->refs[i]) {
435 referals = PyList_New(i);
436 if (referals == NULL) {
442 for (i = 0;result->refs && result->refs[i]; i++) {
443 PyList_SetItem(referals, i, PyStr_FromString(result->refs[i]));
445 ret->referals = referals;
446 return (PyObject *)ret;
450 * Create a LDB Result from a Python object.
451 * If conversion fails, NULL will be returned and a Python exception set.
453 * Note: the result object only includes the messages at the moment; extended
454 * result, controls and referrals are ignored.
456 * @param mem_ctx Memory context in which to allocate the LDB Result
457 * @param obj Python object to convert
458 * @return a ldb_result, or NULL if the conversion failed
460 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
463 struct ldb_result *res;
469 res = talloc_zero(mem_ctx, struct ldb_result);
470 res->count = PyList_Size(obj);
471 res->msgs = talloc_array(res, struct ldb_message *, res->count);
472 for (i = 0; i < res->count; i++) {
473 PyObject *item = PyList_GetItem(obj, i);
474 res->msgs[i] = pyldb_Message_AsMessage(item);
479 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
481 return PyBool_FromLong(ldb_dn_validate(self->dn));
484 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
486 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
489 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
491 return PyBool_FromLong(ldb_dn_is_special(self->dn));
494 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
496 return PyBool_FromLong(ldb_dn_is_null(self->dn));
499 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
501 return PyStr_FromString(ldb_dn_get_casefold(self->dn));
504 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
506 return PyStr_FromString(ldb_dn_get_linearized(self->dn));
509 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
511 return PyStr_FromString(ldb_dn_canonical_string(self->dn, self->dn));
514 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
516 return PyStr_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
519 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
521 const char * const kwnames[] = { "mode", NULL };
523 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
524 discard_const_p(char *, kwnames),
527 return PyStr_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
530 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
533 const struct ldb_val *val;
535 if (!PyArg_ParseTuple(args, "s", &name))
537 val = ldb_dn_get_extended_component(self->dn, name);
542 return PyBytes_FromStringAndSize((const char *)val->data, val->length);
545 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
549 uint8_t *value = NULL;
552 if (!PyArg_ParseTuple(args, "sz#", &name, (char **)&value, &size))
556 err = ldb_dn_set_extended_component(self->dn, name, NULL);
559 val.data = (uint8_t *)value;
561 err = ldb_dn_set_extended_component(self->dn, name, &val);
564 if (err != LDB_SUCCESS) {
565 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
572 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
574 PyObject *str = PyStr_FromString(ldb_dn_get_linearized(self->dn));
575 PyObject *repr, *result;
578 repr = PyObject_Repr(str);
583 result = PyStr_FromFormat("Dn(%s)", PyStr_AsUTF8(repr));
589 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
593 if (!PyArg_ParseTuple(args, "s", &name))
596 return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
599 static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
602 if (!pyldb_Dn_Check(dn2)) {
603 Py_INCREF(Py_NotImplemented);
604 return Py_NotImplemented;
606 ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2));
607 return richcmp(ret, op);
610 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
612 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
613 struct ldb_dn *parent;
614 PyLdbDnObject *py_ret;
615 TALLOC_CTX *mem_ctx = talloc_new(NULL);
617 parent = ldb_dn_get_parent(mem_ctx, dn);
618 if (parent == NULL) {
619 talloc_free(mem_ctx);
623 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
624 if (py_ret == NULL) {
626 talloc_free(mem_ctx);
629 py_ret->mem_ctx = mem_ctx;
631 return (PyObject *)py_ret;
634 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
637 struct ldb_dn *dn, *other;
638 if (!PyArg_ParseTuple(args, "O", &py_other))
641 dn = pyldb_Dn_AsDn((PyObject *)self);
643 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
646 return PyBool_FromLong(ldb_dn_add_child(dn, other));
649 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
652 struct ldb_dn *other, *dn;
653 if (!PyArg_ParseTuple(args, "O", &py_other))
656 dn = pyldb_Dn_AsDn((PyObject *)self);
658 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
661 return PyBool_FromLong(ldb_dn_add_base(dn, other));
664 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
668 if (!PyArg_ParseTuple(args, "i", &i))
671 dn = pyldb_Dn_AsDn((PyObject *)self);
673 return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
676 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
679 struct ldb_dn *dn, *base;
680 if (!PyArg_ParseTuple(args, "O", &py_base))
683 dn = pyldb_Dn_AsDn((PyObject *)self);
685 if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
688 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
691 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
695 unsigned int num = 0;
697 if (!PyArg_ParseTuple(args, "I", &num))
700 dn = pyldb_Dn_AsDn((PyObject *)self);
702 name = ldb_dn_get_component_name(dn, num);
707 return PyStr_FromString(name);
710 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
713 const struct ldb_val *val;
714 unsigned int num = 0;
716 if (!PyArg_ParseTuple(args, "I", &num))
719 dn = pyldb_Dn_AsDn((PyObject *)self);
721 val = ldb_dn_get_component_val(dn, num);
726 return PyStr_FromLdbValue(val);
729 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
731 unsigned int num = 0;
732 char *name = NULL, *value = NULL;
733 struct ldb_val val = { NULL, };
737 if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size))
740 val.data = (unsigned char*) value;
743 err = ldb_dn_set_component(self->dn, num, name, val);
744 if (err != LDB_SUCCESS) {
745 PyErr_SetString(PyExc_TypeError, "Failed to set component");
752 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
757 dn = pyldb_Dn_AsDn((PyObject *)self);
759 name = ldb_dn_get_rdn_name(dn);
764 return PyStr_FromString(name);
767 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
770 const struct ldb_val *val;
772 dn = pyldb_Dn_AsDn((PyObject *)self);
774 val = ldb_dn_get_rdn_val(dn);
779 return PyStr_FromLdbValue(val);
782 static PyMethodDef py_ldb_dn_methods[] = {
783 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
784 "S.validate() -> bool\n"
785 "Validate DN is correct." },
786 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
787 "S.is_valid() -> bool\n" },
788 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
789 "S.is_special() -> bool\n"
790 "Check whether this is a special LDB DN." },
791 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
792 "Check whether this is a null DN." },
793 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
795 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
797 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
798 "S.canonical_str() -> string\n"
799 "Canonical version of this DN (like a posix path)." },
800 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
801 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
802 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
803 "S.canonical_ex_str() -> string\n"
804 "Canonical version of this DN (like a posix path, with terminating newline)." },
805 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
806 "S.extended_str(mode=1) -> string\n"
807 "Extended version of this DN" },
808 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
810 "Get the parent for this DN." },
811 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
812 "S.add_child(dn) -> None\n"
813 "Add a child DN to this DN." },
814 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
815 "S.add_base(dn) -> None\n"
816 "Add a base DN to this DN." },
817 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
818 "S.remove_base_components(int) -> bool\n"
819 "Remove a number of DN components from the base of this DN." },
820 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
821 "S.check_special(name) -> bool\n\n"
822 "Check if name is a special DN name"},
823 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
824 "S.get_extended_component(name) -> string\n\n"
825 "returns a DN extended component as a binary string"},
826 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
827 "S.set_extended_component(name, value) -> None\n\n"
828 "set a DN extended component as a binary string"},
829 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
830 "S.get_component_name(num) -> string\n"
831 "get the attribute name of the specified component" },
832 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
833 "S.get_component_value(num) -> string\n"
834 "get the attribute value of the specified component as a binary string" },
835 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
836 "S.get_component_value(num, name, value) -> None\n"
837 "set the attribute name and value of the specified component" },
838 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
839 "S.get_rdn_name() -> string\n"
840 "get the RDN attribute name" },
841 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
842 "S.get_rdn_value() -> string\n"
843 "get the RDN attribute value as a binary string" },
847 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
849 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
853 copy a DN as a python object
855 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
857 PyLdbDnObject *py_ret;
859 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
860 if (py_ret == NULL) {
864 py_ret->mem_ctx = talloc_new(NULL);
865 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
866 return (PyObject *)py_ret;
869 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
871 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
873 PyLdbDnObject *py_ret;
875 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
878 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
879 if (py_ret == NULL) {
883 py_ret->mem_ctx = talloc_new(NULL);
884 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
885 ldb_dn_add_base(py_ret->dn, other);
886 return (PyObject *)py_ret;
889 static PySequenceMethods py_ldb_dn_seq = {
890 .sq_length = (lenfunc)py_ldb_dn_len,
891 .sq_concat = (binaryfunc)py_ldb_dn_concat,
894 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
899 struct ldb_context *ldb_ctx;
901 PyLdbDnObject *py_ret;
902 const char * const kwnames[] = { "ldb", "dn", NULL };
904 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
905 discard_const_p(char *, kwnames),
909 if (!PyLdb_Check(py_ldb)) {
910 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
914 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
916 mem_ctx = talloc_new(NULL);
917 if (mem_ctx == NULL) {
922 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
923 if (!ldb_dn_validate(ret)) {
924 talloc_free(mem_ctx);
925 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
929 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
931 talloc_free(mem_ctx);
935 py_ret->mem_ctx = mem_ctx;
937 return (PyObject *)py_ret;
940 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
942 talloc_free(self->mem_ctx);
946 static PyTypeObject PyLdbDn = {
948 .tp_methods = py_ldb_dn_methods,
949 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
950 .tp_repr = (reprfunc)py_ldb_dn_repr,
951 .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp,
952 .tp_as_sequence = &py_ldb_dn_seq,
953 .tp_doc = "A LDB distinguished name.",
954 .tp_new = py_ldb_dn_new,
955 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
956 .tp_basicsize = sizeof(PyLdbDnObject),
957 .tp_flags = Py_TPFLAGS_DEFAULT,
961 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
962 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
964 PyObject *fn = (PyObject *)context;
965 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyStr_FromFormatV(fmt, ap));
968 static PyObject *py_ldb_debug_func;
970 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
973 struct ldb_context *ldb_ctx;
975 if (!PyArg_ParseTuple(args, "O", &cb))
978 if (py_ldb_debug_func != NULL) {
979 Py_DECREF(py_ldb_debug_func);
983 /* FIXME: DECREF cb when exiting program */
984 py_ldb_debug_func = cb;
985 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
986 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
987 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
993 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
996 if (!PyArg_ParseTuple(args, "I", &perms))
999 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
1004 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
1007 if (!PyArg_ParseTuple(args, "s", &modules_dir))
1010 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
1015 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
1017 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1019 ldb_err = ldb_transaction_start(ldb_ctx);
1020 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1024 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
1026 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1028 ldb_err = ldb_transaction_commit(ldb_ctx);
1029 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1033 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
1035 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1037 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
1038 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1042 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
1044 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1046 ldb_err = ldb_transaction_cancel(ldb_ctx);
1047 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1051 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
1053 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1055 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
1056 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1060 static PyObject *py_ldb_repr(PyLdbObject *self)
1062 return PyStr_FromString("<ldb connection>");
1065 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
1067 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
1070 return py_ldb_dn_copy(dn);
1074 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
1076 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
1079 return py_ldb_dn_copy(dn);
1082 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
1084 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
1087 return py_ldb_dn_copy(dn);
1090 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
1092 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
1095 return py_ldb_dn_copy(dn);
1098 static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
1099 const char *paramname)
1103 if (!PyList_Check(list)) {
1104 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
1107 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1113 for (i = 0; i < PyList_Size(list); i++) {
1114 const char *str = NULL;
1116 PyObject *item = PyList_GetItem(list, i);
1117 if (!(PyStr_Check(item) || PyUnicode_Check(item))) {
1118 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
1122 str = PyStr_AsUTF8AndSize(item, &size);
1127 ret[i] = talloc_strndup(ret, str, size);
1133 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1135 const char * const kwnames[] = { "url", "flags", "options", NULL };
1137 PyObject *py_options = Py_None;
1138 const char **options;
1139 unsigned int flags = 0;
1141 struct ldb_context *ldb;
1143 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1144 discard_const_p(char *, kwnames),
1145 &url, &flags, &py_options))
1148 ldb = pyldb_Ldb_AsLdbContext(self);
1150 if (py_options == Py_None) {
1153 options = PyList_AsStrList(ldb, py_options, "options");
1154 if (options == NULL)
1159 ret = ldb_connect(ldb, url, flags, options);
1160 if (ret != LDB_SUCCESS) {
1161 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1166 talloc_free(options);
1170 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1173 struct ldb_context *ldb;
1174 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1179 ret->mem_ctx = talloc_new(NULL);
1180 ldb = ldb_init(ret->mem_ctx, NULL);
1188 return (PyObject *)ret;
1191 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1194 unsigned int flags = 0;
1195 PyObject *py_options = Py_None;
1197 const char **options;
1198 const char * const kwnames[] = { "url", "flags", "options", NULL };
1199 struct ldb_context *ldb_ctx;
1201 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
1202 discard_const_p(char *, kwnames),
1203 &url, &flags, &py_options))
1206 if (py_options == Py_None) {
1209 options = PyList_AsStrList(NULL, py_options, "options");
1210 if (options == NULL)
1214 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1215 ret = ldb_connect(ldb_ctx, url, flags, options);
1216 talloc_free(options);
1218 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1223 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1226 PyObject *py_controls = Py_None;
1227 struct ldb_context *ldb_ctx;
1228 struct ldb_request *req;
1229 struct ldb_control **parsed_controls;
1230 struct ldb_message *msg;
1232 TALLOC_CTX *mem_ctx;
1234 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1236 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1237 discard_const_p(char *, kwnames),
1238 &py_msg, &py_controls, &validate))
1241 mem_ctx = talloc_new(NULL);
1242 if (mem_ctx == NULL) {
1246 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1248 if (py_controls == Py_None) {
1249 parsed_controls = NULL;
1251 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1252 if (controls == NULL) {
1253 talloc_free(mem_ctx);
1256 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1257 talloc_free(controls);
1260 if (!PyLdbMessage_Check(py_msg)) {
1261 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1262 talloc_free(mem_ctx);
1265 msg = pyldb_Message_AsMessage(py_msg);
1268 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1269 if (ret != LDB_SUCCESS) {
1270 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1271 talloc_free(mem_ctx);
1276 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1277 NULL, ldb_op_default_callback, NULL);
1278 if (ret != LDB_SUCCESS) {
1279 PyErr_SetString(PyExc_TypeError, "failed to build request");
1280 talloc_free(mem_ctx);
1284 /* do request and autostart a transaction */
1285 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1287 ret = ldb_transaction_start(ldb_ctx);
1288 if (ret != LDB_SUCCESS) {
1289 talloc_free(mem_ctx);
1290 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1294 ret = ldb_request(ldb_ctx, req);
1295 if (ret == LDB_SUCCESS) {
1296 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1299 if (ret == LDB_SUCCESS) {
1300 ret = ldb_transaction_commit(ldb_ctx);
1302 ldb_transaction_cancel(ldb_ctx);
1305 talloc_free(mem_ctx);
1306 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1313 * Obtain a ldb message from a Python Dictionary object.
1315 * @param mem_ctx Memory context
1316 * @param py_obj Python Dictionary object
1317 * @param ldb_ctx LDB context
1318 * @param mod_flags Flags to be set on every message element
1319 * @return ldb_message on success or NULL on failure
1321 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1323 struct ldb_context *ldb_ctx,
1324 unsigned int mod_flags)
1326 struct ldb_message *msg;
1327 unsigned int msg_pos = 0;
1328 Py_ssize_t dict_pos = 0;
1329 PyObject *key, *value;
1330 struct ldb_message_element *msg_el;
1331 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1333 msg = ldb_msg_new(mem_ctx);
1338 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1341 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1342 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1345 if (msg->dn == NULL) {
1346 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1350 PyErr_SetString(PyExc_TypeError, "no dn set");
1354 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1355 char *key_str = PyStr_AsUTF8(key);
1356 if (ldb_attr_cmp(key_str, "dn") != 0) {
1357 msg_el = PyObject_AsMessageElement(msg->elements, value,
1358 mod_flags, key_str);
1359 if (msg_el == NULL) {
1360 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1363 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1368 msg->num_elements = msg_pos;
1373 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1377 struct ldb_context *ldb_ctx;
1378 struct ldb_request *req;
1379 struct ldb_message *msg = NULL;
1380 PyObject *py_controls = Py_None;
1381 TALLOC_CTX *mem_ctx;
1382 struct ldb_control **parsed_controls;
1383 const char * const kwnames[] = { "message", "controls", NULL };
1385 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1386 discard_const_p(char *, kwnames),
1387 &py_obj, &py_controls))
1390 mem_ctx = talloc_new(NULL);
1391 if (mem_ctx == NULL) {
1395 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1397 if (py_controls == Py_None) {
1398 parsed_controls = NULL;
1400 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1401 if (controls == NULL) {
1402 talloc_free(mem_ctx);
1405 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1406 talloc_free(controls);
1409 if (PyLdbMessage_Check(py_obj)) {
1410 msg = pyldb_Message_AsMessage(py_obj);
1411 } else if (PyDict_Check(py_obj)) {
1412 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1414 PyErr_SetString(PyExc_TypeError,
1415 "Dictionary or LdbMessage object expected!");
1419 /* we should have a PyErr already set */
1420 talloc_free(mem_ctx);
1424 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1425 if (ret != LDB_SUCCESS) {
1426 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1427 talloc_free(mem_ctx);
1431 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1432 NULL, ldb_op_default_callback, NULL);
1433 if (ret != LDB_SUCCESS) {
1434 PyErr_SetString(PyExc_TypeError, "failed to build request");
1435 talloc_free(mem_ctx);
1439 /* do request and autostart a transaction */
1440 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1442 ret = ldb_transaction_start(ldb_ctx);
1443 if (ret != LDB_SUCCESS) {
1444 talloc_free(mem_ctx);
1445 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1449 ret = ldb_request(ldb_ctx, req);
1450 if (ret == LDB_SUCCESS) {
1451 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1454 if (ret == LDB_SUCCESS) {
1455 ret = ldb_transaction_commit(ldb_ctx);
1457 ldb_transaction_cancel(ldb_ctx);
1460 talloc_free(mem_ctx);
1461 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1466 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1471 struct ldb_context *ldb_ctx;
1472 struct ldb_request *req;
1473 PyObject *py_controls = Py_None;
1474 TALLOC_CTX *mem_ctx;
1475 struct ldb_control **parsed_controls;
1476 const char * const kwnames[] = { "dn", "controls", NULL };
1478 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1479 discard_const_p(char *, kwnames),
1480 &py_dn, &py_controls))
1483 mem_ctx = talloc_new(NULL);
1484 if (mem_ctx == NULL) {
1488 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1490 if (py_controls == Py_None) {
1491 parsed_controls = NULL;
1493 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1494 if (controls == NULL) {
1495 talloc_free(mem_ctx);
1498 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1499 talloc_free(controls);
1502 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1503 talloc_free(mem_ctx);
1507 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1508 NULL, ldb_op_default_callback, NULL);
1509 if (ret != LDB_SUCCESS) {
1510 PyErr_SetString(PyExc_TypeError, "failed to build request");
1511 talloc_free(mem_ctx);
1515 /* do request and autostart a transaction */
1516 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1518 ret = ldb_transaction_start(ldb_ctx);
1519 if (ret != LDB_SUCCESS) {
1520 talloc_free(mem_ctx);
1521 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1525 ret = ldb_request(ldb_ctx, req);
1526 if (ret == LDB_SUCCESS) {
1527 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1530 if (ret == LDB_SUCCESS) {
1531 ret = ldb_transaction_commit(ldb_ctx);
1533 ldb_transaction_cancel(ldb_ctx);
1536 talloc_free(mem_ctx);
1537 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1542 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1544 PyObject *py_dn1, *py_dn2;
1545 struct ldb_dn *dn1, *dn2;
1547 TALLOC_CTX *mem_ctx;
1548 PyObject *py_controls = Py_None;
1549 struct ldb_control **parsed_controls;
1550 struct ldb_context *ldb_ctx;
1551 struct ldb_request *req;
1552 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1554 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1556 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1557 discard_const_p(char *, kwnames),
1558 &py_dn1, &py_dn2, &py_controls))
1562 mem_ctx = talloc_new(NULL);
1563 if (mem_ctx == NULL) {
1568 if (py_controls == Py_None) {
1569 parsed_controls = NULL;
1571 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1572 if (controls == NULL) {
1573 talloc_free(mem_ctx);
1576 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1577 talloc_free(controls);
1581 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1582 talloc_free(mem_ctx);
1586 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1587 talloc_free(mem_ctx);
1591 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1592 NULL, ldb_op_default_callback, NULL);
1593 if (ret != LDB_SUCCESS) {
1594 PyErr_SetString(PyExc_TypeError, "failed to build request");
1595 talloc_free(mem_ctx);
1599 /* do request and autostart a transaction */
1600 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1602 ret = ldb_transaction_start(ldb_ctx);
1603 if (ret != LDB_SUCCESS) {
1604 talloc_free(mem_ctx);
1605 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1609 ret = ldb_request(ldb_ctx, req);
1610 if (ret == LDB_SUCCESS) {
1611 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1614 if (ret == LDB_SUCCESS) {
1615 ret = ldb_transaction_commit(ldb_ctx);
1617 ldb_transaction_cancel(ldb_ctx);
1620 talloc_free(mem_ctx);
1621 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1626 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1629 if (!PyArg_ParseTuple(args, "s", &name))
1632 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1637 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1639 char *attribute, *syntax;
1642 struct ldb_context *ldb_ctx;
1644 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1647 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1648 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1650 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1655 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1660 /* We don't want this attached to the 'ldb' any more */
1661 return Py_BuildValue(discard_const_p(char, "(iO)"),
1663 PyLdbMessage_FromMessage(ldif->msg));
1668 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1672 struct ldb_ldif ldif;
1675 TALLOC_CTX *mem_ctx;
1677 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1680 if (!PyLdbMessage_Check(py_msg)) {
1681 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1685 ldif.msg = pyldb_Message_AsMessage(py_msg);
1686 ldif.changetype = changetype;
1688 mem_ctx = talloc_new(NULL);
1690 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1692 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1696 ret = PyStr_FromString(string);
1698 talloc_free(mem_ctx);
1703 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1705 PyObject *list, *ret;
1706 struct ldb_ldif *ldif;
1708 struct ldb_dn *last_dn = NULL;
1710 TALLOC_CTX *mem_ctx;
1712 if (!PyArg_ParseTuple(args, "s", &s))
1715 mem_ctx = talloc_new(NULL);
1720 list = PyList_New(0);
1721 while (s && *s != '\0') {
1722 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1723 talloc_steal(mem_ctx, ldif);
1725 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1726 last_dn = ldif->msg->dn;
1728 const char *last_dn_str = NULL;
1729 const char *err_string = NULL;
1730 if (last_dn == NULL) {
1731 PyErr_SetString(PyExc_ValueError,
1732 "unable to parse LDIF "
1733 "string at first chunk");
1734 talloc_free(mem_ctx);
1739 = ldb_dn_get_linearized(last_dn);
1742 = talloc_asprintf(mem_ctx,
1743 "unable to parse ldif "
1747 PyErr_SetString(PyExc_ValueError,
1749 talloc_free(mem_ctx);
1753 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1754 ret = PyObject_GetIter(list);
1759 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1762 PyObject *py_msg_old;
1763 PyObject *py_msg_new;
1764 struct ldb_message *diff;
1765 struct ldb_context *ldb;
1768 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1771 if (!PyLdbMessage_Check(py_msg_old)) {
1772 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1776 if (!PyLdbMessage_Check(py_msg_new)) {
1777 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1781 ldb = pyldb_Ldb_AsLdbContext(self);
1782 ldb_ret = ldb_msg_difference(ldb, ldb,
1783 pyldb_Message_AsMessage(py_msg_old),
1784 pyldb_Message_AsMessage(py_msg_new),
1786 if (ldb_ret != LDB_SUCCESS) {
1787 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1791 py_ret = PyLdbMessage_FromMessage(diff);
1793 talloc_unlink(ldb, diff);
1798 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1800 const struct ldb_schema_attribute *a;
1801 struct ldb_val old_val;
1802 struct ldb_val new_val;
1803 TALLOC_CTX *mem_ctx;
1810 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1813 result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1814 old_val.length = size;
1817 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1821 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1827 mem_ctx = talloc_new(NULL);
1828 if (mem_ctx == NULL) {
1833 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1834 talloc_free(mem_ctx);
1838 ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1840 talloc_free(mem_ctx);
1845 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1847 PyObject *py_base = Py_None;
1848 int scope = LDB_SCOPE_DEFAULT;
1850 PyObject *py_attrs = Py_None;
1851 PyObject *py_controls = Py_None;
1852 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1854 struct ldb_result *res;
1855 struct ldb_request *req;
1857 struct ldb_context *ldb_ctx;
1858 struct ldb_control **parsed_controls;
1859 struct ldb_dn *base;
1861 TALLOC_CTX *mem_ctx;
1863 /* type "int" rather than "enum" for "scope" is intentional */
1864 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1865 discard_const_p(char *, kwnames),
1866 &py_base, &scope, &expr, &py_attrs, &py_controls))
1870 mem_ctx = talloc_new(NULL);
1871 if (mem_ctx == NULL) {
1875 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1877 if (py_attrs == Py_None) {
1880 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1881 if (attrs == NULL) {
1882 talloc_free(mem_ctx);
1887 if (py_base == Py_None) {
1888 base = ldb_get_default_basedn(ldb_ctx);
1890 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1891 talloc_free(mem_ctx);
1896 if (py_controls == Py_None) {
1897 parsed_controls = NULL;
1899 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1900 if (controls == NULL) {
1901 talloc_free(mem_ctx);
1904 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1905 talloc_free(controls);
1908 res = talloc_zero(mem_ctx, struct ldb_result);
1911 talloc_free(mem_ctx);
1915 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1922 ldb_search_default_callback,
1925 if (ret != LDB_SUCCESS) {
1926 talloc_free(mem_ctx);
1927 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1931 talloc_steal(req, attrs);
1933 ret = ldb_request(ldb_ctx, req);
1935 if (ret == LDB_SUCCESS) {
1936 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1939 if (ret != LDB_SUCCESS) {
1940 talloc_free(mem_ctx);
1941 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1945 py_ret = PyLdbResult_FromResult(res);
1947 talloc_free(mem_ctx);
1952 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
1954 if (reply->py_iter != NULL) {
1955 DLIST_REMOVE(reply->py_iter->state.next, reply);
1956 if (reply->py_iter->state.result == reply) {
1957 reply->py_iter->state.result = NULL;
1959 reply->py_iter = NULL;
1962 if (reply->obj != NULL) {
1963 Py_DECREF(reply->obj);
1970 static int py_ldb_search_iterator_callback(struct ldb_request *req,
1971 struct ldb_reply *ares)
1973 PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
1974 struct ldb_result result = { .msgs = NULL };
1975 struct py_ldb_search_iterator_reply *reply = NULL;
1978 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1981 if (ares->error != LDB_SUCCESS) {
1982 int ret = ares->error;
1984 return ldb_request_done(req, ret);
1987 reply = talloc_zero(py_iter->mem_ctx,
1988 struct py_ldb_search_iterator_reply);
1989 if (reply == NULL) {
1991 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1993 reply->py_iter = py_iter;
1994 talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
1996 switch (ares->type) {
1997 case LDB_REPLY_ENTRY:
1998 reply->obj = PyLdbMessage_FromMessage(ares->message);
1999 if (reply->obj == NULL) {
2001 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2003 DLIST_ADD_END(py_iter->state.next, reply);
2007 case LDB_REPLY_REFERRAL:
2008 reply->obj = PyStr_FromString(ares->referral);
2009 if (reply->obj == NULL) {
2011 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2013 DLIST_ADD_END(py_iter->state.next, reply);
2017 case LDB_REPLY_DONE:
2018 result = (struct ldb_result) { .controls = ares->controls };
2019 reply->obj = PyLdbResult_FromResult(&result);
2020 if (reply->obj == NULL) {
2022 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2024 py_iter->state.result = reply;
2026 return ldb_request_done(req, LDB_SUCCESS);
2030 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2033 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2035 PyObject *py_base = Py_None;
2036 int scope = LDB_SCOPE_DEFAULT;
2039 PyObject *py_attrs = Py_None;
2040 PyObject *py_controls = Py_None;
2041 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
2044 struct ldb_context *ldb_ctx;
2045 struct ldb_control **parsed_controls;
2046 struct ldb_dn *base;
2047 PyLdbSearchIteratorObject *py_iter;
2049 /* type "int" rather than "enum" for "scope" is intentional */
2050 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
2051 discard_const_p(char *, kwnames),
2052 &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
2055 py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
2056 if (py_iter == NULL) {
2060 py_iter->ldb = self;
2062 ZERO_STRUCT(py_iter->state);
2063 py_iter->mem_ctx = talloc_new(NULL);
2064 if (py_iter->mem_ctx == NULL) {
2070 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2072 if (py_attrs == Py_None) {
2075 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2076 if (attrs == NULL) {
2083 if (py_base == Py_None) {
2084 base = ldb_get_default_basedn(ldb_ctx);
2086 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2093 if (py_controls == Py_None) {
2094 parsed_controls = NULL;
2096 const char **controls = NULL;
2098 controls = PyList_AsStrList(py_iter->mem_ctx,
2099 py_controls, "controls");
2100 if (controls == NULL) {
2106 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2109 if (controls[0] != NULL && parsed_controls == NULL) {
2114 talloc_free(controls);
2117 ret = ldb_build_search_req(&py_iter->state.req,
2126 py_ldb_search_iterator_callback,
2128 if (ret != LDB_SUCCESS) {
2130 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2134 ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2136 ret = ldb_request(ldb_ctx, py_iter->state.req);
2137 if (ret != LDB_SUCCESS) {
2139 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2143 return (PyObject *)py_iter;
2146 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2151 if (!PyArg_ParseTuple(args, "s", &name))
2154 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
2159 /* FIXME: More interpretation */
2164 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2169 if (!PyArg_ParseTuple(args, "sO", &name, &data))
2172 /* FIXME: More interpretation */
2174 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
2179 static PyObject *py_ldb_modules(PyLdbObject *self)
2181 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2182 PyObject *ret = PyList_New(0);
2183 struct ldb_module *mod;
2185 for (mod = ldb->modules; mod; mod = mod->next) {
2186 PyList_Append(ret, PyLdbModule_FromModule(mod));
2192 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2194 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2198 if (!PyArg_ParseTuple(args, "i", &type))
2201 /* FIXME: More interpretation */
2203 ret = ldb_sequence_number(ldb, type, &value);
2205 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2207 return PyLong_FromLongLong(value);
2211 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2213 .read_fn = ldb_handler_copy,
2214 .write_clear_fn = ldb_handler_copy,
2215 .write_hex_fn = ldb_handler_copy,
2218 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self)
2220 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2223 ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2225 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2231 static PyMethodDef py_ldb_methods[] = {
2232 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
2233 "S.set_debug(callback) -> None\n"
2234 "Set callback for LDB debug messages.\n"
2235 "The callback should accept a debug level and debug text." },
2236 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
2237 "S.set_create_perms(mode) -> None\n"
2238 "Set mode to use when creating new LDB files." },
2239 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2240 "S.set_modules_dir(path) -> None\n"
2241 "Set path LDB should search for modules" },
2242 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
2243 "S.transaction_start() -> None\n"
2244 "Start a new transaction." },
2245 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2246 "S.transaction_prepare_commit() -> None\n"
2247 "prepare to commit a new transaction (2-stage commit)." },
2248 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
2249 "S.transaction_commit() -> None\n"
2250 "commit a new transaction." },
2251 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
2252 "S.transaction_cancel() -> None\n"
2253 "cancel a new transaction." },
2254 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
2256 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2258 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2260 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2262 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2264 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
2265 "S.connect(url, flags=0, options=None) -> None\n"
2266 "Connect to a LDB URL." },
2267 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
2268 "S.modify(message, controls=None, validate=False) -> None\n"
2269 "Modify an entry." },
2270 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
2271 "S.add(message, controls=None) -> None\n"
2273 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
2274 "S.delete(dn, controls=None) -> None\n"
2275 "Remove an entry." },
2276 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
2277 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2278 "Rename an entry." },
2279 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
2280 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2281 "Search in a database.\n"
2283 ":param base: Optional base DN to search\n"
2284 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2285 ":param expression: Optional search expression\n"
2286 ":param attrs: Attributes to return (defaults to all)\n"
2287 ":param controls: Optional list of controls\n"
2288 ":return: ldb.Result object\n"
2290 { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS,
2291 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2292 "Search in a database.\n"
2294 ":param base: Optional base DN to search\n"
2295 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2296 ":param expression: Optional search expression\n"
2297 ":param attrs: Attributes to return (defaults to all)\n"
2298 ":param controls: Optional list of controls\n"
2299 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2300 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2302 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2304 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2306 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2308 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2309 "S.parse_ldif(ldif) -> iter(messages)\n"
2310 "Parse a string formatted using LDIF." },
2311 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2312 "S.write_ldif(message, changetype) -> ldif\n"
2313 "Print the message as a string formatted using LDIF." },
2314 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2315 "S.msg_diff(Message) -> Message\n"
2316 "Return an LDB Message of the difference between two Message objects." },
2317 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2318 "S.get_opaque(name) -> value\n"
2319 "Get an opaque value set on this LDB connection. \n"
2320 ":note: The returned value may not be useful in Python."
2322 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2323 "S.set_opaque(name, value) -> None\n"
2324 "Set an opaque value on this LDB connection. \n"
2325 ":note: Passing incorrect values may cause crashes." },
2326 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2327 "S.modules() -> list\n"
2328 "Return the list of modules on this LDB connection " },
2329 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2330 "S.sequence_number(type) -> value\n"
2331 "Return the value of the sequence according to the requested type" },
2332 { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2333 "S._register_test_extensions() -> None\n"
2334 "Register internal extensions used in testing" },
2338 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2340 PyLdbModuleObject *ret;
2342 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2347 ret->mem_ctx = talloc_new(NULL);
2348 ret->mod = talloc_reference(ret->mem_ctx, mod);
2349 return (PyObject *)ret;
2352 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2354 struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2358 return PyLdbModule_FromModule(mod);
2361 static PyGetSetDef py_ldb_getset[] = {
2362 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
2366 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2368 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2370 struct ldb_result *result;
2374 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2378 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2380 if (ret != LDB_SUCCESS) {
2381 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2385 count = result->count;
2387 talloc_free(result);
2390 PyErr_Format(PyExc_RuntimeError,
2391 "Searching for [%s] dn gave %u results!",
2392 ldb_dn_get_linearized(dn),
2400 static PySequenceMethods py_ldb_seq = {
2401 .sq_contains = (objobjproc)py_ldb_contains,
2404 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2408 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2413 ret->mem_ctx = talloc_new(NULL);
2414 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2415 return (PyObject *)ret;
2418 static void py_ldb_dealloc(PyLdbObject *self)
2420 talloc_free(self->mem_ctx);
2421 Py_TYPE(self)->tp_free(self);
2424 static PyTypeObject PyLdb = {
2425 .tp_name = "ldb.Ldb",
2426 .tp_methods = py_ldb_methods,
2427 .tp_repr = (reprfunc)py_ldb_repr,
2428 .tp_new = py_ldb_new,
2429 .tp_init = (initproc)py_ldb_init,
2430 .tp_dealloc = (destructor)py_ldb_dealloc,
2431 .tp_getset = py_ldb_getset,
2432 .tp_getattro = PyObject_GenericGetAttr,
2433 .tp_basicsize = sizeof(PyLdbObject),
2434 .tp_doc = "Connection to a LDB database.",
2435 .tp_as_sequence = &py_ldb_seq,
2436 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2439 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2441 talloc_free(self->mem_ctx);
2442 Py_DECREF(self->msgs);
2443 Py_DECREF(self->referals);
2444 Py_DECREF(self->controls);
2445 Py_TYPE(self)->tp_free(self);
2448 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2450 Py_INCREF(self->msgs);
2454 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2456 Py_INCREF(self->controls);
2457 return self->controls;
2460 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2462 Py_INCREF(self->referals);
2463 return self->referals;
2466 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2469 if (self->msgs == NULL) {
2470 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2473 size = PyList_Size(self->msgs);
2474 return PyInt_FromLong(size);
2477 static PyGetSetDef py_ldb_result_getset[] = {
2478 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2479 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2480 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2481 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2485 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2487 return PyObject_GetIter(self->msgs);
2490 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2492 return PySequence_Size(self->msgs);
2495 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2497 return PySequence_GetItem(self->msgs, idx);
2500 static PySequenceMethods py_ldb_result_seq = {
2501 .sq_length = (lenfunc)py_ldb_result_len,
2502 .sq_item = (ssizeargfunc)py_ldb_result_find,
2505 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2507 return PyStr_FromString("<ldb result>");
2511 static PyTypeObject PyLdbResult = {
2512 .tp_name = "ldb.Result",
2513 .tp_repr = (reprfunc)py_ldb_result_repr,
2514 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2515 .tp_iter = (getiterfunc)py_ldb_result_iter,
2516 .tp_getset = py_ldb_result_getset,
2517 .tp_getattro = PyObject_GenericGetAttr,
2518 .tp_basicsize = sizeof(PyLdbResultObject),
2519 .tp_as_sequence = &py_ldb_result_seq,
2520 .tp_doc = "LDB result.",
2521 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2524 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2526 Py_XDECREF(self->state.exception);
2527 TALLOC_FREE(self->mem_ctx);
2528 ZERO_STRUCT(self->state);
2529 Py_DECREF(self->ldb);
2530 Py_TYPE(self)->tp_free(self);
2533 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2535 PyObject *py_ret = NULL;
2537 if (self->state.req == NULL) {
2538 PyErr_SetString(PyExc_RuntimeError,
2539 "ldb.SearchIterator request already finished");
2544 * TODO: do we want a non-blocking mode?
2545 * In future we may add an optional 'nonblocking'
2546 * argument to search_iterator().
2548 * For now we keep it simple and wait for at
2552 while (self->state.next == NULL) {
2555 if (self->state.result != NULL) {
2557 * We (already) got a final result from the server.
2559 * We stop the iteration and let
2560 * py_ldb_search_iterator_result() will deliver
2561 * the result details.
2563 TALLOC_FREE(self->state.req);
2564 PyErr_SetNone(PyExc_StopIteration);
2568 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2569 if (ret != LDB_SUCCESS) {
2570 struct ldb_context *ldb_ctx;
2571 TALLOC_FREE(self->state.req);
2572 ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb);
2574 * We stop the iteration and let
2575 * py_ldb_search_iterator_result() will deliver
2578 self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2579 ret, ldb_errstring(ldb_ctx));
2580 PyErr_SetNone(PyExc_StopIteration);
2585 py_ret = self->state.next->obj;
2586 self->state.next->obj = NULL;
2587 /* no TALLOC_FREE() as self->state.next is a list */
2588 talloc_free(self->state.next);
2592 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self)
2594 PyObject *py_ret = NULL;
2596 if (self->state.req != NULL) {
2597 PyErr_SetString(PyExc_RuntimeError,
2598 "ldb.SearchIterator request running");
2602 if (self->state.next != NULL) {
2603 PyErr_SetString(PyExc_RuntimeError,
2604 "ldb.SearchIterator not fully consumed.");
2608 if (self->state.exception != NULL) {
2609 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2610 self->state.exception = NULL;
2614 if (self->state.result == NULL) {
2615 PyErr_SetString(PyExc_RuntimeError,
2616 "ldb.SearchIterator result already consumed");
2620 py_ret = self->state.result->obj;
2621 self->state.result->obj = NULL;
2622 TALLOC_FREE(self->state.result);
2626 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self)
2628 if (self->state.req == NULL) {
2629 PyErr_SetString(PyExc_RuntimeError,
2630 "ldb.SearchIterator request already finished");
2634 Py_XDECREF(self->state.exception);
2635 TALLOC_FREE(self->mem_ctx);
2636 ZERO_STRUCT(self->state);
2640 static PyMethodDef py_ldb_search_iterator_methods[] = {
2641 { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2642 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2643 { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2648 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2650 return PyStr_FromString("<ldb search iterator>");
2653 static PyTypeObject PyLdbSearchIterator = {
2654 .tp_name = "ldb.SearchIterator",
2655 .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2656 .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2657 .tp_iter = PyObject_SelfIter,
2658 .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2659 .tp_methods = py_ldb_search_iterator_methods,
2660 .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2661 .tp_doc = "LDB search_iterator.",
2662 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2665 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2667 return PyStr_FromFormat("<ldb module '%s'>",
2668 pyldb_Module_AsModule(self)->ops->name);
2671 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2673 return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
2676 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2678 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2682 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2684 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2688 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2690 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2694 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2696 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2698 struct ldb_request *req;
2699 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2700 struct ldb_module *mod;
2701 const char * const*attrs;
2703 /* type "int" rather than "enum" for "scope" is intentional */
2704 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2705 discard_const_p(char *, kwnames),
2706 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2711 if (py_attrs == Py_None) {
2714 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2719 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2720 scope, NULL /* expr */, attrs,
2721 NULL /* controls */, NULL, NULL, NULL);
2723 talloc_steal(req, attrs);
2725 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2727 req->op.search.res = NULL;
2729 ret = mod->ops->search(mod, req);
2731 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2733 py_ret = PyLdbResult_FromResult(req->op.search.res);
2741 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2743 struct ldb_request *req;
2744 PyObject *py_message;
2746 struct ldb_module *mod;
2748 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2751 req = talloc_zero(NULL, struct ldb_request);
2752 req->operation = LDB_ADD;
2753 req->op.add.message = pyldb_Message_AsMessage(py_message);
2755 mod = pyldb_Module_AsModule(self);
2756 ret = mod->ops->add(mod, req);
2758 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2763 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2766 struct ldb_request *req;
2767 PyObject *py_message;
2768 struct ldb_module *mod;
2770 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2773 req = talloc_zero(NULL, struct ldb_request);
2774 req->operation = LDB_MODIFY;
2775 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2777 mod = pyldb_Module_AsModule(self);
2778 ret = mod->ops->modify(mod, req);
2780 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2785 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2788 struct ldb_request *req;
2791 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2794 req = talloc_zero(NULL, struct ldb_request);
2795 req->operation = LDB_DELETE;
2796 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2798 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2800 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2805 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2808 struct ldb_request *req;
2809 PyObject *py_dn1, *py_dn2;
2811 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2814 req = talloc_zero(NULL, struct ldb_request);
2816 req->operation = LDB_RENAME;
2817 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2818 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2820 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2822 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2827 static PyMethodDef py_ldb_module_methods[] = {
2828 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2829 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2830 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2831 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2832 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2833 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2834 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2835 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2839 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2841 talloc_free(self->mem_ctx);
2845 static PyTypeObject PyLdbModule = {
2846 .tp_name = "ldb.LdbModule",
2847 .tp_methods = py_ldb_module_methods,
2848 .tp_repr = (reprfunc)py_ldb_module_repr,
2849 .tp_str = (reprfunc)py_ldb_module_str,
2850 .tp_basicsize = sizeof(PyLdbModuleObject),
2851 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2852 .tp_flags = Py_TPFLAGS_DEFAULT,
2853 .tp_doc = "LDB module (extension)",
2858 * Create a ldb_message_element from a Python object.
2860 * This will accept any sequence objects that contains strings, or
2863 * A reference to set_obj will be borrowed.
2865 * @param mem_ctx Memory context
2866 * @param set_obj Python object to convert
2867 * @param flags ldb_message_element flags to set
2868 * @param attr_name Name of the attribute
2869 * @return New ldb_message_element, allocated as child of mem_ctx
2871 static struct ldb_message_element *PyObject_AsMessageElement(
2872 TALLOC_CTX *mem_ctx,
2875 const char *attr_name)
2877 struct ldb_message_element *me;
2878 const char *msg = NULL;
2882 if (pyldb_MessageElement_Check(set_obj)) {
2883 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2884 /* We have to talloc_reference() the memory context, not the pointer
2885 * which may not actually be it's own context */
2886 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2887 return pyldb_MessageElement_AsMessageElement(set_obj);
2892 me = talloc(mem_ctx, struct ldb_message_element);
2898 me->name = talloc_strdup(me, attr_name);
2900 if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) {
2902 me->values = talloc_array(me, struct ldb_val, me->num_values);
2903 if (PyBytes_Check(set_obj)) {
2905 result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
2912 msg = PyStr_AsUTF8AndSize(set_obj, &size);
2918 me->values[0].data = talloc_memdup(me,
2919 (const uint8_t *)msg,
2921 me->values[0].length = size;
2922 } else if (PySequence_Check(set_obj)) {
2924 me->num_values = PySequence_Size(set_obj);
2925 me->values = talloc_array(me, struct ldb_val, me->num_values);
2926 for (i = 0; i < me->num_values; i++) {
2927 PyObject *obj = PySequence_GetItem(set_obj, i);
2928 if (PyBytes_Check(obj)) {
2930 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
2936 } else if (PyUnicode_Check(obj)) {
2937 msg = PyStr_AsUTF8AndSize(obj, &size);
2943 PyErr_Format(PyExc_TypeError,
2944 "Expected string as element %zd in list", i);
2948 me->values[i].data = talloc_memdup(me,
2949 (const uint8_t *)msg,
2951 me->values[i].length = size;
2954 PyErr_Format(PyExc_TypeError,
2955 "String or List type expected for '%s' attribute", attr_name);
2964 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2965 struct ldb_message_element *me)
2970 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2971 result = PyList_New(me->num_values);
2973 for (i = 0; i < me->num_values; i++) {
2974 PyList_SetItem(result, i,
2975 PyObject_FromLdbValue(&me->values[i]));
2981 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2984 if (!PyArg_ParseTuple(args, "I", &i))
2986 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2989 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2992 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2994 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2995 return PyInt_FromLong(el->flags);
2998 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
3001 struct ldb_message_element *el;
3002 if (!PyArg_ParseTuple(args, "I", &flags))
3005 el = pyldb_MessageElement_AsMessageElement(self);
3010 static PyMethodDef py_ldb_msg_element_methods[] = {
3011 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
3012 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
3013 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
3017 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
3019 return pyldb_MessageElement_AsMessageElement(self)->num_values;
3022 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
3024 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3025 if (idx < 0 || idx >= el->num_values) {
3026 PyErr_SetString(PyExc_IndexError, "Out of range");
3029 return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
3032 static PySequenceMethods py_ldb_msg_element_seq = {
3033 .sq_length = (lenfunc)py_ldb_msg_element_len,
3034 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
3037 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3040 if (!pyldb_MessageElement_Check(other)) {
3041 Py_INCREF(Py_NotImplemented);
3042 return Py_NotImplemented;
3044 ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3045 pyldb_MessageElement_AsMessageElement(other));
3046 return richcmp(ret, op);
3049 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3051 PyObject *el = ldb_msg_element_to_set(NULL,
3052 pyldb_MessageElement_AsMessageElement(self));
3053 PyObject *ret = PyObject_GetIter(el);
3058 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3060 PyLdbMessageElementObject *ret;
3061 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3066 ret->mem_ctx = talloc_new(NULL);
3067 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
3072 return (PyObject *)ret;
3075 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3077 PyObject *py_elements = NULL;
3078 struct ldb_message_element *el;
3079 unsigned int flags = 0;
3081 const char * const kwnames[] = { "elements", "flags", "name", NULL };
3082 PyLdbMessageElementObject *ret;
3083 TALLOC_CTX *mem_ctx;
3084 const char *msg = NULL;
3088 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3089 discard_const_p(char *, kwnames),
3090 &py_elements, &flags, &name))
3093 mem_ctx = talloc_new(NULL);
3094 if (mem_ctx == NULL) {
3099 el = talloc_zero(mem_ctx, struct ldb_message_element);
3102 talloc_free(mem_ctx);
3106 if (py_elements != NULL) {
3108 if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) {
3111 el->values = talloc_array(el, struct ldb_val, 1);
3112 if (el->values == NULL) {
3113 talloc_free(mem_ctx);
3117 if (PyBytes_Check(py_elements)) {
3118 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3121 msg = PyStr_AsUTF8AndSize(py_elements, &size);
3122 result = (msg == NULL) ? -1 : 0;
3125 talloc_free(mem_ctx);
3128 el->values[0].data = talloc_memdup(el->values,
3129 (const uint8_t *)msg, size + 1);
3130 el->values[0].length = size;
3131 } else if (PySequence_Check(py_elements)) {
3132 el->num_values = PySequence_Size(py_elements);
3133 el->values = talloc_array(el, struct ldb_val, el->num_values);
3134 if (el->values == NULL) {
3135 talloc_free(mem_ctx);
3139 for (i = 0; i < el->num_values; i++) {
3140 PyObject *item = PySequence_GetItem(py_elements, i);
3142 talloc_free(mem_ctx);
3145 if (PyBytes_Check(item)) {
3147 result = PyBytes_AsStringAndSize(item, &_msg, &size);
3149 } else if (PyUnicode_Check(item)) {
3150 msg = PyStr_AsUTF8AndSize(item, &size);
3151 result = (msg == NULL) ? -1 : 0;
3153 PyErr_Format(PyExc_TypeError,
3154 "Expected string as element %zd in list", i);
3158 talloc_free(mem_ctx);
3161 el->values[i].data = talloc_memdup(el,
3162 (const uint8_t *)msg, size+1);
3163 el->values[i].length = size;
3166 PyErr_SetString(PyExc_TypeError,
3167 "Expected string or list");
3168 talloc_free(mem_ctx);
3174 el->name = talloc_strdup(el, name);
3176 ret = PyObject_New(PyLdbMessageElementObject, type);
3178 talloc_free(mem_ctx);
3182 ret->mem_ctx = mem_ctx;
3184 return (PyObject *)ret;
3187 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3189 char *element_str = NULL;
3191 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3192 PyObject *ret, *repr;
3194 for (i = 0; i < el->num_values; i++) {
3195 PyObject *o = py_ldb_msg_element_find(self, i);
3196 repr = PyObject_Repr(o);
3197 if (element_str == NULL)
3198 element_str = talloc_strdup(NULL, PyStr_AsUTF8(repr));
3200 element_str = talloc_asprintf_append(element_str, ",%s", PyStr_AsUTF8(repr));
3204 if (element_str != NULL) {
3205 ret = PyStr_FromFormat("MessageElement([%s])", element_str);
3206 talloc_free(element_str);
3208 ret = PyStr_FromString("MessageElement([])");
3214 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3216 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3218 if (el->num_values == 1)
3219 return PyStr_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3224 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3226 talloc_free(self->mem_ctx);
3230 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3232 return wrap_text("MessageElementTextWrapper", self);
3235 static PyGetSetDef py_ldb_msg_element_getset[] = {
3236 { discard_const_p(char, "text"), (getter)py_ldb_msg_element_get_text, NULL, NULL },
3240 static PyTypeObject PyLdbMessageElement = {
3241 .tp_name = "ldb.MessageElement",
3242 .tp_basicsize = sizeof(PyLdbMessageElementObject),
3243 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3244 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3245 .tp_str = (reprfunc)py_ldb_msg_element_str,
3246 .tp_methods = py_ldb_msg_element_methods,
3247 .tp_getset = py_ldb_msg_element_getset,
3248 .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3249 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3250 .tp_as_sequence = &py_ldb_msg_element_seq,
3251 .tp_new = py_ldb_msg_element_new,
3252 .tp_flags = Py_TPFLAGS_DEFAULT,
3253 .tp_doc = "An element of a Message",
3257 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3262 struct ldb_message *msg;
3263 struct ldb_context *ldb_ctx;
3264 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3266 if (!PyArg_ParseTuple(args, "O!O!|I",
3267 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3272 if (!PyLdb_Check(py_ldb)) {
3273 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
3277 /* mask only flags we are going to use */
3278 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3280 PyErr_SetString(PyExc_ValueError,
3281 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3282 " expected as mod_flag value");
3286 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
3288 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3293 py_ret = PyLdbMessage_FromMessage(msg);
3295 talloc_unlink(ldb_ctx, msg);
3300 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3303 if (!PyArg_ParseTuple(args, "s", &name))
3306 ldb_msg_remove_attr(self->msg, name);
3311 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
3313 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3314 Py_ssize_t i, j = 0;
3315 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3316 if (msg->dn != NULL) {
3317 PyList_SetItem(obj, j, PyStr_FromString("dn"));
3320 for (i = 0; i < msg->num_elements; i++) {
3321 PyList_SetItem(obj, j, PyStr_FromString(msg->elements[i].name));
3327 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
3329 struct ldb_message_element *el;
3331 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3332 name = PyStr_AsUTF8(py_name);
3334 PyErr_SetNone(PyExc_TypeError);
3337 if (!ldb_attr_cmp(name, "dn"))
3338 return pyldb_Dn_FromDn(msg->dn);
3339 el = ldb_msg_find_element(msg, name);
3343 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3346 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3348 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
3350 PyErr_SetString(PyExc_KeyError, "No such element");
3356 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3358 PyObject *def = NULL;
3359 const char *kwnames[] = { "name", "default", "idx", NULL };
3360 const char *name = NULL;
3362 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3363 struct ldb_message_element *el;
3365 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3366 discard_const_p(char *, kwnames), &name, &def, &idx)) {
3370 if (strcasecmp(name, "dn") == 0) {
3371 return pyldb_Dn_FromDn(msg->dn);
3374 el = ldb_msg_find_element(msg, name);
3376 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3385 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3388 return PyObject_FromLdbValue(&el->values[idx]);
3391 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
3393 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3394 Py_ssize_t i, j = 0;
3395 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3396 if (msg->dn != NULL) {
3397 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
3400 for (i = 0; i < msg->num_elements; i++, j++) {
3401 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3402 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3403 PyList_SetItem(l, j, value);
3408 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
3410 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3412 PyObject *l = PyList_New(msg->num_elements);
3413 for (i = 0; i < msg->num_elements; i++) {
3414 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
3419 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3421 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3422 PyLdbMessageElementObject *py_element;
3424 struct ldb_message_element *el;
3425 struct ldb_message_element *el_new;
3427 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
3430 el = py_element->el;
3432 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3436 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3437 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3439 /* now deep copy all attribute values */
3440 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3441 if (el_new->values == NULL) {
3445 el_new->num_values = el->num_values;
3447 for (i = 0; i < el->num_values; i++) {
3448 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
3449 if (el_new->values[i].data == NULL
3450 && el->values[i].length != 0) {
3459 static PyMethodDef py_ldb_msg_methods[] = {
3460 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
3461 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3462 "Class method to create ldb.Message object from Dictionary.\n"
3463 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3464 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
3465 "S.keys() -> list\n\n"
3466 "Return sequence of all attribute names." },
3467 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
3468 "S.remove(name)\n\n"
3469 "Remove all entries for attributes with the specified name."},
3470 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
3471 "msg.get(name,default=None,idx=None) -> string\n"
3472 "idx is the index into the values array\n"
3473 "if idx is None, then a list is returned\n"
3474 "if idx is not None, then the element with that index is returned\n"
3475 "if you pass the special name 'dn' then the DN object is returned\n"},
3476 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
3477 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
3478 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
3479 "S.add(element)\n\n"
3480 "Add an element to this message." },
3484 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
3486 PyObject *list, *iter;
3488 list = py_ldb_msg_keys(self);
3489 iter = PyObject_GetIter(list);
3494 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
3498 attr_name = PyStr_AsUTF8(name);
3499 if (attr_name == NULL) {
3500 PyErr_SetNone(PyExc_TypeError);
3504 if (value == NULL) {
3506 ldb_msg_remove_attr(self->msg, attr_name);
3509 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
3510 value, 0, attr_name);
3514 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
3515 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
3516 if (ret != LDB_SUCCESS) {
3517 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
3524 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
3526 return pyldb_Message_AsMessage(self)->num_elements;
3529 static PyMappingMethods py_ldb_msg_mapping = {
3530 .mp_length = (lenfunc)py_ldb_msg_length,
3531 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
3532 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
3535 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3537 const char * const kwnames[] = { "dn", NULL };
3538 struct ldb_message *ret;
3539 TALLOC_CTX *mem_ctx;
3540 PyObject *pydn = NULL;
3541 PyLdbMessageObject *py_ret;
3543 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
3544 discard_const_p(char *, kwnames),
3548 mem_ctx = talloc_new(NULL);
3549 if (mem_ctx == NULL) {
3554 ret = ldb_msg_new(mem_ctx);
3556 talloc_free(mem_ctx);
3563 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
3564 talloc_free(mem_ctx);
3567 ret->dn = talloc_reference(ret, dn);
3570 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
3571 if (py_ret == NULL) {
3573 talloc_free(mem_ctx);
3577 py_ret->mem_ctx = mem_ctx;
3579 return (PyObject *)py_ret;
3582 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
3584 PyLdbMessageObject *ret;
3586 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3591 ret->mem_ctx = talloc_new(NULL);
3592 ret->msg = talloc_reference(ret->mem_ctx, msg);
3593 return (PyObject *)ret;
3596 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3598 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3599 return pyldb_Dn_FromDn(msg->dn);
3602 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3604 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3605 if (!pyldb_Dn_Check(value)) {
3606 PyErr_SetString(PyExc_TypeError, "expected dn");
3610 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3614 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
3616 return wrap_text("MessageTextWrapper", self);
3619 static PyGetSetDef py_ldb_msg_getset[] = {
3620 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
3621 { discard_const_p(char, "text"), (getter)py_ldb_msg_get_text, NULL, NULL },
3625 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3627 PyObject *dict = PyDict_New(), *ret, *repr;
3628 if (PyDict_Update(dict, (PyObject *)self) != 0)
3630 repr = PyObject_Repr(dict);
3635 ret = PyStr_FromFormat("Message(%s)", PyStr_AsUTF8(repr));
3641 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3643 talloc_free(self->mem_ctx);
3647 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3648 PyLdbMessageObject *py_msg2, int op)
3650 struct ldb_message *msg1, *msg2;
3654 if (!PyLdbMessage_Check(py_msg2)) {
3655 Py_INCREF(Py_NotImplemented);
3656 return Py_NotImplemented;
3659 msg1 = pyldb_Message_AsMessage(py_msg1),
3660 msg2 = pyldb_Message_AsMessage(py_msg2);
3662 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3663 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3665 return richcmp(ret, op);
3669 ret = msg1->num_elements - msg2->num_elements;
3671 return richcmp(ret, op);
3674 for (i = 0; i < msg1->num_elements; i++) {
3675 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3676 &msg2->elements[i]);
3678 return richcmp(ret, op);
3681 ret = ldb_msg_element_compare(&msg1->elements[i],
3682 &msg2->elements[i]);
3684 return richcmp(ret, op);
3688 return richcmp(0, op);
3691 static PyTypeObject PyLdbMessage = {
3692 .tp_name = "ldb.Message",
3693 .tp_methods = py_ldb_msg_methods,
3694 .tp_getset = py_ldb_msg_getset,
3695 .tp_as_mapping = &py_ldb_msg_mapping,
3696 .tp_basicsize = sizeof(PyLdbMessageObject),
3697 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3698 .tp_new = py_ldb_msg_new,
3699 .tp_repr = (reprfunc)py_ldb_msg_repr,
3700 .tp_flags = Py_TPFLAGS_DEFAULT,
3701 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3702 .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3703 .tp_doc = "A LDB Message",
3706 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3708 PyLdbTreeObject *ret;
3710 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3716 ret->mem_ctx = talloc_new(NULL);
3717 ret->tree = talloc_reference(ret->mem_ctx, tree);
3718 return (PyObject *)ret;
3721 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3723 talloc_free(self->mem_ctx);
3727 static PyTypeObject PyLdbTree = {
3728 .tp_name = "ldb.Tree",
3729 .tp_basicsize = sizeof(PyLdbTreeObject),
3730 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3731 .tp_flags = Py_TPFLAGS_DEFAULT,
3732 .tp_doc = "A search tree",
3736 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3738 PyObject *py_ldb = (PyObject *)mod->private_data;
3739 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3741 py_base = pyldb_Dn_FromDn(req->op.search.base);
3743 if (py_base == NULL)
3744 return LDB_ERR_OPERATIONS_ERROR;
3746 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3748 if (py_tree == NULL)
3749 return LDB_ERR_OPERATIONS_ERROR;
3751 if (req->op.search.attrs == NULL) {
3755 for (len = 0; req->op.search.attrs[len]; len++);
3756 py_attrs = PyList_New(len);
3757 for (i = 0; i < len; i++)
3758 PyList_SetItem(py_attrs, i, PyStr_FromString(req->op.search.attrs[i]));
3761 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3762 discard_const_p(char, "OiOO"),
3763 py_base, req->op.search.scope, py_tree, py_attrs);
3765 Py_DECREF(py_attrs);
3769 if (py_result == NULL) {
3770 return LDB_ERR_PYTHON_EXCEPTION;
3773 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3774 if (req->op.search.res == NULL) {
3775 return LDB_ERR_PYTHON_EXCEPTION;
3778 Py_DECREF(py_result);
3783 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3785 PyObject *py_ldb = (PyObject *)mod->private_data;
3786 PyObject *py_result, *py_msg;
3788 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3790 if (py_msg == NULL) {
3791 return LDB_ERR_OPERATIONS_ERROR;
3794 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3795 discard_const_p(char, "O"),
3800 if (py_result == NULL) {
3801 return LDB_ERR_PYTHON_EXCEPTION;
3804 Py_DECREF(py_result);
3809 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3811 PyObject *py_ldb = (PyObject *)mod->private_data;
3812 PyObject *py_result, *py_msg;
3814 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3816 if (py_msg == NULL) {
3817 return LDB_ERR_OPERATIONS_ERROR;
3820 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3821 discard_const_p(char, "O"),
3826 if (py_result == NULL) {
3827 return LDB_ERR_PYTHON_EXCEPTION;
3830 Py_DECREF(py_result);
3835 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3837 PyObject *py_ldb = (PyObject *)mod->private_data;
3838 PyObject *py_result, *py_dn;
3840 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3843 return LDB_ERR_OPERATIONS_ERROR;
3845 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3846 discard_const_p(char, "O"),
3849 if (py_result == NULL) {
3850 return LDB_ERR_PYTHON_EXCEPTION;
3853 Py_DECREF(py_result);
3858 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3860 PyObject *py_ldb = (PyObject *)mod->private_data;
3861 PyObject *py_result, *py_olddn, *py_newdn;
3863 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3865 if (py_olddn == NULL)
3866 return LDB_ERR_OPERATIONS_ERROR;
3868 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3870 if (py_newdn == NULL)
3871 return LDB_ERR_OPERATIONS_ERROR;
3873 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3874 discard_const_p(char, "OO"),
3875 py_olddn, py_newdn);
3877 Py_DECREF(py_olddn);
3878 Py_DECREF(py_newdn);
3880 if (py_result == NULL) {
3881 return LDB_ERR_PYTHON_EXCEPTION;
3884 Py_DECREF(py_result);
3889 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3891 PyObject *py_ldb = (PyObject *)mod->private_data;
3892 PyObject *py_result;
3894 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3895 discard_const_p(char, ""));
3897 Py_XDECREF(py_result);
3899 return LDB_ERR_OPERATIONS_ERROR;
3902 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3904 PyObject *py_ldb = (PyObject *)mod->private_data;
3905 PyObject *py_result;
3907 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3908 discard_const_p(char, ""));
3910 Py_XDECREF(py_result);
3912 return LDB_ERR_OPERATIONS_ERROR;
3915 static int py_module_start_transaction(struct ldb_module *mod)
3917 PyObject *py_ldb = (PyObject *)mod->private_data;
3918 PyObject *py_result;
3920 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3921 discard_const_p(char, ""));
3923 if (py_result == NULL) {
3924 return LDB_ERR_PYTHON_EXCEPTION;
3927 Py_DECREF(py_result);
3932 static int py_module_end_transaction(struct ldb_module *mod)
3934 PyObject *py_ldb = (PyObject *)mod->private_data;
3935 PyObject *py_result;
3937 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3938 discard_const_p(char, ""));
3940 if (py_result == NULL) {
3941 return LDB_ERR_PYTHON_EXCEPTION;
3944 Py_DECREF(py_result);
3949 static int py_module_del_transaction(struct ldb_module *mod)
3951 PyObject *py_ldb = (PyObject *)mod->private_data;
3952 PyObject *py_result;
3954 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3955 discard_const_p(char, ""));
3957 if (py_result == NULL) {
3958 return LDB_ERR_PYTHON_EXCEPTION;
3961 Py_DECREF(py_result);
3966 static int py_module_destructor(struct ldb_module *mod)
3968 Py_DECREF((PyObject *)mod->private_data);
3972 static int py_module_init(struct ldb_module *mod)
3974 PyObject *py_class = (PyObject *)mod->ops->private_data;
3975 PyObject *py_result, *py_next, *py_ldb;
3977 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3980 return LDB_ERR_OPERATIONS_ERROR;
3982 py_next = PyLdbModule_FromModule(mod->next);
3984 if (py_next == NULL)
3985 return LDB_ERR_OPERATIONS_ERROR;
3987 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3990 if (py_result == NULL) {
3991 return LDB_ERR_PYTHON_EXCEPTION;
3994 mod->private_data = py_result;
3996 talloc_set_destructor(mod, py_module_destructor);
3998 return ldb_next_init(mod);
4001 static PyObject *py_register_module(PyObject *module, PyObject *args)
4004 struct ldb_module_ops *ops;
4007 if (!PyArg_ParseTuple(args, "O", &input))
4010 ops = talloc_zero(NULL, struct ldb_module_ops);
4016 ops->name = talloc_strdup(ops, PyStr_AsUTF8(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
4019 ops->private_data = input;
4020 ops->init_context = py_module_init;
4021 ops->search = py_module_search;
4022 ops->add = py_module_add;
4023 ops->modify = py_module_modify;
4024 ops->del = py_module_del;
4025 ops->rename = py_module_rename;
4026 ops->request = py_module_request;
4027 ops->extended = py_module_extended;
4028 ops->start_transaction = py_module_start_transaction;
4029 ops->end_transaction = py_module_end_transaction;
4030 ops->del_transaction = py_module_del_transaction;
4032 ret = ldb_register_module(ops);
4033 if (ret != LDB_SUCCESS) {
4037 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
4042 static PyObject *py_timestring(PyObject *module, PyObject *args)
4044 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4045 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4049 if (!PyArg_ParseTuple(args, "l", &t_val))
4051 tresult = ldb_timestring(NULL, (time_t) t_val);
4052 ret = PyStr_FromString(tresult);
4053 talloc_free(tresult);
4057 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
4060 if (!PyArg_ParseTuple(args, "s", &str))
4063 return PyInt_FromLong(ldb_string_to_time(str));
4066 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4069 if (!PyArg_ParseTuple(args, "s", &name))
4071 return PyBool_FromLong(ldb_valid_attr_name(name));
4075 encode a string using RFC2254 rules
4077 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4079 char *str, *encoded;
4080 Py_ssize_t size = 0;
4084 if (!PyArg_ParseTuple(args, "s#", &str, &size))
4086 val.data = (uint8_t *)str;
4089 encoded = ldb_binary_encode(NULL, val);
4090 if (encoded == NULL) {
4091 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4094 ret = PyStr_FromString(encoded);
4095 talloc_free(encoded);
4100 decode a string using RFC2254 rules
4102 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4108 if (!PyArg_ParseTuple(args, "s", &str))
4111 val = ldb_binary_decode(NULL, str);
4112 if (val.data == NULL) {
4113 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4116 ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4117 talloc_free(val.data);
4121 static PyMethodDef py_ldb_global_methods[] = {
4122 { "register_module", py_register_module, METH_VARARGS,
4123 "S.register_module(module) -> None\n\n"
4124 "Register a LDB module."},
4125 { "timestring", py_timestring, METH_VARARGS,
4126 "S.timestring(int) -> string\n\n"
4127 "Generate a LDAP time string from a UNIX timestamp" },
4128 { "string_to_time", py_string_to_time, METH_VARARGS,
4129 "S.string_to_time(string) -> int\n\n"
4130 "Parse a LDAP time string into a UNIX timestamp." },
4131 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4132 "S.valid_attr_name(name) -> bool\n\nn"
4133 "Check whether the supplied name is a valid attribute name." },
4134 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
4135 "S.open() -> Ldb\n\n"
4136 "Open a new LDB context." },
4137 { "binary_encode", py_binary_encode, METH_VARARGS,
4138 "S.binary_encode(string) -> string\n\n"
4139 "Perform a RFC2254 binary encoding on a string" },
4140 { "binary_decode", py_binary_decode, METH_VARARGS,
4141 "S.binary_decode(string) -> string\n\n"
4142 "Perform a RFC2254 binary decode on a string" },
4146 #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."
4148 #if PY_MAJOR_VERSION >= 3
4149 static struct PyModuleDef moduledef = {
4150 PyModuleDef_HEAD_INIT,
4152 .m_doc = MODULE_DOC,
4154 .m_methods = py_ldb_global_methods,
4158 static PyObject* module_init(void)
4162 PyLdbBytesType.tp_base = &PyBytes_Type;
4163 if (PyType_Ready(&PyLdbBytesType) < 0) {
4167 if (PyType_Ready(&PyLdbDn) < 0)
4170 if (PyType_Ready(&PyLdbMessage) < 0)
4173 if (PyType_Ready(&PyLdbMessageElement) < 0)
4176 if (PyType_Ready(&PyLdb) < 0)
4179 if (PyType_Ready(&PyLdbModule) < 0)
4182 if (PyType_Ready(&PyLdbTree) < 0)
4185 if (PyType_Ready(&PyLdbResult) < 0)
4188 if (PyType_Ready(&PyLdbSearchIterator) < 0)
4191 if (PyType_Ready(&PyLdbControl) < 0)
4194 #if PY_MAJOR_VERSION >= 3
4195 m = PyModule_Create(&moduledef);
4197 m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC);
4202 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4204 ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4205 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4206 ADD_LDB_INT(SEQ_NEXT);
4207 ADD_LDB_INT(SCOPE_DEFAULT);
4208 ADD_LDB_INT(SCOPE_BASE);
4209 ADD_LDB_INT(SCOPE_ONELEVEL);
4210 ADD_LDB_INT(SCOPE_SUBTREE);
4212 ADD_LDB_INT(CHANGETYPE_NONE);
4213 ADD_LDB_INT(CHANGETYPE_ADD);
4214 ADD_LDB_INT(CHANGETYPE_DELETE);
4215 ADD_LDB_INT(CHANGETYPE_MODIFY);
4217 ADD_LDB_INT(FLAG_MOD_ADD);
4218 ADD_LDB_INT(FLAG_MOD_REPLACE);
4219 ADD_LDB_INT(FLAG_MOD_DELETE);
4221 ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4222 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4223 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4224 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4226 ADD_LDB_INT(SUCCESS);
4227 ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4228 ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4229 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4230 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4231 ADD_LDB_INT(ERR_COMPARE_FALSE);
4232 ADD_LDB_INT(ERR_COMPARE_TRUE);
4233 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4234 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4235 ADD_LDB_INT(ERR_REFERRAL);
4236 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4237 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4238 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4239 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4240 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4241 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4242 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4243 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4244 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4245 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4246 ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4247 ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4248 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4249 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4250 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4251 ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4252 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4253 ADD_LDB_INT(ERR_BUSY);
4254 ADD_LDB_INT(ERR_UNAVAILABLE);
4255 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4256 ADD_LDB_INT(ERR_LOOP_DETECT);
4257 ADD_LDB_INT(ERR_NAMING_VIOLATION);
4258 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4259 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4260 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4261 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4262 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4263 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4264 ADD_LDB_INT(ERR_OTHER);
4266 ADD_LDB_INT(FLG_RDONLY);
4267 ADD_LDB_INT(FLG_NOSYNC);
4268 ADD_LDB_INT(FLG_RECONNECT);
4269 ADD_LDB_INT(FLG_NOMMAP);
4270 ADD_LDB_INT(FLG_SHOW_BINARY);
4271 ADD_LDB_INT(FLG_ENABLE_TRACING);
4272 ADD_LDB_INT(FLG_DONT_CREATE_DB);
4275 /* Historical misspelling */
4276 PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
4278 PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
4280 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
4281 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
4284 Py_INCREF(&PyLdbDn);
4285 Py_INCREF(&PyLdbModule);
4286 Py_INCREF(&PyLdbMessage);
4287 Py_INCREF(&PyLdbMessageElement);
4288 Py_INCREF(&PyLdbTree);
4289 Py_INCREF(&PyLdbResult);
4290 Py_INCREF(&PyLdbControl);
4292 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
4293 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
4294 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
4295 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
4296 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
4297 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
4298 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
4300 PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
4302 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4304 ADD_LDB_STRING(SYNTAX_DN);
4305 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
4306 ADD_LDB_STRING(SYNTAX_INTEGER);
4307 ADD_LDB_STRING(SYNTAX_BOOLEAN);
4308 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
4309 ADD_LDB_STRING(SYNTAX_UTC_TIME);
4310 ADD_LDB_STRING(OID_COMPARATOR_AND);
4311 ADD_LDB_STRING(OID_COMPARATOR_OR);
4316 #if PY_MAJOR_VERSION >= 3
4317 PyMODINIT_FUNC PyInit_ldb(void);
4318 PyMODINIT_FUNC PyInit_ldb(void)
4320 return module_init();