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/>.
31 #include "lib/replace/system/python.h"
32 #include "ldb_private.h"
33 #include "ldb_handlers.h"
35 #include "dlinklist.h"
37 /* discard signature of 'func' in favour of 'target_sig' */
38 #define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func
40 struct py_ldb_search_iterator_reply;
47 struct ldb_request *req;
48 struct py_ldb_search_iterator_reply *next;
49 struct py_ldb_search_iterator_reply *result;
52 } PyLdbSearchIteratorObject;
54 struct py_ldb_search_iterator_reply {
55 struct py_ldb_search_iterator_reply *prev, *next;
56 PyLdbSearchIteratorObject *py_iter;
61 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
62 static PyObject *PyExc_LdbError;
64 static PyTypeObject PyLdbControl;
65 static PyTypeObject PyLdbResult;
66 static PyTypeObject PyLdbSearchIterator;
67 static PyTypeObject PyLdbMessage;
68 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
69 static PyTypeObject PyLdbModule;
70 static PyTypeObject PyLdbDn;
71 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
72 static PyTypeObject PyLdb;
73 static PyTypeObject PyLdbMessageElement;
74 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
76 static PyTypeObject PyLdbTree;
77 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
78 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
79 static struct ldb_message_element *PyObject_AsMessageElement(
83 const char *attr_name);
84 static PyTypeObject PyLdbBytesType;
86 #define PYARG_STR_UNI "es"
88 static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size)
90 PyObject* result = NULL;
91 PyObject* args = NULL;
92 args = Py_BuildValue("(y#)", msg, size);
96 result = PyLdbBytesType.tp_new(&PyLdbBytesType, args, NULL);
101 static PyObject *richcmp(int cmp_val, int op)
105 case Py_LT: ret = cmp_val < 0; break;
106 case Py_LE: ret = cmp_val <= 0; break;
107 case Py_EQ: ret = cmp_val == 0; break;
108 case Py_NE: ret = cmp_val != 0; break;
109 case Py_GT: ret = cmp_val > 0; break;
110 case Py_GE: ret = cmp_val >= 0; break;
112 Py_INCREF(Py_NotImplemented);
113 return Py_NotImplemented;
115 return PyBool_FromLong(ret);
119 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
121 if (self->data != NULL) {
122 char* control = ldb_control_to_string(self->mem_ctx, self->data);
123 if (control == NULL) {
127 return PyUnicode_FromString(control);
129 return PyUnicode_FromString("ldb control");
133 static void py_ldb_control_dealloc(PyLdbControlObject *self)
135 if (self->mem_ctx != NULL) {
136 talloc_free(self->mem_ctx);
139 Py_TYPE(self)->tp_free(self);
142 /* Create a text (rather than bytes) interface for a LDB result object */
143 static PyObject *wrap_text(const char *type, PyObject *wrapped)
145 PyObject *mod, *cls, *constructor, *inst;
146 mod = PyImport_ImportModule("_ldb_text");
149 cls = PyObject_GetAttrString(mod, type);
155 constructor = PyObject_GetAttrString(cls, "_wrap");
157 if (constructor == NULL) {
160 inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped);
161 Py_DECREF(constructor);
165 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self,
166 PyObject *Py_UNUSED(ignored))
168 return PyUnicode_FromString(self->data->oid);
171 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self,
172 PyObject *Py_UNUSED(ignored))
174 return PyBool_FromLong(self->data->critical);
177 static int py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
180 PyErr_SetString(PyExc_AttributeError, "cannot delete critical flag");
183 if (PyObject_IsTrue(value)) {
184 self->data->critical = true;
186 self->data->critical = false;
191 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
194 const char * const kwnames[] = { "ldb", "data", NULL };
195 struct ldb_control *parsed_controls;
196 PyLdbControlObject *ret;
199 struct ldb_context *ldb_ctx;
201 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
202 discard_const_p(char *, kwnames),
203 &PyLdb, &py_ldb, &data))
206 mem_ctx = talloc_new(NULL);
207 if (mem_ctx == NULL) {
212 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(py_ldb);
213 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
215 if (!parsed_controls) {
216 talloc_free(mem_ctx);
217 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
221 ret = PyObject_New(PyLdbControlObject, type);
224 talloc_free(mem_ctx);
228 ret->mem_ctx = mem_ctx;
230 ret->data = talloc_move(mem_ctx, &parsed_controls);
231 if (ret->data == NULL) {
234 talloc_free(mem_ctx);
238 return (PyObject *)ret;
241 static PyGetSetDef py_ldb_control_getset[] = {
243 .name = discard_const_p(char, "oid"),
244 .get = (getter)py_ldb_control_get_oid,
247 .name = discard_const_p(char, "critical"),
248 .get = (getter)py_ldb_control_get_critical,
249 .set = (setter)py_ldb_control_set_critical,
254 static PyTypeObject PyLdbControl = {
255 .tp_name = "ldb.control",
256 .tp_dealloc = (destructor)py_ldb_control_dealloc,
257 .tp_getattro = PyObject_GenericGetAttr,
258 .tp_basicsize = sizeof(PyLdbControlObject),
259 .tp_getset = py_ldb_control_getset,
260 .tp_doc = "LDB control.",
261 .tp_str = (reprfunc)py_ldb_control_str,
262 .tp_new = py_ldb_control_new,
263 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
266 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
268 PyObject *exc = NULL;
269 if (ret == LDB_ERR_PYTHON_EXCEPTION) {
270 return; /* Python exception should already be set, just keep that */
272 exc = Py_BuildValue("(i,s)", ret,
273 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx));
276 * Py_BuildValue failed, and will have set its own exception.
277 * It isn't the one we wanted, but it will have to do.
278 * This is all very unexpected.
280 fprintf(stderr, "could not make LdbError %d!\n", ret);
283 PyErr_SetObject(error, exc);
287 static PyObject *py_ldb_bytes_str(PyBytesObject *self)
292 if (!PyBytes_Check(self)) {
293 PyErr_Format(PyExc_TypeError,"Unexpected type");
296 result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size);
298 PyErr_Format(PyExc_TypeError, "Failed to extract bytes");
301 return PyUnicode_FromStringAndSize(msg, size);
304 static PyTypeObject PyLdbBytesType = {
305 PyVarObject_HEAD_INIT(NULL, 0)
306 .tp_name = "ldb.bytes",
307 .tp_doc = "str/bytes (with custom str)",
308 .tp_str = (reprfunc)py_ldb_bytes_str,
309 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
312 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
314 return PyLdbBytes_FromStringAndSize((const char *)val->data, val->length);
317 static PyObject *PyStr_FromLdbValue(const struct ldb_val *val)
319 return PyUnicode_FromStringAndSize((const char *)val->data, val->length);
323 * Create a Python object from a ldb_result.
325 * @param result LDB result to convert
326 * @return Python object with converted result (a list object)
328 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
330 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
331 PyLdbControlObject *ctrl;
332 if (ctl_ctx == NULL) {
337 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
339 talloc_free(ctl_ctx);
343 ctrl->mem_ctx = ctl_ctx;
344 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
345 if (ctrl->data == NULL) {
350 return (PyObject*) ctrl;
354 * Create a Python object from a ldb_result.
356 * @param result LDB result to convert
357 * @return Python object with converted result (a list object)
359 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
361 PyLdbResultObject *ret;
362 PyObject *list, *controls, *referals;
365 if (result == NULL) {
369 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
375 list = PyList_New(result->count);
382 for (i = 0; i < result->count; i++) {
383 PyObject *pymessage = PyLdbMessage_FromMessage(result->msgs[i]);
384 if (pymessage == NULL) {
389 PyList_SetItem(list, i, pymessage);
392 ret->mem_ctx = talloc_new(NULL);
393 if (ret->mem_ctx == NULL) {
402 if (result->controls) {
404 while (result->controls[i]) {
407 controls = PyList_New(i);
408 if (controls == NULL) {
414 for (i=0; result->controls[i]; i++) {
415 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
423 PyList_SetItem(controls, i, ctrl);
427 * No controls so we keep an empty list
429 controls = PyList_New(0);
430 if (controls == NULL) {
438 ret->controls = controls;
442 while (result->refs && result->refs[i]) {
446 referals = PyList_New(i);
447 if (referals == NULL) {
454 for (i = 0;result->refs && result->refs[i]; i++) {
455 PyList_SetItem(referals, i, PyUnicode_FromString(result->refs[i]));
457 ret->referals = referals;
458 return (PyObject *)ret;
462 * Create a LDB Result from a Python object.
463 * If conversion fails, NULL will be returned and a Python exception set.
465 * Note: the result object only includes the messages at the moment; extended
466 * result, controls and referrals are ignored.
468 * @param mem_ctx Memory context in which to allocate the LDB Result
469 * @param obj Python object to convert
470 * @return a ldb_result, or NULL if the conversion failed
472 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
475 struct ldb_result *res;
481 if (!PyList_Check(obj)) {
482 PyErr_SetString(PyExc_ValueError, "Expected list of LDB results");
486 res = talloc_zero(mem_ctx, struct ldb_result);
491 res->count = PyList_Size(obj);
492 res->msgs = talloc_array(res, struct ldb_message *, res->count);
493 if (res->msgs == NULL) {
498 for (i = 0; i < res->count; i++) {
499 PyObject *item = PyList_GetItem(obj, i);
504 res->msgs[i] = pyldb_Message_AsMessage(item);
509 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self,
510 PyObject *Py_UNUSED(ignored))
512 return PyBool_FromLong(ldb_dn_validate(self->dn));
515 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self,
516 PyObject *Py_UNUSED(ignored))
518 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
521 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self,
522 PyObject *Py_UNUSED(ignored))
524 return PyBool_FromLong(ldb_dn_is_special(self->dn));
527 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self,
528 PyObject *Py_UNUSED(ignored))
530 return PyBool_FromLong(ldb_dn_is_null(self->dn));
533 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self,
534 PyObject *Py_UNUSED(ignored))
536 return PyUnicode_FromString(ldb_dn_get_casefold(self->dn));
539 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self,
540 PyObject *Py_UNUSED(ignored))
542 return PyUnicode_FromString(ldb_dn_get_linearized(self->dn));
545 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self,
546 PyObject *Py_UNUSED(ignored))
548 return PyUnicode_FromString(ldb_dn_canonical_string(self->dn, self->dn));
551 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self,
552 PyObject *Py_UNUSED(ignored))
554 return PyUnicode_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
557 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
559 const char * const kwnames[] = { "mode", NULL };
561 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
562 discard_const_p(char *, kwnames),
565 return PyUnicode_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
568 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
571 const struct ldb_val *val;
573 if (!PyArg_ParseTuple(args, "s", &name))
575 val = ldb_dn_get_extended_component(self->dn, name);
580 return PyBytes_FromStringAndSize((const char *)val->data, val->length);
583 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
587 uint8_t *value = NULL;
590 if (!PyArg_ParseTuple(args, "sz#", &name, (char **)&value, &size))
594 err = ldb_dn_set_extended_component(self->dn, name, NULL);
597 val.data = (uint8_t *)value;
599 err = ldb_dn_set_extended_component(self->dn, name, &val);
602 if (err != LDB_SUCCESS) {
603 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
610 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
612 PyObject *str = PyUnicode_FromString(ldb_dn_get_linearized(self->dn));
613 PyObject *repr, *result;
616 repr = PyObject_Repr(str);
621 result = PyUnicode_FromFormat("Dn(%s)", PyUnicode_AsUTF8(repr));
627 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
631 if (!PyArg_ParseTuple(args, "s", &name))
634 return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
637 static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
640 if (!pyldb_Dn_Check(dn2)) {
641 Py_INCREF(Py_NotImplemented);
642 return Py_NotImplemented;
644 ret = ldb_dn_compare(pyldb_Dn_AS_DN(dn1), pyldb_Dn_AS_DN(dn2));
645 return richcmp(ret, op);
648 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self,
649 PyObject *Py_UNUSED(ignored))
651 struct ldb_dn *dn = pyldb_Dn_AS_DN((PyObject *)self);
652 struct ldb_dn *parent;
653 PyLdbDnObject *py_ret;
654 TALLOC_CTX *mem_ctx = NULL;
656 if (ldb_dn_get_comp_num(dn) < 1) {
660 mem_ctx = talloc_new(NULL);
661 if (mem_ctx == NULL) {
666 parent = ldb_dn_get_parent(mem_ctx, dn);
667 if (parent == NULL) {
669 talloc_free(mem_ctx);
673 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
674 if (py_ret == NULL) {
676 talloc_free(mem_ctx);
679 py_ret->mem_ctx = mem_ctx;
681 return (PyObject *)py_ret;
684 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
687 struct ldb_dn *dn, *other;
689 if (!PyArg_ParseTuple(args, "O", &py_other))
692 dn = pyldb_Dn_AS_DN((PyObject *)self);
694 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
697 ok = ldb_dn_add_child(dn, other);
699 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, NULL);
706 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
709 struct ldb_dn *other, *dn;
711 if (!PyArg_ParseTuple(args, "O", &py_other))
714 dn = pyldb_Dn_AS_DN((PyObject *)self);
716 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
719 ok = ldb_dn_add_base(dn, other);
721 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, NULL);
728 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
733 if (!PyArg_ParseTuple(args, "i", &i))
736 dn = pyldb_Dn_AS_DN((PyObject *)self);
738 ok = ldb_dn_remove_base_components(dn, i);
740 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, NULL);
747 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
750 struct ldb_dn *dn, *base;
751 if (!PyArg_ParseTuple(args, "O", &py_base))
754 dn = pyldb_Dn_AS_DN((PyObject *)self);
756 if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
759 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
762 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
766 unsigned int num = 0;
768 if (!PyArg_ParseTuple(args, "I", &num))
771 dn = pyldb_Dn_AS_DN((PyObject *)self);
773 name = ldb_dn_get_component_name(dn, num);
778 return PyUnicode_FromString(name);
781 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
784 const struct ldb_val *val;
785 unsigned int num = 0;
787 if (!PyArg_ParseTuple(args, "I", &num))
790 dn = pyldb_Dn_AS_DN((PyObject *)self);
792 val = ldb_dn_get_component_val(dn, num);
797 return PyStr_FromLdbValue(val);
800 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
802 unsigned int num = 0;
803 char *name = NULL, *value = NULL;
804 struct ldb_val val = { 0 };
808 if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size))
811 val.data = (unsigned char*) value;
814 err = ldb_dn_set_component(self->dn, num, name, val);
815 if (err != LDB_SUCCESS) {
816 PyErr_SetString(PyExc_TypeError, "Failed to set component");
823 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self,
824 PyObject *Py_UNUSED(ignored))
829 dn = pyldb_Dn_AS_DN((PyObject *)self);
831 name = ldb_dn_get_rdn_name(dn);
836 return PyUnicode_FromString(name);
839 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self,
840 PyObject *Py_UNUSED(ignored))
843 const struct ldb_val *val;
845 dn = pyldb_Dn_AS_DN((PyObject *)self);
847 val = ldb_dn_get_rdn_val(dn);
852 return PyStr_FromLdbValue(val);
855 static PyMethodDef py_ldb_dn_methods[] = {
856 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
857 "S.validate() -> bool\n"
858 "Validate DN is correct." },
859 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
860 "S.is_valid() -> bool\n" },
861 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
862 "S.is_special() -> bool\n"
863 "Check whether this is a special LDB DN." },
864 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
865 "Check whether this is a null DN." },
866 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
868 { "get_linearized", PY_DISCARD_FUNC_SIG(PyCFunction,
869 py_ldb_dn_get_linearized),
872 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
873 "S.canonical_str() -> string\n"
874 "Canonical version of this DN (like a posix path)." },
875 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
876 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
877 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
878 "S.canonical_ex_str() -> string\n"
879 "Canonical version of this DN (like a posix path, with terminating newline)." },
880 { "extended_str", PY_DISCARD_FUNC_SIG(PyCFunction,
881 py_ldb_dn_extended_str),
882 METH_VARARGS | METH_KEYWORDS,
883 "S.extended_str(mode=1) -> string\n"
884 "Extended version of this DN" },
885 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
887 "Get the parent for this DN." },
888 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
889 "S.add_child(dn) -> bool\n"
890 "Add a child DN to this DN." },
891 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
892 "S.add_base(dn) -> bool\n"
893 "Add a base DN to this DN." },
894 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
895 "S.remove_base_components(int) -> bool\n"
896 "Remove a number of DN components from the base of this DN." },
897 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
898 "S.check_special(name) -> bool\n\n"
899 "Check if name is a special DN name"},
900 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
901 "S.get_extended_component(name) -> string\n\n"
902 "returns a DN extended component as a binary string"},
903 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
904 "S.set_extended_component(name, value) -> None\n\n"
905 "set a DN extended component as a binary string"},
906 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
907 "S.get_component_name(num) -> string\n"
908 "get the attribute name of the specified component" },
909 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
910 "S.get_component_value(num) -> string\n"
911 "get the attribute value of the specified component as a binary string" },
912 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
913 "S.set_component(num, name, value) -> None\n"
914 "set the attribute name and value of the specified component" },
915 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
916 "S.get_rdn_name() -> string\n"
917 "get the RDN attribute name" },
918 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
919 "S.get_rdn_value() -> string\n"
920 "get the RDN attribute value as a binary string" },
924 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
926 return ldb_dn_get_comp_num(pyldb_Dn_AS_DN((PyObject *)self));
930 copy a DN as a python object
932 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
934 TALLOC_CTX *mem_ctx = NULL;
935 struct ldb_dn *new_dn = NULL;
936 PyLdbDnObject *py_ret;
938 mem_ctx = talloc_new(NULL);
939 if (mem_ctx == NULL) {
940 return PyErr_NoMemory();
943 new_dn = ldb_dn_copy(mem_ctx, dn);
944 if (new_dn == NULL) {
945 talloc_free(mem_ctx);
946 return PyErr_NoMemory();
949 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
950 if (py_ret == NULL) {
951 talloc_free(mem_ctx);
955 py_ret->mem_ctx = mem_ctx;
957 return (PyObject *)py_ret;
960 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
962 TALLOC_CTX *mem_ctx = NULL;
963 struct ldb_dn *dn = pyldb_Dn_AS_DN((PyObject *)self),
965 struct ldb_dn *new_dn = NULL;
966 PyLdbDnObject *py_ret;
968 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
971 mem_ctx = talloc_new(NULL);
972 if (mem_ctx == NULL) {
973 return PyErr_NoMemory();
976 new_dn = ldb_dn_copy(mem_ctx, dn);
977 if (new_dn == NULL) {
978 talloc_free(mem_ctx);
979 return PyErr_NoMemory();
982 if (!ldb_dn_add_base(new_dn, other)) {
983 PyErr_SetString(PyExc_RuntimeError, "unable to concatenate DNs");
984 talloc_free(mem_ctx);
988 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
989 if (py_ret == NULL) {
990 talloc_free(mem_ctx);
994 py_ret->mem_ctx = mem_ctx;
997 return (PyObject *)py_ret;
1000 static PySequenceMethods py_ldb_dn_seq = {
1001 .sq_length = (lenfunc)py_ldb_dn_len,
1002 .sq_concat = (binaryfunc)py_ldb_dn_concat,
1005 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1007 struct ldb_dn *ret = NULL;
1009 PyObject *py_ldb = NULL;
1010 struct ldb_context *ldb_ctx = NULL;
1011 TALLOC_CTX *mem_ctx = NULL;
1012 PyLdbDnObject *py_ret = NULL;
1013 const char * const kwnames[] = { "ldb", "dn", NULL };
1015 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!"PYARG_STR_UNI,
1016 discard_const_p(char *, kwnames),
1017 &PyLdb, &py_ldb, "utf8", &str))
1020 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(py_ldb);
1022 mem_ctx = talloc_new(NULL);
1023 if (mem_ctx == NULL) {
1028 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
1029 if (!ldb_dn_validate(ret)) {
1030 talloc_free(mem_ctx);
1031 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
1035 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
1036 if (py_ret == NULL) {
1037 talloc_free(mem_ctx);
1041 py_ret->mem_ctx = mem_ctx;
1045 PyMem_Free(discard_const_p(char, str));
1047 return (PyObject *)py_ret;
1050 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
1052 talloc_free(self->mem_ctx);
1056 static PyTypeObject PyLdbDn = {
1057 .tp_name = "ldb.Dn",
1058 .tp_methods = py_ldb_dn_methods,
1059 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
1060 .tp_repr = (reprfunc)py_ldb_dn_repr,
1061 .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp,
1062 .tp_as_sequence = &py_ldb_dn_seq,
1063 .tp_doc = "A LDB distinguished name.",
1064 .tp_new = py_ldb_dn_new,
1065 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
1066 .tp_basicsize = sizeof(PyLdbDnObject),
1067 .tp_flags = Py_TPFLAGS_DEFAULT,
1071 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
1072 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
1074 PyObject *fn = (PyObject *)context;
1075 PyObject *result = NULL;
1076 result = PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyUnicode_FromFormatV(fmt, ap));
1080 static PyObject *py_ldb_debug_func;
1082 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
1085 struct ldb_context *ldb_ctx;
1087 if (!PyArg_ParseTuple(args, "O", &cb))
1090 if (py_ldb_debug_func != NULL) {
1091 Py_DECREF(py_ldb_debug_func);
1095 /* FIXME: DECREF cb when exiting program */
1096 py_ldb_debug_func = cb;
1097 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1098 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
1099 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
1105 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
1108 if (!PyArg_ParseTuple(args, "I", &perms))
1111 ldb_set_create_perms(pyldb_Ldb_AS_LDBCONTEXT(self), perms);
1116 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
1119 if (!PyArg_ParseTuple(args, "s", &modules_dir))
1122 ldb_set_modules_dir(pyldb_Ldb_AS_LDBCONTEXT(self), modules_dir);
1127 static PyObject *py_ldb_transaction_start(PyLdbObject *self,
1128 PyObject *Py_UNUSED(ignored))
1130 struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1132 ldb_err = ldb_transaction_start(ldb_ctx);
1133 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1137 static PyObject *py_ldb_transaction_commit(PyLdbObject *self,
1138 PyObject *Py_UNUSED(ignored))
1140 struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1142 ldb_err = ldb_transaction_commit(ldb_ctx);
1143 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1147 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self,
1148 PyObject *Py_UNUSED(ignored))
1150 struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1152 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
1153 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1157 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self,
1158 PyObject *Py_UNUSED(ignored))
1160 struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1162 ldb_err = ldb_transaction_cancel(ldb_ctx);
1163 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1167 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self,
1168 PyObject *Py_UNUSED(ignored))
1170 struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1172 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
1173 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1177 static PyObject *py_ldb_repr(PyLdbObject *self)
1179 return PyUnicode_FromString("<ldb connection>");
1182 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self,
1183 PyObject *Py_UNUSED(ignored))
1185 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AS_LDBCONTEXT(self));
1188 return py_ldb_dn_copy(dn);
1192 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self,
1193 PyObject *Py_UNUSED(ignored))
1195 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AS_LDBCONTEXT(self));
1198 return py_ldb_dn_copy(dn);
1201 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self,
1202 PyObject *Py_UNUSED(ignored))
1204 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AS_LDBCONTEXT(self));
1207 return py_ldb_dn_copy(dn);
1210 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self,
1211 PyObject *Py_UNUSED(ignored))
1213 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AS_LDBCONTEXT(self));
1216 return py_ldb_dn_copy(dn);
1219 static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
1220 const char *paramname)
1224 if (!PyList_Check(list)) {
1225 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
1228 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1234 for (i = 0; i < PyList_Size(list); i++) {
1235 const char *str = NULL;
1237 PyObject *item = PyList_GetItem(list, i);
1238 if (!PyUnicode_Check(item)) {
1239 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
1243 str = PyUnicode_AsUTF8AndSize(item, &size);
1248 ret[i] = talloc_strndup(ret, str, size);
1254 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1256 const char * const kwnames[] = { "url", "flags", "options", NULL };
1258 PyObject *py_options = Py_None;
1259 const char **options;
1260 unsigned int flags = 0;
1262 struct ldb_context *ldb;
1264 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1265 discard_const_p(char *, kwnames),
1266 &url, &flags, &py_options))
1269 ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
1271 if (py_options == Py_None) {
1274 options = PyList_AsStrList(ldb, py_options, "options");
1275 if (options == NULL)
1280 ret = ldb_connect(ldb, url, flags, options);
1281 if (ret != LDB_SUCCESS) {
1282 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1283 talloc_free(options);
1287 ldb_set_flags(ldb, flags);
1290 talloc_free(options);
1294 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1296 TALLOC_CTX *mem_ctx = NULL;
1298 struct ldb_context *ldb;
1300 mem_ctx = talloc_new(NULL);
1301 if (mem_ctx == NULL) {
1302 return PyErr_NoMemory();
1305 ldb = ldb_init(mem_ctx, NULL);
1307 talloc_free(mem_ctx);
1312 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1314 talloc_free(mem_ctx);
1318 ret->mem_ctx = mem_ctx;
1321 return (PyObject *)ret;
1324 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1327 unsigned int flags = 0;
1328 PyObject *py_options = Py_None;
1330 const char **options;
1331 const char * const kwnames[] = { "url", "flags", "options", NULL };
1332 struct ldb_context *ldb_ctx;
1334 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|IO",
1335 discard_const_p(char *, kwnames),
1336 &url, &flags, &py_options))
1339 if (py_options == Py_None) {
1342 options = PyList_AsStrList(NULL, py_options, "options");
1343 if (options == NULL)
1347 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1348 ret = ldb_connect(ldb_ctx, url, flags, options);
1349 talloc_free(options);
1351 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1356 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1359 PyObject *py_controls = Py_None;
1360 struct ldb_context *ldb_ctx;
1361 struct ldb_request *req;
1362 struct ldb_control **parsed_controls;
1363 struct ldb_message *msg;
1365 TALLOC_CTX *mem_ctx;
1367 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1369 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1370 discard_const_p(char *, kwnames),
1371 &py_msg, &py_controls, &validate))
1374 mem_ctx = talloc_new(NULL);
1375 if (mem_ctx == NULL) {
1379 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1381 if (py_controls == Py_None) {
1382 parsed_controls = NULL;
1384 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1385 if (controls == NULL) {
1386 talloc_free(mem_ctx);
1389 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1390 if (controls[0] != NULL && parsed_controls == NULL) {
1391 talloc_free(mem_ctx);
1392 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, ldb_ctx);
1395 talloc_free(controls);
1398 if (!PyLdbMessage_Check(py_msg)) {
1399 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1400 talloc_free(mem_ctx);
1403 msg = pyldb_Message_AsMessage(py_msg);
1406 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1407 if (ret != LDB_SUCCESS) {
1408 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1409 talloc_free(mem_ctx);
1414 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1415 NULL, ldb_op_default_callback, NULL);
1416 if (ret != LDB_SUCCESS) {
1417 PyErr_SetString(PyExc_TypeError, "failed to build request");
1418 talloc_free(mem_ctx);
1422 /* do request and autostart a transaction */
1423 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1425 ret = ldb_transaction_start(ldb_ctx);
1426 if (ret != LDB_SUCCESS) {
1427 talloc_free(mem_ctx);
1428 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1432 ret = ldb_request(ldb_ctx, req);
1433 if (ret == LDB_SUCCESS) {
1434 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1437 if (ret == LDB_SUCCESS) {
1438 ret = ldb_transaction_commit(ldb_ctx);
1440 ldb_transaction_cancel(ldb_ctx);
1443 talloc_free(mem_ctx);
1444 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1451 * Obtain a ldb message from a Python Dictionary object.
1453 * @param mem_ctx Memory context
1454 * @param py_obj Python Dictionary object
1455 * @param ldb_ctx LDB context
1456 * @param mod_flags Flags to be set on every message element
1457 * @return ldb_message on success or NULL on failure
1459 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1461 struct ldb_context *ldb_ctx,
1462 unsigned int mod_flags)
1464 struct ldb_message *msg;
1465 unsigned int msg_pos = 0;
1466 Py_ssize_t dict_pos = 0;
1467 PyObject *key, *value;
1468 struct ldb_message_element *msg_el;
1469 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1471 msg = ldb_msg_new(mem_ctx);
1476 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1477 if (msg->elements == NULL) {
1484 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1485 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1489 if (msg->dn == NULL) {
1490 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1495 PyErr_SetString(PyExc_TypeError, "no dn set");
1500 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1501 const char *key_str = PyUnicode_AsUTF8(key);
1502 if (ldb_attr_cmp(key_str, "dn") != 0) {
1503 msg_el = PyObject_AsMessageElement(msg->elements, value,
1504 mod_flags, key_str);
1505 if (msg_el == NULL) {
1506 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1510 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1513 * PyObject_AsMessageElement might have returned a
1514 * reference to an existing MessageElement, and so left
1515 * the name and flags unchanged. Thus if those members
1516 * aren’t set, we’ll assume that the user forgot to
1519 if (msg->elements[msg_pos].name == NULL) {
1520 /* No name was set — set it now. */
1521 msg->elements[msg_pos].name = talloc_strdup(msg->elements, key_str);
1522 if (msg->elements[msg_pos].name == NULL) {
1528 if (msg->elements[msg_pos].flags == 0) {
1529 /* No flags were set — set them now. */
1530 msg->elements[msg_pos].flags = mod_flags;
1537 msg->num_elements = msg_pos;
1542 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1546 struct ldb_context *ldb_ctx;
1547 struct ldb_request *req;
1548 struct ldb_message *msg = NULL;
1549 PyObject *py_controls = Py_None;
1550 TALLOC_CTX *mem_ctx;
1551 struct ldb_control **parsed_controls;
1552 const char * const kwnames[] = { "message", "controls", NULL };
1554 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1555 discard_const_p(char *, kwnames),
1556 &py_obj, &py_controls))
1559 mem_ctx = talloc_new(NULL);
1560 if (mem_ctx == NULL) {
1564 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1566 if (py_controls == Py_None) {
1567 parsed_controls = NULL;
1569 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1570 if (controls == NULL) {
1571 talloc_free(mem_ctx);
1574 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1575 if (controls[0] != NULL && parsed_controls == NULL) {
1576 talloc_free(mem_ctx);
1577 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, ldb_ctx);
1580 talloc_free(controls);
1583 if (PyLdbMessage_Check(py_obj)) {
1584 msg = pyldb_Message_AsMessage(py_obj);
1585 } else if (PyDict_Check(py_obj)) {
1586 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1588 PyErr_SetString(PyExc_TypeError,
1589 "Dictionary or LdbMessage object expected!");
1593 /* we should have a PyErr already set */
1594 talloc_free(mem_ctx);
1598 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1599 if (ret != LDB_SUCCESS) {
1600 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1601 talloc_free(mem_ctx);
1605 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1606 NULL, ldb_op_default_callback, NULL);
1607 if (ret != LDB_SUCCESS) {
1608 PyErr_SetString(PyExc_TypeError, "failed to build request");
1609 talloc_free(mem_ctx);
1613 /* do request and autostart a transaction */
1614 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1616 ret = ldb_transaction_start(ldb_ctx);
1617 if (ret != LDB_SUCCESS) {
1618 talloc_free(mem_ctx);
1619 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1623 ret = ldb_request(ldb_ctx, req);
1624 if (ret == LDB_SUCCESS) {
1625 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1628 if (ret == LDB_SUCCESS) {
1629 ret = ldb_transaction_commit(ldb_ctx);
1631 ldb_transaction_cancel(ldb_ctx);
1634 talloc_free(mem_ctx);
1635 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1640 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1645 struct ldb_context *ldb_ctx;
1646 struct ldb_request *req;
1647 PyObject *py_controls = Py_None;
1648 TALLOC_CTX *mem_ctx;
1649 struct ldb_control **parsed_controls;
1650 const char * const kwnames[] = { "dn", "controls", NULL };
1652 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1653 discard_const_p(char *, kwnames),
1654 &py_dn, &py_controls))
1657 mem_ctx = talloc_new(NULL);
1658 if (mem_ctx == NULL) {
1662 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1664 if (py_controls == Py_None) {
1665 parsed_controls = NULL;
1667 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1668 if (controls == NULL) {
1669 talloc_free(mem_ctx);
1672 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1673 if (controls[0] != NULL && parsed_controls == NULL) {
1674 talloc_free(mem_ctx);
1675 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, ldb_ctx);
1678 talloc_free(controls);
1681 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1682 talloc_free(mem_ctx);
1686 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1687 NULL, ldb_op_default_callback, NULL);
1688 if (ret != LDB_SUCCESS) {
1689 PyErr_SetString(PyExc_TypeError, "failed to build request");
1690 talloc_free(mem_ctx);
1694 /* do request and autostart a transaction */
1695 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1697 ret = ldb_transaction_start(ldb_ctx);
1698 if (ret != LDB_SUCCESS) {
1699 talloc_free(mem_ctx);
1700 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1704 ret = ldb_request(ldb_ctx, req);
1705 if (ret == LDB_SUCCESS) {
1706 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1709 if (ret == LDB_SUCCESS) {
1710 ret = ldb_transaction_commit(ldb_ctx);
1712 ldb_transaction_cancel(ldb_ctx);
1715 talloc_free(mem_ctx);
1716 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1721 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1723 PyObject *py_dn1, *py_dn2;
1724 struct ldb_dn *dn1, *dn2;
1726 TALLOC_CTX *mem_ctx;
1727 PyObject *py_controls = Py_None;
1728 struct ldb_control **parsed_controls;
1729 struct ldb_context *ldb_ctx;
1730 struct ldb_request *req;
1731 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1733 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1735 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1736 discard_const_p(char *, kwnames),
1737 &py_dn1, &py_dn2, &py_controls))
1741 mem_ctx = talloc_new(NULL);
1742 if (mem_ctx == NULL) {
1747 if (py_controls == Py_None) {
1748 parsed_controls = NULL;
1750 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1751 if (controls == NULL) {
1752 talloc_free(mem_ctx);
1755 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1756 if (controls[0] != NULL && parsed_controls == NULL) {
1757 talloc_free(mem_ctx);
1758 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, ldb_ctx);
1761 talloc_free(controls);
1765 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1766 talloc_free(mem_ctx);
1770 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1771 talloc_free(mem_ctx);
1775 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1776 NULL, ldb_op_default_callback, NULL);
1777 if (ret != LDB_SUCCESS) {
1778 PyErr_SetString(PyExc_TypeError, "failed to build request");
1779 talloc_free(mem_ctx);
1783 /* do request and autostart a transaction */
1784 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1786 ret = ldb_transaction_start(ldb_ctx);
1787 if (ret != LDB_SUCCESS) {
1788 talloc_free(mem_ctx);
1789 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1793 ret = ldb_request(ldb_ctx, req);
1794 if (ret == LDB_SUCCESS) {
1795 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1798 if (ret == LDB_SUCCESS) {
1799 ret = ldb_transaction_commit(ldb_ctx);
1801 ldb_transaction_cancel(ldb_ctx);
1804 talloc_free(mem_ctx);
1805 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1810 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1813 if (!PyArg_ParseTuple(args, "s", &name))
1816 ldb_schema_attribute_remove(pyldb_Ldb_AS_LDBCONTEXT(self), name);
1821 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1823 char *attribute, *syntax;
1826 struct ldb_context *ldb_ctx;
1828 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1831 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1832 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1834 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1839 static PyObject *ldb_ldif_to_pyobject(struct ldb_context *ldb, struct ldb_ldif *ldif)
1841 PyObject *obj = NULL;
1842 PyObject *result = NULL;
1848 switch (ldif->changetype) {
1849 case LDB_CHANGETYPE_NONE:
1850 case LDB_CHANGETYPE_ADD:
1851 obj = PyLdbMessage_FromMessage(ldif->msg);
1853 case LDB_CHANGETYPE_MODIFY:
1854 obj = PyLdbMessage_FromMessage(ldif->msg);
1856 case LDB_CHANGETYPE_DELETE:
1857 if (ldif->msg->num_elements != 0) {
1858 PyErr_Format(PyExc_ValueError,
1859 "CHANGETYPE(DELETE) with num_elements=%u",
1860 ldif->msg->num_elements);
1863 obj = pyldb_Dn_FromDn(ldif->msg->dn);
1865 case LDB_CHANGETYPE_MODRDN: {
1866 struct ldb_dn *olddn = NULL;
1867 PyObject *olddn_obj = NULL;
1868 bool deleteoldrdn = false;
1869 PyObject *deleteoldrdn_obj = NULL;
1870 struct ldb_dn *newdn = NULL;
1871 PyObject *newdn_obj = NULL;
1874 ret = ldb_ldif_parse_modrdn(ldb,
1882 if (ret != LDB_SUCCESS) {
1883 PyErr_Format(PyExc_ValueError,
1884 "ldb_ldif_parse_modrdn() failed");
1888 olddn_obj = pyldb_Dn_FromDn(olddn);
1889 if (olddn_obj == NULL) {
1893 deleteoldrdn_obj = Py_True;
1895 deleteoldrdn_obj = Py_False;
1897 newdn_obj = pyldb_Dn_FromDn(newdn);
1898 if (newdn_obj == NULL) {
1899 deleteoldrdn_obj = NULL;
1900 Py_CLEAR(olddn_obj);
1904 obj = Py_BuildValue(discard_const_p(char, "{s:O,s:O,s:O}"),
1906 "deleteoldrdn", deleteoldrdn_obj,
1907 "newdn", newdn_obj);
1908 Py_CLEAR(olddn_obj);
1909 deleteoldrdn_obj = NULL;
1910 Py_CLEAR(newdn_obj);
1914 PyErr_Format(PyExc_NotImplementedError,
1915 "Unsupported LDB_CHANGETYPE(%u)",
1924 /* We don't want this being attached * to the 'ldb' any more */
1925 result = Py_BuildValue(discard_const_p(char, "(iO)"),
1933 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1937 struct ldb_ldif ldif;
1940 TALLOC_CTX *mem_ctx;
1942 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1945 if (!PyLdbMessage_Check(py_msg)) {
1946 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1950 ldif.msg = pyldb_Message_AsMessage(py_msg);
1951 ldif.changetype = changetype;
1953 mem_ctx = talloc_new(NULL);
1954 if (mem_ctx == NULL) {
1955 return PyErr_NoMemory();
1958 string = ldb_ldif_write_string(pyldb_Ldb_AS_LDBCONTEXT(self), mem_ctx, &ldif);
1960 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1961 talloc_free(mem_ctx);
1965 ret = PyUnicode_FromString(string);
1967 talloc_free(mem_ctx);
1972 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1974 PyObject *list, *ret;
1975 struct ldb_ldif *ldif;
1977 struct ldb_dn *last_dn = NULL;
1979 TALLOC_CTX *mem_ctx;
1981 if (!PyArg_ParseTuple(args, "s", &s))
1984 mem_ctx = talloc_new(NULL);
1989 list = PyList_New(0);
1991 talloc_free(mem_ctx);
1995 while (s && *s != '\0') {
1996 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1997 talloc_steal(mem_ctx, ldif);
2000 PyObject *py_ldif = ldb_ldif_to_pyobject(self->ldb_ctx, ldif);
2001 if (py_ldif == NULL) {
2003 if (PyErr_Occurred() == NULL) {
2004 PyErr_BadArgument();
2006 talloc_free(mem_ctx);
2009 res = PyList_Append(list, py_ldif);
2013 talloc_free(mem_ctx);
2016 last_dn = ldif->msg->dn;
2018 const char *last_dn_str = NULL;
2019 const char *err_string = NULL;
2020 if (last_dn == NULL) {
2021 PyErr_SetString(PyExc_ValueError,
2022 "unable to parse LDIF "
2023 "string at first chunk");
2025 talloc_free(mem_ctx);
2030 = ldb_dn_get_linearized(last_dn);
2033 = talloc_asprintf(mem_ctx,
2034 "unable to parse ldif "
2038 PyErr_SetString(PyExc_ValueError,
2040 talloc_free(mem_ctx);
2045 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
2046 ret = PyObject_GetIter(list);
2051 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
2054 PyObject *py_msg_old;
2055 PyObject *py_msg_new;
2056 struct ldb_message *diff;
2057 struct ldb_context *ldb;
2059 TALLOC_CTX *mem_ctx = NULL;
2061 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
2064 if (!PyLdbMessage_Check(py_msg_old)) {
2065 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
2069 if (!PyLdbMessage_Check(py_msg_new)) {
2070 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
2074 mem_ctx = talloc_new(NULL);
2075 if (mem_ctx == NULL) {
2080 ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
2081 ldb_ret = ldb_msg_difference(ldb, mem_ctx,
2082 pyldb_Message_AsMessage(py_msg_old),
2083 pyldb_Message_AsMessage(py_msg_new),
2085 if (ldb_ret != LDB_SUCCESS) {
2086 talloc_free(mem_ctx);
2087 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
2091 diff = ldb_msg_copy(mem_ctx, diff);
2093 talloc_free(mem_ctx);
2098 py_ret = PyLdbMessage_FromMessage(diff);
2100 talloc_free(mem_ctx);
2105 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
2107 const struct ldb_schema_attribute *a;
2108 struct ldb_val old_val;
2109 struct ldb_val new_val;
2110 TALLOC_CTX *mem_ctx;
2117 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
2120 result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
2121 old_val.length = size;
2124 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
2128 a = ldb_schema_attribute_by_name(pyldb_Ldb_AS_LDBCONTEXT(self), element_name);
2134 mem_ctx = talloc_new(NULL);
2135 if (mem_ctx == NULL) {
2140 if (a->syntax->ldif_write_fn(pyldb_Ldb_AS_LDBCONTEXT(self), mem_ctx, &old_val, &new_val) != 0) {
2141 talloc_free(mem_ctx);
2145 ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
2147 talloc_free(mem_ctx);
2152 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2154 PyObject *py_base = Py_None;
2155 int scope = LDB_SCOPE_DEFAULT;
2157 PyObject *py_attrs = Py_None;
2158 PyObject *py_controls = Py_None;
2159 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
2161 struct ldb_result *res;
2162 struct ldb_request *req;
2164 struct ldb_context *ldb_ctx;
2165 struct ldb_control **parsed_controls;
2166 struct ldb_dn *base;
2168 TALLOC_CTX *mem_ctx;
2170 /* type "int" rather than "enum" for "scope" is intentional */
2171 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
2172 discard_const_p(char *, kwnames),
2173 &py_base, &scope, &expr, &py_attrs, &py_controls))
2177 mem_ctx = talloc_new(NULL);
2178 if (mem_ctx == NULL) {
2182 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
2184 if (py_attrs == Py_None) {
2187 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
2188 if (attrs == NULL) {
2189 talloc_free(mem_ctx);
2194 if (py_base == Py_None) {
2195 base = ldb_get_default_basedn(ldb_ctx);
2197 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
2198 talloc_free(mem_ctx);
2203 if (py_controls == Py_None) {
2204 parsed_controls = NULL;
2206 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
2207 if (controls == NULL) {
2208 talloc_free(mem_ctx);
2211 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
2212 if (controls[0] != NULL && parsed_controls == NULL) {
2213 talloc_free(mem_ctx);
2214 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, ldb_ctx);
2217 talloc_free(controls);
2220 res = talloc_zero(mem_ctx, struct ldb_result);
2223 talloc_free(mem_ctx);
2227 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
2234 ldb_search_default_callback,
2237 if (ret != LDB_SUCCESS) {
2238 talloc_free(mem_ctx);
2239 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2243 talloc_steal(req, attrs);
2245 ret = ldb_request(ldb_ctx, req);
2247 if (ret == LDB_SUCCESS) {
2248 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
2251 if (ret != LDB_SUCCESS) {
2252 talloc_free(mem_ctx);
2253 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2257 py_ret = PyLdbResult_FromResult(res);
2259 talloc_free(mem_ctx);
2264 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
2266 if (reply->py_iter != NULL) {
2267 DLIST_REMOVE(reply->py_iter->state.next, reply);
2268 if (reply->py_iter->state.result == reply) {
2269 reply->py_iter->state.result = NULL;
2271 reply->py_iter = NULL;
2274 Py_CLEAR(reply->obj);
2279 static int py_ldb_search_iterator_callback(struct ldb_request *req,
2280 struct ldb_reply *ares)
2282 PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
2283 struct ldb_result result = { .msgs = NULL };
2284 struct py_ldb_search_iterator_reply *reply = NULL;
2287 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2290 if (ares->error != LDB_SUCCESS) {
2291 int ret = ares->error;
2293 return ldb_request_done(req, ret);
2296 reply = talloc_zero(py_iter->mem_ctx,
2297 struct py_ldb_search_iterator_reply);
2298 if (reply == NULL) {
2300 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2302 reply->py_iter = py_iter;
2303 talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
2305 switch (ares->type) {
2306 case LDB_REPLY_ENTRY:
2307 reply->obj = PyLdbMessage_FromMessage(ares->message);
2308 if (reply->obj == NULL) {
2310 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2312 DLIST_ADD_END(py_iter->state.next, reply);
2316 case LDB_REPLY_REFERRAL:
2317 reply->obj = PyUnicode_FromString(ares->referral);
2318 if (reply->obj == NULL) {
2320 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2322 DLIST_ADD_END(py_iter->state.next, reply);
2326 case LDB_REPLY_DONE:
2327 result = (struct ldb_result) { .controls = ares->controls };
2328 reply->obj = PyLdbResult_FromResult(&result);
2329 if (reply->obj == NULL) {
2331 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2333 py_iter->state.result = reply;
2335 return ldb_request_done(req, LDB_SUCCESS);
2339 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2342 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2344 PyObject *py_base = Py_None;
2345 int scope = LDB_SCOPE_DEFAULT;
2348 PyObject *py_attrs = Py_None;
2349 PyObject *py_controls = Py_None;
2350 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
2353 struct ldb_context *ldb_ctx;
2354 struct ldb_control **parsed_controls;
2355 struct ldb_dn *base;
2356 PyLdbSearchIteratorObject *py_iter;
2358 /* type "int" rather than "enum" for "scope" is intentional */
2359 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
2360 discard_const_p(char *, kwnames),
2361 &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
2364 py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
2365 if (py_iter == NULL) {
2369 py_iter->ldb = self;
2371 ZERO_STRUCT(py_iter->state);
2372 py_iter->mem_ctx = talloc_new(NULL);
2373 if (py_iter->mem_ctx == NULL) {
2379 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
2381 if (py_attrs == Py_None) {
2384 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2385 if (attrs == NULL) {
2392 if (py_base == Py_None) {
2393 base = ldb_get_default_basedn(ldb_ctx);
2395 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2402 if (py_controls == Py_None) {
2403 parsed_controls = NULL;
2405 const char **controls = NULL;
2407 controls = PyList_AsStrList(py_iter->mem_ctx,
2408 py_controls, "controls");
2409 if (controls == NULL) {
2415 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2418 if (controls[0] != NULL && parsed_controls == NULL) {
2420 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, ldb_ctx);
2423 talloc_free(controls);
2426 ret = ldb_build_search_req(&py_iter->state.req,
2435 py_ldb_search_iterator_callback,
2437 if (ret != LDB_SUCCESS) {
2439 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2443 ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2445 ret = ldb_request(ldb_ctx, py_iter->state.req);
2446 if (ret != LDB_SUCCESS) {
2448 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2452 return (PyObject *)py_iter;
2455 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2460 if (!PyArg_ParseTuple(args, "s", &name))
2463 data = ldb_get_opaque(pyldb_Ldb_AS_LDBCONTEXT(self), name);
2468 /* FIXME: More interpretation */
2473 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2478 if (!PyArg_ParseTuple(args, "sO", &name, &data))
2481 /* FIXME: More interpretation */
2483 ldb_set_opaque(pyldb_Ldb_AS_LDBCONTEXT(self), name, data);
2488 static PyObject *py_ldb_modules(PyLdbObject *self,
2489 PyObject *Py_UNUSED(ignored))
2491 struct ldb_context *ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
2492 PyObject *ret = PyList_New(0);
2493 struct ldb_module *mod;
2496 return PyErr_NoMemory();
2498 for (mod = ldb->modules; mod; mod = mod->next) {
2499 PyObject *item = PyLdbModule_FromModule(mod);
2502 PyErr_SetString(PyExc_RuntimeError,
2503 "Failed to load LdbModule");
2507 res = PyList_Append(ret, item);
2518 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2520 struct ldb_context *ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
2524 if (!PyArg_ParseTuple(args, "i", &type))
2527 /* FIXME: More interpretation */
2529 ret = ldb_sequence_number(ldb, type, &value);
2531 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2533 return PyLong_FromLongLong(value);
2536 static PyObject *py_ldb_whoami(PyLdbObject *self, PyObject *args)
2538 struct ldb_context *ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
2539 struct ldb_result *res = NULL;
2540 struct ldb_extended *ext_res = NULL;
2544 ret = ldb_extended(ldb, LDB_EXTENDED_WHOAMI_OID, NULL, &res);
2545 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2547 ext_res = res->extended;
2548 if (ext_res == NULL) {
2549 PyErr_SetString(PyExc_TypeError, "Got no exop reply");
2553 if (strcmp(ext_res->oid, LDB_EXTENDED_WHOAMI_OID) != 0) {
2554 PyErr_SetString(PyExc_TypeError, "Got wrong reply OID");
2558 len = talloc_get_size(ext_res->data);
2563 return PyUnicode_FromStringAndSize(ext_res->data, len);
2567 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2569 .read_fn = ldb_handler_copy,
2570 .write_clear_fn = ldb_handler_copy,
2571 .write_hex_fn = ldb_handler_copy,
2574 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self,
2575 PyObject *Py_UNUSED(ignored))
2577 struct ldb_context *ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
2580 ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2582 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2588 static PyMethodDef py_ldb_methods[] = {
2589 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
2590 "S.set_debug(callback) -> None\n"
2591 "Set callback for LDB debug messages.\n"
2592 "The callback should accept a debug level and debug text." },
2593 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
2594 "S.set_create_perms(mode) -> None\n"
2595 "Set mode to use when creating new LDB files." },
2596 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2597 "S.set_modules_dir(path) -> None\n"
2598 "Set path LDB should search for modules" },
2599 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
2600 "S.transaction_start() -> None\n"
2601 "Start a new transaction." },
2602 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2603 "S.transaction_prepare_commit() -> None\n"
2604 "prepare to commit a new transaction (2-stage commit)." },
2605 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
2606 "S.transaction_commit() -> None\n"
2607 "commit a new transaction." },
2608 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
2609 "S.transaction_cancel() -> None\n"
2610 "cancel a new transaction." },
2611 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
2613 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2615 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2617 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2619 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2621 { "connect", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_connect),
2622 METH_VARARGS|METH_KEYWORDS,
2623 "S.connect(url, flags=0, options=None) -> None\n"
2624 "Connect to a LDB URL." },
2625 { "modify", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_modify),
2626 METH_VARARGS|METH_KEYWORDS,
2627 "S.modify(message, controls=None, validate=False) -> None\n"
2628 "Modify an entry." },
2629 { "add", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_add),
2630 METH_VARARGS|METH_KEYWORDS,
2631 "S.add(message, controls=None) -> None\n"
2633 { "delete", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_delete),
2634 METH_VARARGS|METH_KEYWORDS,
2635 "S.delete(dn, controls=None) -> None\n"
2636 "Remove an entry." },
2637 { "rename", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_rename),
2638 METH_VARARGS|METH_KEYWORDS,
2639 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2640 "Rename an entry." },
2641 { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_search),
2642 METH_VARARGS|METH_KEYWORDS,
2643 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2644 "Search in a database.\n"
2646 ":param base: Optional base DN to search\n"
2647 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2648 ":param expression: Optional search expression\n"
2649 ":param attrs: Attributes to return (defaults to all)\n"
2650 ":param controls: Optional list of controls\n"
2651 ":return: ldb.Result object\n"
2653 { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction,
2654 py_ldb_search_iterator),
2655 METH_VARARGS|METH_KEYWORDS,
2656 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2657 "Search in a database.\n"
2659 ":param base: Optional base DN to search\n"
2660 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2661 ":param expression: Optional search expression\n"
2662 ":param attrs: Attributes to return (defaults to all)\n"
2663 ":param controls: Optional list of controls\n"
2664 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2665 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2667 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2669 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2671 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2673 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2674 "S.parse_ldif(ldif) -> iter(messages)\n"
2675 "Parse a string formatted using LDIF." },
2676 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2677 "S.write_ldif(message, changetype) -> ldif\n"
2678 "Print the message as a string formatted using LDIF." },
2679 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2680 "S.msg_diff(Message) -> Message\n"
2681 "Return an LDB Message of the difference between two Message objects." },
2682 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2683 "S.get_opaque(name) -> value\n"
2684 "Get an opaque value set on this LDB connection. \n"
2685 ":note: The returned value may not be useful in Python."
2687 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2688 "S.set_opaque(name, value) -> None\n"
2689 "Set an opaque value on this LDB connection. \n"
2690 ":note: Passing incorrect values may cause crashes." },
2691 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2692 "S.modules() -> list\n"
2693 "Return the list of modules on this LDB connection " },
2694 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2695 "S.sequence_number(type) -> value\n"
2696 "Return the value of the sequence according to the requested type" },
2698 (PyCFunction)py_ldb_whoami,
2700 "S.whoami(type) -> value\n"
2701 "Return the RFC4532 whoami string",
2703 { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2704 "S._register_test_extensions() -> None\n"
2705 "Register internal extensions used in testing" },
2709 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2711 TALLOC_CTX *mem_ctx = NULL;
2712 struct ldb_module *mod_ref = NULL;
2713 PyLdbModuleObject *ret;
2715 mem_ctx = talloc_new(NULL);
2716 if (mem_ctx == NULL) {
2717 return PyErr_NoMemory();
2720 mod_ref = talloc_reference(mem_ctx, mod);
2721 if (mod_ref == NULL) {
2722 talloc_free(mem_ctx);
2723 return PyErr_NoMemory();
2726 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2728 talloc_free(mem_ctx);
2732 ret->mem_ctx = mem_ctx;
2734 return (PyObject *)ret;
2737 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2739 struct ldb_module *mod = pyldb_Ldb_AS_LDBCONTEXT(self)->modules;
2743 return PyLdbModule_FromModule(mod);
2746 static PyGetSetDef py_ldb_getset[] = {
2748 .name = discard_const_p(char, "firstmodule"),
2749 .get = (getter)py_ldb_get_firstmodule,
2754 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2756 struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
2758 struct ldb_result *result;
2762 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2766 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2768 if (ret != LDB_SUCCESS) {
2769 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2773 count = result->count;
2775 talloc_free(result);
2778 PyErr_Format(PyExc_RuntimeError,
2779 "Searching for [%s] dn gave %u results!",
2780 ldb_dn_get_linearized(dn),
2788 static PySequenceMethods py_ldb_seq = {
2789 .sq_contains = (objobjproc)py_ldb_contains,
2792 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2794 TALLOC_CTX *mem_ctx = NULL;
2795 struct ldb_context *ldb_ctx_ref = NULL;
2798 mem_ctx = talloc_new(NULL);
2799 if (mem_ctx == NULL) {
2800 return PyErr_NoMemory();
2803 ldb_ctx_ref = talloc_reference(mem_ctx, ldb_ctx);
2804 if (ldb_ctx_ref == NULL) {
2805 talloc_free(mem_ctx);
2806 return PyErr_NoMemory();
2809 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2811 talloc_free(mem_ctx);
2815 ret->mem_ctx = mem_ctx;
2816 ret->ldb_ctx = ldb_ctx_ref;
2817 return (PyObject *)ret;
2820 static void py_ldb_dealloc(PyLdbObject *self)
2822 talloc_free(self->mem_ctx);
2823 Py_TYPE(self)->tp_free(self);
2826 static PyTypeObject PyLdb = {
2827 .tp_name = "ldb.Ldb",
2828 .tp_methods = py_ldb_methods,
2829 .tp_repr = (reprfunc)py_ldb_repr,
2830 .tp_new = py_ldb_new,
2831 .tp_init = (initproc)py_ldb_init,
2832 .tp_dealloc = (destructor)py_ldb_dealloc,
2833 .tp_getset = py_ldb_getset,
2834 .tp_getattro = PyObject_GenericGetAttr,
2835 .tp_basicsize = sizeof(PyLdbObject),
2836 .tp_doc = "Connection to a LDB database.",
2837 .tp_as_sequence = &py_ldb_seq,
2838 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2841 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2843 talloc_free(self->mem_ctx);
2844 Py_CLEAR(self->msgs);
2845 Py_CLEAR(self->referals);
2846 Py_CLEAR(self->controls);
2847 Py_TYPE(self)->tp_free(self);
2850 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2852 Py_INCREF(self->msgs);
2856 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2858 Py_INCREF(self->controls);
2859 return self->controls;
2862 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2864 Py_INCREF(self->referals);
2865 return self->referals;
2868 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2871 if (self->msgs == NULL) {
2872 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2875 size = PyList_Size(self->msgs);
2876 return PyLong_FromLong(size);
2879 static PyGetSetDef py_ldb_result_getset[] = {
2881 .name = discard_const_p(char, "controls"),
2882 .get = (getter)py_ldb_result_get_controls,
2885 .name = discard_const_p(char, "msgs"),
2886 .get = (getter)py_ldb_result_get_msgs,
2889 .name = discard_const_p(char, "referals"),
2890 .get = (getter)py_ldb_result_get_referals,
2893 .name = discard_const_p(char, "count"),
2894 .get = (getter)py_ldb_result_get_count,
2899 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2901 return PyObject_GetIter(self->msgs);
2904 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2906 return PySequence_Size(self->msgs);
2909 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2911 return PySequence_GetItem(self->msgs, idx);
2914 static PySequenceMethods py_ldb_result_seq = {
2915 .sq_length = (lenfunc)py_ldb_result_len,
2916 .sq_item = (ssizeargfunc)py_ldb_result_find,
2919 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2921 return PyUnicode_FromString("<ldb result>");
2925 static PyTypeObject PyLdbResult = {
2926 .tp_name = "ldb.Result",
2927 .tp_repr = (reprfunc)py_ldb_result_repr,
2928 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2929 .tp_iter = (getiterfunc)py_ldb_result_iter,
2930 .tp_getset = py_ldb_result_getset,
2931 .tp_getattro = PyObject_GenericGetAttr,
2932 .tp_basicsize = sizeof(PyLdbResultObject),
2933 .tp_as_sequence = &py_ldb_result_seq,
2934 .tp_doc = "LDB result.",
2935 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2938 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2940 Py_CLEAR(self->state.exception);
2941 TALLOC_FREE(self->mem_ctx);
2942 ZERO_STRUCT(self->state);
2943 Py_CLEAR(self->ldb);
2944 Py_TYPE(self)->tp_free(self);
2947 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2949 PyObject *py_ret = NULL;
2951 if (self->state.req == NULL) {
2952 PyErr_SetString(PyExc_RuntimeError,
2953 "ldb.SearchIterator request already finished");
2958 * TODO: do we want a non-blocking mode?
2959 * In future we may add an optional 'nonblocking'
2960 * argument to search_iterator().
2962 * For now we keep it simple and wait for at
2966 while (self->state.next == NULL) {
2969 if (self->state.result != NULL) {
2971 * We (already) got a final result from the server.
2973 * We stop the iteration and let
2974 * py_ldb_search_iterator_result() will deliver
2975 * the result details.
2977 TALLOC_FREE(self->state.req);
2978 PyErr_SetNone(PyExc_StopIteration);
2982 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2983 if (ret != LDB_SUCCESS) {
2984 struct ldb_context *ldb_ctx;
2985 TALLOC_FREE(self->state.req);
2986 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self->ldb);
2988 * We stop the iteration and let
2989 * py_ldb_search_iterator_result() will deliver
2992 self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2993 ret, ldb_errstring(ldb_ctx));
2994 PyErr_SetNone(PyExc_StopIteration);
2999 py_ret = self->state.next->obj;
3000 self->state.next->obj = NULL;
3001 /* no TALLOC_FREE() as self->state.next is a list */
3002 talloc_free(self->state.next);
3006 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self,
3007 PyObject *Py_UNUSED(ignored))
3009 PyObject *py_ret = NULL;
3011 if (self->state.req != NULL) {
3012 PyErr_SetString(PyExc_RuntimeError,
3013 "ldb.SearchIterator request running");
3017 if (self->state.next != NULL) {
3018 PyErr_SetString(PyExc_RuntimeError,
3019 "ldb.SearchIterator not fully consumed.");
3023 if (self->state.exception != NULL) {
3024 PyErr_SetObject(PyExc_LdbError, self->state.exception);
3025 Py_DECREF(self->state.exception);
3026 self->state.exception = NULL;
3030 if (self->state.result == NULL) {
3031 PyErr_SetString(PyExc_RuntimeError,
3032 "ldb.SearchIterator result already consumed");
3036 py_ret = self->state.result->obj;
3037 self->state.result->obj = NULL;
3038 TALLOC_FREE(self->state.result);
3042 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self,
3043 PyObject *Py_UNUSED(ignored))
3045 if (self->state.req == NULL) {
3046 PyErr_SetString(PyExc_RuntimeError,
3047 "ldb.SearchIterator request already finished");
3051 Py_CLEAR(self->state.exception);
3052 TALLOC_FREE(self->mem_ctx);
3053 ZERO_STRUCT(self->state);
3057 static PyMethodDef py_ldb_search_iterator_methods[] = {
3058 { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
3059 "S.result() -> ldb.Result (without msgs and referrals)\n" },
3060 { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
3065 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
3067 return PyUnicode_FromString("<ldb search iterator>");
3070 static PyTypeObject PyLdbSearchIterator = {
3071 .tp_name = "ldb.SearchIterator",
3072 .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
3073 .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
3074 .tp_iter = PyObject_SelfIter,
3075 .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
3076 .tp_methods = py_ldb_search_iterator_methods,
3077 .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
3078 .tp_doc = "LDB search_iterator.",
3079 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
3082 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
3084 return PyUnicode_FromFormat("<ldb module '%s'>",
3085 pyldb_Module_AsModule(self)->ops->name);
3088 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
3090 return PyUnicode_FromString(pyldb_Module_AsModule(self)->ops->name);
3093 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self,
3094 PyObject *Py_UNUSED(ignored))
3096 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
3100 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self,
3101 PyObject *Py_UNUSED(ignored))
3103 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
3107 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self,
3108 PyObject *Py_UNUSED(ignored))
3110 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
3114 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
3116 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
3118 struct ldb_request *req;
3119 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
3120 struct ldb_module *mod;
3121 const char * const*attrs;
3123 /* type "int" rather than "enum" for "scope" is intentional */
3124 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
3125 discard_const_p(char *, kwnames),
3126 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
3131 if (py_attrs == Py_None) {
3134 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
3139 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AS_DN(py_base),
3140 scope, NULL /* expr */, attrs,
3141 NULL /* controls */, NULL, NULL, NULL);
3143 talloc_steal(req, attrs);
3145 PyErr_LDB_ERROR_IS_ERR_RAISE_FREE(PyExc_LdbError, ret, mod->ldb, req);
3147 req->op.search.res = NULL;
3149 ret = mod->ops->search(mod, req);
3151 PyErr_LDB_ERROR_IS_ERR_RAISE_FREE(PyExc_LdbError, ret, mod->ldb, req);
3153 py_ret = PyLdbResult_FromResult(req->op.search.res);
3161 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
3163 struct ldb_request *req;
3164 PyObject *py_message;
3166 struct ldb_module *mod;
3168 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
3171 req = talloc_zero(NULL, struct ldb_request);
3176 req->operation = LDB_ADD;
3177 req->op.add.message = pyldb_Message_AsMessage(py_message);
3179 mod = pyldb_Module_AsModule(self);
3180 ret = mod->ops->add(mod, req);
3182 PyErr_LDB_ERROR_IS_ERR_RAISE_FREE(PyExc_LdbError, ret, mod->ldb, req);
3188 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
3191 struct ldb_request *req;
3192 PyObject *py_message;
3193 struct ldb_module *mod;
3195 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
3198 req = talloc_zero(NULL, struct ldb_request);
3204 req->operation = LDB_MODIFY;
3205 req->op.mod.message = pyldb_Message_AsMessage(py_message);
3207 mod = pyldb_Module_AsModule(self);
3208 ret = mod->ops->modify(mod, req);
3210 PyErr_LDB_ERROR_IS_ERR_RAISE_FREE(PyExc_LdbError, ret, mod->ldb, req);
3216 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
3219 struct ldb_request *req;
3222 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
3225 req = talloc_zero(NULL, struct ldb_request);
3230 req->operation = LDB_DELETE;
3231 req->op.del.dn = pyldb_Dn_AS_DN(py_dn);
3233 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
3235 PyErr_LDB_ERROR_IS_ERR_RAISE_FREE(PyExc_LdbError, ret, NULL, req);
3242 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
3245 struct ldb_request *req;
3246 PyObject *py_dn1, *py_dn2;
3248 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
3251 req = talloc_zero(NULL, struct ldb_request);
3257 req->operation = LDB_RENAME;
3258 req->op.rename.olddn = pyldb_Dn_AS_DN(py_dn1);
3259 req->op.rename.newdn = pyldb_Dn_AS_DN(py_dn2);
3261 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
3263 PyErr_LDB_ERROR_IS_ERR_RAISE_FREE(PyExc_LdbError, ret, NULL, req);
3270 static PyMethodDef py_ldb_module_methods[] = {
3271 { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_module_search),
3272 METH_VARARGS|METH_KEYWORDS, NULL },
3273 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
3274 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
3275 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
3276 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
3277 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
3278 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
3279 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
3283 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
3285 talloc_free(self->mem_ctx);
3289 static PyTypeObject PyLdbModule = {
3290 .tp_name = "ldb.LdbModule",
3291 .tp_methods = py_ldb_module_methods,
3292 .tp_repr = (reprfunc)py_ldb_module_repr,
3293 .tp_str = (reprfunc)py_ldb_module_str,
3294 .tp_basicsize = sizeof(PyLdbModuleObject),
3295 .tp_dealloc = (destructor)py_ldb_module_dealloc,
3296 .tp_flags = Py_TPFLAGS_DEFAULT,
3297 .tp_doc = "LDB module (extension)",
3302 * Create a ldb_message_element from a Python object.
3304 * This will accept any sequence objects that contains strings, or
3307 * A reference to set_obj might be borrowed.
3309 * @param mem_ctx Memory context
3310 * @param set_obj Python object to convert
3311 * @param flags ldb_message_element flags to set, if a new element is returned
3312 * @param attr_name Name of the attribute to set, if a new element is returned
3313 * @return New ldb_message_element, allocated as child of mem_ctx
3315 static struct ldb_message_element *PyObject_AsMessageElement(
3316 TALLOC_CTX *mem_ctx,
3319 const char *attr_name)
3321 struct ldb_message_element *me;
3322 const char *msg = NULL;
3326 if (pyldb_MessageElement_Check(set_obj)) {
3327 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
3328 /* We have to talloc_reference() the memory context, not the pointer
3329 * which may not actually be it's own context */
3330 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
3331 return pyldb_MessageElement_AsMessageElement(set_obj);
3336 me = talloc(mem_ctx, struct ldb_message_element);
3342 me->name = talloc_strdup(me, attr_name);
3343 if (me->name == NULL) {
3349 if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) {
3351 me->values = talloc_array(me, struct ldb_val, me->num_values);
3352 if (PyBytes_Check(set_obj)) {
3354 result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
3361 msg = PyUnicode_AsUTF8AndSize(set_obj, &size);
3367 me->values[0].data = talloc_memdup(me,
3368 (const uint8_t *)msg,
3370 me->values[0].length = size;
3371 } else if (PySequence_Check(set_obj)) {
3373 me->num_values = PySequence_Size(set_obj);
3374 me->values = talloc_array(me, struct ldb_val, me->num_values);
3375 for (i = 0; i < me->num_values; i++) {
3376 PyObject *obj = PySequence_GetItem(set_obj, i);
3377 if (PyBytes_Check(obj)) {
3379 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
3385 } else if (PyUnicode_Check(obj)) {
3386 msg = PyUnicode_AsUTF8AndSize(obj, &size);
3392 PyErr_Format(PyExc_TypeError,
3393 "Expected string as element %zd in list", i);
3397 me->values[i].data = talloc_memdup(me,
3398 (const uint8_t *)msg,
3400 me->values[i].length = size;
3403 PyErr_Format(PyExc_TypeError,
3404 "String or List type expected for '%s' attribute", attr_name);
3413 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
3414 struct ldb_message_element *me)
3419 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3420 result = PyList_New(me->num_values);
3421 if (result == NULL) {
3425 for (i = 0; i < me->num_values; i++) {
3426 PyObject *obj = NULL;
3429 obj = PyObject_FromLdbValue(&me->values[i]);
3435 ret = PyList_SetItem(result, i, obj);
3446 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
3449 if (!PyArg_ParseTuple(args, "I", &i))
3451 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
3454 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
3457 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
3459 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3460 return PyLong_FromLong(el->flags);
3463 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
3466 struct ldb_message_element *el;
3467 if (!PyArg_ParseTuple(args, "I", &flags))
3470 el = pyldb_MessageElement_AsMessageElement(self);
3475 static PyMethodDef py_ldb_msg_element_methods[] = {
3476 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
3477 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
3478 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
3482 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
3484 return pyldb_MessageElement_AsMessageElement(self)->num_values;
3487 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
3489 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3490 if (idx < 0 || idx >= el->num_values) {
3491 PyErr_SetString(PyExc_IndexError, "Out of range");
3494 return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
3497 static PySequenceMethods py_ldb_msg_element_seq = {
3498 .sq_length = (lenfunc)py_ldb_msg_element_len,
3499 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
3502 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3505 if (!pyldb_MessageElement_Check(other)) {
3506 Py_INCREF(Py_NotImplemented);
3507 return Py_NotImplemented;
3509 ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3510 pyldb_MessageElement_AsMessageElement(other));
3511 return richcmp(ret, op);
3514 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3516 PyObject *el = ldb_msg_element_to_set(NULL,
3517 pyldb_MessageElement_AsMessageElement(self));
3518 PyObject *ret = PyObject_GetIter(el);
3523 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3525 TALLOC_CTX *ret_mem_ctx = NULL;
3526 PyLdbMessageElementObject *ret;
3528 ret_mem_ctx = talloc_new(NULL);
3529 if (ret_mem_ctx == NULL) {
3530 return PyErr_NoMemory();
3533 if (talloc_reference(ret_mem_ctx, mem_ctx) == NULL) {
3534 talloc_free(ret_mem_ctx);
3539 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3541 talloc_free(ret_mem_ctx);
3545 ret->mem_ctx = ret_mem_ctx;
3547 return (PyObject *)ret;
3550 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3552 PyObject *py_elements = NULL;
3553 struct ldb_message_element *el;
3554 unsigned int flags = 0;
3556 const char * const kwnames[] = { "elements", "flags", "name", NULL };
3557 PyLdbMessageElementObject *ret;
3558 TALLOC_CTX *mem_ctx;
3559 const char *msg = NULL;
3563 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3564 discard_const_p(char *, kwnames),
3565 &py_elements, &flags, &name))
3568 mem_ctx = talloc_new(NULL);
3569 if (mem_ctx == NULL) {
3574 el = talloc_zero(mem_ctx, struct ldb_message_element);
3577 talloc_free(mem_ctx);
3581 if (py_elements != NULL) {
3583 if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) {
3586 el->values = talloc_array(el, struct ldb_val, 1);
3587 if (el->values == NULL) {
3588 talloc_free(mem_ctx);
3592 if (PyBytes_Check(py_elements)) {
3593 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3596 msg = PyUnicode_AsUTF8AndSize(py_elements, &size);
3597 result = (msg == NULL) ? -1 : 0;
3600 talloc_free(mem_ctx);
3603 el->values[0].data = talloc_memdup(el->values,
3604 (const uint8_t *)msg, size + 1);
3605 el->values[0].length = size;
3606 } else if (PySequence_Check(py_elements)) {
3607 el->num_values = PySequence_Size(py_elements);
3608 el->values = talloc_array(el, struct ldb_val, el->num_values);
3609 if (el->values == NULL) {
3610 talloc_free(mem_ctx);
3614 for (i = 0; i < el->num_values; i++) {
3615 PyObject *item = PySequence_GetItem(py_elements, i);
3617 talloc_free(mem_ctx);
3620 if (PyBytes_Check(item)) {
3622 result = PyBytes_AsStringAndSize(item, &_msg, &size);
3624 } else if (PyUnicode_Check(item)) {
3625 msg = PyUnicode_AsUTF8AndSize(item, &size);
3626 result = (msg == NULL) ? -1 : 0;
3628 PyErr_Format(PyExc_TypeError,
3629 "Expected string as element %zd in list", i);
3633 talloc_free(mem_ctx);
3636 el->values[i].data = talloc_memdup(el,
3637 (const uint8_t *)msg, size+1);
3638 el->values[i].length = size;
3641 PyErr_SetString(PyExc_TypeError,
3642 "Expected string or list");
3643 talloc_free(mem_ctx);
3650 el->name = talloc_strdup(el, name);
3651 if (el->name == NULL) {
3652 talloc_free(mem_ctx);
3653 return PyErr_NoMemory();
3657 ret = PyObject_New(PyLdbMessageElementObject, type);
3659 talloc_free(mem_ctx);
3663 ret->mem_ctx = mem_ctx;
3665 return (PyObject *)ret;
3668 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3670 char *element_str = NULL;
3672 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3673 PyObject *ret, *repr;
3675 for (i = 0; i < el->num_values; i++) {
3676 PyObject *o = py_ldb_msg_element_find(self, i);
3677 repr = PyObject_Repr(o);
3678 if (element_str == NULL)
3679 element_str = talloc_strdup(NULL, PyUnicode_AsUTF8(repr));
3681 element_str = talloc_asprintf_append(element_str, ",%s", PyUnicode_AsUTF8(repr));
3684 if (element_str == NULL) {
3685 return PyErr_NoMemory();
3689 if (element_str != NULL) {
3690 ret = PyUnicode_FromFormat("MessageElement([%s])", element_str);
3691 talloc_free(element_str);
3693 ret = PyUnicode_FromString("MessageElement([])");
3699 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3701 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3703 if (el->num_values == 1)
3704 return PyUnicode_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3709 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3711 talloc_free(self->mem_ctx);
3715 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3717 return wrap_text("MessageElementTextWrapper", self);
3720 static PyGetSetDef py_ldb_msg_element_getset[] = {
3722 .name = discard_const_p(char, "text"),
3723 .get = (getter)py_ldb_msg_element_get_text,
3728 static PyTypeObject PyLdbMessageElement = {
3729 .tp_name = "ldb.MessageElement",
3730 .tp_basicsize = sizeof(PyLdbMessageElementObject),
3731 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3732 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3733 .tp_str = (reprfunc)py_ldb_msg_element_str,
3734 .tp_methods = py_ldb_msg_element_methods,
3735 .tp_getset = py_ldb_msg_element_getset,
3736 .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3737 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3738 .tp_as_sequence = &py_ldb_msg_element_seq,
3739 .tp_new = py_ldb_msg_element_new,
3740 .tp_flags = Py_TPFLAGS_DEFAULT,
3741 .tp_doc = "An element of a Message",
3745 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3750 struct ldb_message *msg;
3751 struct ldb_context *ldb_ctx;
3752 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3754 if (!PyArg_ParseTuple(args, "O!O!|I",
3755 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3760 /* mask only flags we are going to use */
3761 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3763 PyErr_SetString(PyExc_ValueError,
3764 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3765 " expected as mod_flag value");
3769 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(py_ldb);
3771 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3776 py_ret = PyLdbMessage_FromMessage(msg);
3778 talloc_unlink(ldb_ctx, msg);
3783 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3786 if (!PyArg_ParseTuple(args, "s", &name))
3789 ldb_msg_remove_attr(self->msg, name);
3794 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self,
3795 PyObject *Py_UNUSED(ignored))
3797 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3798 Py_ssize_t i, j = 0;
3799 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3804 if (msg->dn != NULL) {
3805 PyObject *py_dn = NULL;
3808 py_dn = PyUnicode_FromString("dn");
3809 if (py_dn == NULL) {
3814 ret = PyList_SetItem(obj, j, py_dn);
3823 for (i = 0; i < msg->num_elements; i++) {
3824 PyObject *py_name = NULL;
3827 py_name = PyUnicode_FromString(msg->elements[i].name);
3828 if (py_name == NULL) {
3833 ret = PyList_SetItem(obj, j, py_name);
3845 static int py_ldb_msg_contains(PyLdbMessageObject *self, PyObject *py_name)
3847 struct ldb_message_element *el = NULL;
3848 const char *name = NULL;
3849 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3850 name = PyUnicode_AsUTF8(py_name);
3854 if (!ldb_attr_cmp(name, "dn")) {
3857 el = ldb_msg_find_element(msg, name);
3858 return el != NULL ? 1 : 0;
3861 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3863 struct ldb_message_element *el = NULL;
3864 const char *name = NULL;
3865 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3866 name = PyUnicode_AsUTF8(py_name);
3870 if (!ldb_attr_cmp(name, "dn")) {
3871 return pyldb_Dn_FromDn(msg->dn);
3873 el = ldb_msg_find_element(msg, name);
3875 PyErr_SetString(PyExc_KeyError, "No such element");
3879 return PyLdbMessageElement_FromMessageElement(el, msg->elements);
3882 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3884 PyObject *def = NULL;
3885 const char *kwnames[] = { "name", "default", "idx", NULL };
3886 const char *name = NULL;
3888 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3889 struct ldb_message_element *el;
3891 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3892 discard_const_p(char *, kwnames), &name, &def, &idx)) {
3896 if (strcasecmp(name, "dn") == 0) {
3897 return pyldb_Dn_FromDn(msg->dn);
3900 el = ldb_msg_find_element(msg, name);
3902 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3911 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3914 return PyObject_FromLdbValue(&el->values[idx]);
3917 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self,
3918 PyObject *Py_UNUSED(ignored))
3920 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3921 Py_ssize_t i, j = 0;
3922 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3924 return PyErr_NoMemory();
3926 if (msg->dn != NULL) {
3927 PyObject *value = NULL;
3928 PyObject *obj = pyldb_Dn_FromDn(msg->dn);
3930 value = Py_BuildValue("(sO)", "dn", obj);
3932 if (value == NULL) {
3936 res = PyList_SetItem(l, 0, value);
3943 for (i = 0; i < msg->num_elements; i++, j++) {
3944 PyObject *value = NULL;
3945 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3947 value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3949 if (value == NULL ) {
3953 res = PyList_SetItem(l, j, value);
3962 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self,
3963 PyObject *Py_UNUSED(ignored))
3965 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3967 PyObject *l = PyList_New(msg->num_elements);
3971 for (i = 0; i < msg->num_elements; i++) {
3972 PyObject *msg_el = NULL;
3975 msg_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3976 if (msg_el == NULL) {
3981 ret = PyList_SetItem(l, i, msg_el);
3991 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3993 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3994 PyLdbMessageElementObject *py_element;
3996 struct ldb_message_element *el;
3997 struct ldb_message_element *el_new;
3999 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
4002 el = py_element->el;
4004 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
4007 if (el->name == NULL) {
4008 PyErr_SetString(PyExc_ValueError,
4009 "The element has no name");
4012 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
4013 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
4015 /* now deep copy all attribute values */
4016 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
4017 if (el_new->values == NULL) {
4021 el_new->num_values = el->num_values;
4023 for (i = 0; i < el->num_values; i++) {
4024 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
4025 if (el_new->values[i].data == NULL
4026 && el->values[i].length != 0) {
4035 static PyMethodDef py_ldb_msg_methods[] = {
4036 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
4037 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
4038 "Class method to create ldb.Message object from Dictionary.\n"
4039 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
4040 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
4041 "S.keys() -> list\n\n"
4042 "Return sequence of all attribute names." },
4043 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
4044 "S.remove(name)\n\n"
4045 "Remove all entries for attributes with the specified name."},
4046 { "get", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_msg_get),
4047 METH_VARARGS | METH_KEYWORDS,
4048 "msg.get(name,default=None,idx=None) -> string\n"
4049 "idx is the index into the values array\n"
4050 "if idx is None, then a list is returned\n"
4051 "if idx is not None, then the element with that index is returned\n"
4052 "if you pass the special name 'dn' then the DN object is returned\n"},
4053 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
4054 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
4055 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
4056 "S.add(element)\n\n"
4057 "Add an element to this message." },
4061 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
4063 PyObject *list, *iter;
4065 list = py_ldb_msg_keys(self, NULL);
4066 iter = PyObject_GetIter(list);
4071 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
4073 const char *attr_name;
4075 attr_name = PyUnicode_AsUTF8(name);
4076 if (attr_name == NULL) {
4077 PyErr_SetNone(PyExc_TypeError);
4081 if (value == NULL) {
4083 ldb_msg_remove_attr(self->msg, attr_name);
4086 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
4087 value, 0, attr_name);
4091 if (el->name == NULL) {
4093 * If ‘value’ is a MessageElement,
4094 * PyObject_AsMessageElement() will have returned a
4095 * reference to it without setting the name. We don’t
4096 * want to modify the original object to set the name
4097 * ourselves, but making a copy would result in
4098 * different behaviour for a caller relying on a
4099 * reference being kept. Rather than continue with a
4100 * NULL name (and probably fail later on), let’s catch
4101 * this potential mistake early.
4103 PyErr_SetString(PyExc_ValueError, "MessageElement has no name set");
4104 talloc_unlink(self->msg, el);
4107 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
4108 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
4109 if (ret != LDB_SUCCESS) {
4110 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
4111 talloc_unlink(self->msg, el);
4118 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
4120 return pyldb_Message_AsMessage(self)->num_elements;
4123 static PySequenceMethods py_ldb_msg_sequence = {
4124 .sq_contains = (objobjproc)py_ldb_msg_contains,
4127 static PyMappingMethods py_ldb_msg_mapping = {
4128 .mp_length = (lenfunc)py_ldb_msg_length,
4129 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
4130 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
4133 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
4135 const char * const kwnames[] = { "dn", NULL };
4136 struct ldb_message *ret;
4137 TALLOC_CTX *mem_ctx;
4138 PyObject *pydn = NULL;
4139 PyLdbMessageObject *py_ret;
4141 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
4142 discard_const_p(char *, kwnames),
4146 mem_ctx = talloc_new(NULL);
4147 if (mem_ctx == NULL) {
4152 ret = ldb_msg_new(mem_ctx);
4154 talloc_free(mem_ctx);
4161 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
4162 talloc_free(mem_ctx);
4165 ret->dn = talloc_reference(ret, dn);
4166 if (ret->dn == NULL) {
4167 talloc_free(mem_ctx);
4168 return PyErr_NoMemory();
4172 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
4173 if (py_ret == NULL) {
4175 talloc_free(mem_ctx);
4179 py_ret->mem_ctx = mem_ctx;
4181 return (PyObject *)py_ret;
4184 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
4186 TALLOC_CTX *mem_ctx = NULL;
4187 struct ldb_message *msg_ref = NULL;
4188 PyLdbMessageObject *ret;
4190 mem_ctx = talloc_new(NULL);
4191 if (mem_ctx == NULL) {
4192 return PyErr_NoMemory();
4195 msg_ref = talloc_reference(mem_ctx, msg);
4196 if (msg_ref == NULL) {
4197 talloc_free(mem_ctx);
4198 return PyErr_NoMemory();
4201 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
4203 talloc_free(mem_ctx);
4207 ret->mem_ctx = mem_ctx;
4209 return (PyObject *)ret;
4212 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
4214 struct ldb_message *msg = pyldb_Message_AsMessage(self);
4215 return pyldb_Dn_FromDn(msg->dn);
4218 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
4220 struct ldb_message *msg = pyldb_Message_AsMessage(self);
4221 struct ldb_dn *dn = NULL;
4222 if (value == NULL) {
4223 PyErr_SetString(PyExc_AttributeError, "cannot delete dn");
4226 if (!pyldb_Dn_Check(value)) {
4227 PyErr_SetString(PyExc_TypeError, "expected dn");
4231 dn = talloc_reference(msg, pyldb_Dn_AS_DN(value));
4241 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
4243 return wrap_text("MessageTextWrapper", self);
4246 static PyGetSetDef py_ldb_msg_getset[] = {
4248 .name = discard_const_p(char, "dn"),
4249 .get = (getter)py_ldb_msg_get_dn,
4250 .set = (setter)py_ldb_msg_set_dn,
4253 .name = discard_const_p(char, "text"),
4254 .get = (getter)py_ldb_msg_get_text,
4259 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
4261 PyObject *dict = PyDict_New(), *ret, *repr;
4262 const char *repr_str = NULL;
4266 if (PyDict_Update(dict, (PyObject *)self) != 0) {
4270 repr = PyObject_Repr(dict);
4275 repr_str = PyUnicode_AsUTF8(repr);
4276 if (repr_str == NULL) {
4281 ret = PyUnicode_FromFormat("Message(%s)", repr_str);
4287 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
4289 talloc_free(self->mem_ctx);
4293 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
4294 PyLdbMessageObject *py_msg2, int op)
4296 struct ldb_message *msg1, *msg2;
4300 if (!PyLdbMessage_Check(py_msg2)) {
4301 Py_INCREF(Py_NotImplemented);
4302 return Py_NotImplemented;
4305 msg1 = pyldb_Message_AsMessage(py_msg1),
4306 msg2 = pyldb_Message_AsMessage(py_msg2);
4308 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
4309 ret = ldb_dn_compare(msg1->dn, msg2->dn);
4311 return richcmp(ret, op);
4315 ret = msg1->num_elements - msg2->num_elements;
4317 return richcmp(ret, op);
4320 for (i = 0; i < msg1->num_elements; i++) {
4321 ret = ldb_msg_element_compare_name(&msg1->elements[i],
4322 &msg2->elements[i]);
4324 return richcmp(ret, op);
4327 ret = ldb_msg_element_compare(&msg1->elements[i],
4328 &msg2->elements[i]);
4330 return richcmp(ret, op);
4334 return richcmp(0, op);
4337 static PyTypeObject PyLdbMessage = {
4338 .tp_name = "ldb.Message",
4339 .tp_methods = py_ldb_msg_methods,
4340 .tp_getset = py_ldb_msg_getset,
4341 .tp_as_sequence = &py_ldb_msg_sequence,
4342 .tp_as_mapping = &py_ldb_msg_mapping,
4343 .tp_basicsize = sizeof(PyLdbMessageObject),
4344 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
4345 .tp_new = py_ldb_msg_new,
4346 .tp_repr = (reprfunc)py_ldb_msg_repr,
4347 .tp_flags = Py_TPFLAGS_DEFAULT,
4348 .tp_iter = (getiterfunc)py_ldb_msg_iter,
4349 .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
4350 .tp_doc = "A LDB Message",
4353 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
4355 TALLOC_CTX *mem_ctx = NULL;
4356 struct ldb_parse_tree *tree_ref = NULL;
4357 PyLdbTreeObject *ret;
4359 mem_ctx = talloc_new(NULL);
4360 if (mem_ctx == NULL) {
4361 return PyErr_NoMemory();
4364 tree_ref = talloc_reference(mem_ctx, tree);
4365 if (tree_ref == NULL) {
4366 talloc_free(mem_ctx);
4367 return PyErr_NoMemory();
4370 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
4372 talloc_free(mem_ctx);
4377 ret->mem_ctx = mem_ctx;
4378 ret->tree = tree_ref;
4379 return (PyObject *)ret;
4382 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
4384 talloc_free(self->mem_ctx);
4388 static PyTypeObject PyLdbTree = {
4389 .tp_name = "ldb.Tree",
4390 .tp_basicsize = sizeof(PyLdbTreeObject),
4391 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
4392 .tp_flags = Py_TPFLAGS_DEFAULT,
4393 .tp_doc = "A search tree",
4397 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
4399 PyObject *py_ldb = (PyObject *)mod->private_data;
4400 PyObject *py_result, *py_base, *py_attrs, *py_tree;
4402 py_base = pyldb_Dn_FromDn(req->op.search.base);
4404 if (py_base == NULL)
4405 return LDB_ERR_OPERATIONS_ERROR;
4407 py_tree = PyLdbTree_FromTree(req->op.search.tree);
4409 if (py_tree == NULL) {
4411 return LDB_ERR_OPERATIONS_ERROR;
4414 if (req->op.search.attrs == NULL) {
4418 for (len = 0; req->op.search.attrs[len]; len++);
4419 py_attrs = PyList_New(len);
4420 if (py_attrs == NULL) {
4423 return LDB_ERR_OPERATIONS_ERROR;
4425 for (i = 0; i < len; i++) {
4426 PyObject *py_attr = NULL;
4429 py_attr = PyUnicode_FromString(req->op.search.attrs[i]);
4430 if (py_attr == NULL) {
4433 Py_DECREF(py_attrs);
4434 return LDB_ERR_OPERATIONS_ERROR;
4437 ret = PyList_SetItem(py_attrs, i, py_attr);
4442 Py_DECREF(py_attrs);
4443 return LDB_ERR_OPERATIONS_ERROR;
4448 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
4449 discard_const_p(char, "OiOO"),
4450 py_base, req->op.search.scope, py_tree, py_attrs);
4452 Py_DECREF(py_attrs);
4456 if (py_result == NULL) {
4457 return LDB_ERR_PYTHON_EXCEPTION;
4460 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
4461 if (req->op.search.res == NULL) {
4462 Py_DECREF(py_result);
4463 return LDB_ERR_PYTHON_EXCEPTION;
4466 Py_DECREF(py_result);
4471 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
4473 PyObject *py_ldb = (PyObject *)mod->private_data;
4474 PyObject *py_result, *py_msg;
4476 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
4478 if (py_msg == NULL) {
4479 return LDB_ERR_OPERATIONS_ERROR;
4482 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
4483 discard_const_p(char, "O"),
4488 if (py_result == NULL) {
4489 return LDB_ERR_PYTHON_EXCEPTION;
4492 Py_DECREF(py_result);
4497 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
4499 PyObject *py_ldb = (PyObject *)mod->private_data;
4500 PyObject *py_result, *py_msg;
4502 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
4504 if (py_msg == NULL) {
4505 return LDB_ERR_OPERATIONS_ERROR;
4508 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
4509 discard_const_p(char, "O"),
4514 if (py_result == NULL) {
4515 return LDB_ERR_PYTHON_EXCEPTION;
4518 Py_DECREF(py_result);
4523 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
4525 PyObject *py_ldb = (PyObject *)mod->private_data;
4526 PyObject *py_result, *py_dn;
4528 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
4531 return LDB_ERR_OPERATIONS_ERROR;
4533 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
4534 discard_const_p(char, "O"),
4538 if (py_result == NULL) {
4539 return LDB_ERR_PYTHON_EXCEPTION;
4542 Py_DECREF(py_result);
4547 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
4549 PyObject *py_ldb = (PyObject *)mod->private_data;
4550 PyObject *py_result, *py_olddn, *py_newdn;
4552 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
4554 if (py_olddn == NULL)
4555 return LDB_ERR_OPERATIONS_ERROR;
4557 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
4559 if (py_newdn == NULL) {
4560 Py_DECREF(py_olddn);
4561 return LDB_ERR_OPERATIONS_ERROR;
4564 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
4565 discard_const_p(char, "OO"),
4566 py_olddn, py_newdn);
4568 Py_DECREF(py_olddn);
4569 Py_DECREF(py_newdn);
4571 if (py_result == NULL) {
4572 return LDB_ERR_PYTHON_EXCEPTION;
4575 Py_DECREF(py_result);
4580 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
4582 PyObject *py_ldb = (PyObject *)mod->private_data;
4583 PyObject *py_result;
4585 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
4586 discard_const_p(char, ""));
4588 Py_XDECREF(py_result);
4590 return LDB_ERR_OPERATIONS_ERROR;
4593 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
4595 PyObject *py_ldb = (PyObject *)mod->private_data;
4596 PyObject *py_result;
4598 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
4599 discard_const_p(char, ""));
4601 Py_XDECREF(py_result);
4603 return LDB_ERR_OPERATIONS_ERROR;
4606 static int py_module_start_transaction(struct ldb_module *mod)
4608 PyObject *py_ldb = (PyObject *)mod->private_data;
4609 PyObject *py_result;
4611 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
4612 discard_const_p(char, ""));
4614 if (py_result == NULL) {
4615 return LDB_ERR_PYTHON_EXCEPTION;
4618 Py_DECREF(py_result);
4623 static int py_module_end_transaction(struct ldb_module *mod)
4625 PyObject *py_ldb = (PyObject *)mod->private_data;
4626 PyObject *py_result;
4628 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
4629 discard_const_p(char, ""));
4631 if (py_result == NULL) {
4632 return LDB_ERR_PYTHON_EXCEPTION;
4635 Py_DECREF(py_result);
4640 static int py_module_del_transaction(struct ldb_module *mod)
4642 PyObject *py_ldb = (PyObject *)mod->private_data;
4643 PyObject *py_result;
4645 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
4646 discard_const_p(char, ""));
4648 if (py_result == NULL) {
4649 return LDB_ERR_PYTHON_EXCEPTION;
4652 Py_DECREF(py_result);
4657 static int py_module_destructor(struct ldb_module *mod)
4659 Py_CLEAR(mod->private_data);
4663 static int py_module_init(struct ldb_module *mod)
4665 PyObject *py_class = (PyObject *)mod->ops->private_data;
4666 PyObject *py_result, *py_next, *py_ldb;
4668 py_ldb = PyLdb_FromLdbContext(mod->ldb);
4671 return LDB_ERR_OPERATIONS_ERROR;
4673 py_next = PyLdbModule_FromModule(mod->next);
4675 if (py_next == NULL) {
4677 return LDB_ERR_OPERATIONS_ERROR;
4680 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
4686 if (py_result == NULL) {
4687 return LDB_ERR_PYTHON_EXCEPTION;
4690 mod->private_data = py_result;
4692 talloc_set_destructor(mod, py_module_destructor);
4694 return ldb_next_init(mod);
4697 static PyObject *py_register_module(PyObject *module, PyObject *args)
4700 struct ldb_module_ops *ops;
4702 PyObject *tmp = NULL;
4703 const char *name = NULL;
4705 if (!PyArg_ParseTuple(args, "O", &input))
4708 ops = talloc_zero(NULL, struct ldb_module_ops);
4714 tmp = PyObject_GetAttrString(input, discard_const_p(char, "name"));
4719 name = PyUnicode_AsUTF8(tmp);
4726 ops->name = talloc_strdup(ops, name);
4728 if (ops->name == NULL) {
4730 return PyErr_NoMemory();
4733 ops->private_data = input;
4734 ops->init_context = py_module_init;
4735 ops->search = py_module_search;
4736 ops->add = py_module_add;
4737 ops->modify = py_module_modify;
4738 ops->del = py_module_del;
4739 ops->rename = py_module_rename;
4740 ops->request = py_module_request;
4741 ops->extended = py_module_extended;
4742 ops->start_transaction = py_module_start_transaction;
4743 ops->end_transaction = py_module_end_transaction;
4744 ops->del_transaction = py_module_del_transaction;
4746 ret = ldb_register_module(ops);
4747 if (ret != LDB_SUCCESS) {
4752 PyErr_LDB_ERROR_IS_ERR_RAISE_FREE(PyExc_LdbError, ret, NULL, ops);
4757 static PyObject *py_timestring(PyObject *module, PyObject *args)
4759 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4760 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4764 if (!PyArg_ParseTuple(args, "l", &t_val))
4766 tresult = ldb_timestring(NULL, (time_t) t_val);
4767 if (tresult == NULL) {
4769 * Most likely EOVERFLOW from gmtime()
4771 PyErr_SetFromErrno(PyExc_OSError);
4774 ret = PyUnicode_FromString(tresult);
4775 talloc_free(tresult);
4779 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
4783 if (!PyArg_ParseTuple(args, "s", &str)) {
4786 t = ldb_string_to_time(str);
4788 if (t == 0 && errno != 0) {
4789 PyErr_SetFromErrno(PyExc_ValueError);
4792 return PyLong_FromLong(t);
4795 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4798 if (!PyArg_ParseTuple(args, "s", &name))
4800 return PyBool_FromLong(ldb_valid_attr_name(name));
4804 encode a string using RFC2254 rules
4806 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4808 char *str, *encoded;
4809 Py_ssize_t size = 0;
4813 if (!PyArg_ParseTuple(args, "s#", &str, &size))
4815 val.data = (uint8_t *)str;
4818 encoded = ldb_binary_encode(NULL, val);
4819 if (encoded == NULL) {
4820 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4823 ret = PyUnicode_FromString(encoded);
4824 talloc_free(encoded);
4829 decode a string using RFC2254 rules
4831 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4837 if (!PyArg_ParseTuple(args, "s", &str))
4840 val = ldb_binary_decode(NULL, str);
4841 if (val.data == NULL) {
4842 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4845 ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4846 talloc_free(val.data);
4850 static PyMethodDef py_ldb_global_methods[] = {
4851 { "register_module", py_register_module, METH_VARARGS,
4852 "S.register_module(module) -> None\n\n"
4853 "Register a LDB module."},
4854 { "timestring", py_timestring, METH_VARARGS,
4855 "S.timestring(int) -> string\n\n"
4856 "Generate a LDAP time string from a UNIX timestamp" },
4857 { "string_to_time", py_string_to_time, METH_VARARGS,
4858 "S.string_to_time(string) -> int\n\n"
4859 "Parse a LDAP time string into a UNIX timestamp." },
4860 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4861 "S.valid_attr_name(name) -> bool\n\n"
4862 "Check whether the supplied name is a valid attribute name." },
4863 { "binary_encode", py_binary_encode, METH_VARARGS,
4864 "S.binary_encode(string) -> string\n\n"
4865 "Perform a RFC2254 binary encoding on a string" },
4866 { "binary_decode", py_binary_decode, METH_VARARGS,
4867 "S.binary_decode(string) -> string\n\n"
4868 "Perform a RFC2254 binary decode on a string" },
4872 #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."
4874 static struct PyModuleDef moduledef = {
4875 PyModuleDef_HEAD_INIT,
4877 .m_doc = MODULE_DOC,
4879 .m_methods = py_ldb_global_methods,
4882 static PyObject* module_init(void)
4886 PyLdbBytesType.tp_base = &PyBytes_Type;
4887 if (PyType_Ready(&PyLdbBytesType) < 0) {
4891 if (PyType_Ready(&PyLdbDn) < 0)
4894 if (PyType_Ready(&PyLdbMessage) < 0)
4897 if (PyType_Ready(&PyLdbMessageElement) < 0)
4900 if (PyType_Ready(&PyLdb) < 0)
4903 if (PyType_Ready(&PyLdbModule) < 0)
4906 if (PyType_Ready(&PyLdbTree) < 0)
4909 if (PyType_Ready(&PyLdbResult) < 0)
4912 if (PyType_Ready(&PyLdbSearchIterator) < 0)
4915 if (PyType_Ready(&PyLdbControl) < 0)
4918 m = PyModule_Create(&moduledef);
4922 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4924 ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4925 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4926 ADD_LDB_INT(SEQ_NEXT);
4927 ADD_LDB_INT(SCOPE_DEFAULT);
4928 ADD_LDB_INT(SCOPE_BASE);
4929 ADD_LDB_INT(SCOPE_ONELEVEL);
4930 ADD_LDB_INT(SCOPE_SUBTREE);
4932 ADD_LDB_INT(CHANGETYPE_NONE);
4933 ADD_LDB_INT(CHANGETYPE_ADD);
4934 ADD_LDB_INT(CHANGETYPE_DELETE);
4935 ADD_LDB_INT(CHANGETYPE_MODIFY);
4936 ADD_LDB_INT(CHANGETYPE_MODRDN);
4938 ADD_LDB_INT(FLAG_MOD_ADD);
4939 ADD_LDB_INT(FLAG_MOD_REPLACE);
4940 ADD_LDB_INT(FLAG_MOD_DELETE);
4941 ADD_LDB_INT(FLAG_FORCE_NO_BASE64_LDIF);
4943 ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4944 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4945 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4946 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4948 ADD_LDB_INT(SUCCESS);
4949 ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4950 ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4951 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4952 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4953 ADD_LDB_INT(ERR_COMPARE_FALSE);
4954 ADD_LDB_INT(ERR_COMPARE_TRUE);
4955 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4956 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4957 ADD_LDB_INT(ERR_REFERRAL);
4958 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4959 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4960 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4961 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4962 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4963 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4964 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4965 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4966 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4967 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4968 ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4969 ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4970 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4971 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4972 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4973 ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4974 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4975 ADD_LDB_INT(ERR_BUSY);
4976 ADD_LDB_INT(ERR_UNAVAILABLE);
4977 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4978 ADD_LDB_INT(ERR_LOOP_DETECT);
4979 ADD_LDB_INT(ERR_NAMING_VIOLATION);
4980 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4981 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4982 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4983 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4984 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4985 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4986 ADD_LDB_INT(ERR_OTHER);
4988 ADD_LDB_INT(FLG_RDONLY);
4989 ADD_LDB_INT(FLG_NOSYNC);
4990 ADD_LDB_INT(FLG_RECONNECT);
4991 ADD_LDB_INT(FLG_NOMMAP);
4992 ADD_LDB_INT(FLG_SHOW_BINARY);
4993 ADD_LDB_INT(FLG_ENABLE_TRACING);
4994 ADD_LDB_INT(FLG_DONT_CREATE_DB);
4996 ADD_LDB_INT(PACKING_FORMAT);
4997 ADD_LDB_INT(PACKING_FORMAT_V2);
4999 /* Historical misspelling */
5000 PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
5002 PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
5004 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
5005 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
5008 Py_INCREF(&PyLdbDn);
5009 Py_INCREF(&PyLdbModule);
5010 Py_INCREF(&PyLdbMessage);
5011 Py_INCREF(&PyLdbMessageElement);
5012 Py_INCREF(&PyLdbTree);
5013 Py_INCREF(&PyLdbResult);
5014 Py_INCREF(&PyLdbControl);
5016 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
5017 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
5018 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
5019 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
5020 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
5021 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
5022 PyModule_AddObject(m, "Result", (PyObject *)&PyLdbResult);
5023 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
5025 PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
5027 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
5029 ADD_LDB_STRING(SYNTAX_DN);
5030 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
5031 ADD_LDB_STRING(SYNTAX_INTEGER);
5032 ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER);
5033 ADD_LDB_STRING(SYNTAX_BOOLEAN);
5034 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
5035 ADD_LDB_STRING(SYNTAX_UTC_TIME);
5036 ADD_LDB_STRING(OID_COMPARATOR_AND);
5037 ADD_LDB_STRING(OID_COMPARATOR_OR);
5042 PyMODINIT_FUNC PyInit_ldb(void);
5043 PyMODINIT_FUNC PyInit_ldb(void)
5045 return module_init();