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 PyLdbDn;
70 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
71 static PyTypeObject PyLdb;
72 static PyTypeObject PyLdbMessageElement;
73 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
75 static PyTypeObject PyLdbTree;
76 static struct ldb_message_element *PyObject_AsMessageElement(
80 const char *attr_name);
81 static PyTypeObject PyLdbBytesType;
83 #define PYARG_STR_UNI "es"
85 static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size)
87 PyObject* result = NULL;
88 PyObject* args = NULL;
89 args = Py_BuildValue("(y#)", msg, size);
93 result = PyLdbBytesType.tp_new(&PyLdbBytesType, args, NULL);
98 static PyObject *richcmp(int cmp_val, int op)
102 case Py_LT: ret = cmp_val < 0; break;
103 case Py_LE: ret = cmp_val <= 0; break;
104 case Py_EQ: ret = cmp_val == 0; break;
105 case Py_NE: ret = cmp_val != 0; break;
106 case Py_GT: ret = cmp_val > 0; break;
107 case Py_GE: ret = cmp_val >= 0; break;
109 Py_INCREF(Py_NotImplemented);
110 return Py_NotImplemented;
112 return PyBool_FromLong(ret);
116 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
118 if (self->data != NULL) {
119 char* control = ldb_control_to_string(self->mem_ctx, self->data);
120 if (control == NULL) {
124 return PyUnicode_FromString(control);
126 return PyUnicode_FromString("ldb control");
130 static void py_ldb_control_dealloc(PyLdbControlObject *self)
132 if (self->mem_ctx != NULL) {
133 talloc_free(self->mem_ctx);
136 Py_TYPE(self)->tp_free(self);
139 /* Create a text (rather than bytes) interface for a LDB result object */
140 static PyObject *wrap_text(const char *type, PyObject *wrapped)
142 PyObject *mod, *cls, *constructor, *inst;
143 mod = PyImport_ImportModule("_ldb_text");
146 cls = PyObject_GetAttrString(mod, type);
152 constructor = PyObject_GetAttrString(cls, "_wrap");
154 if (constructor == NULL) {
157 inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped);
158 Py_DECREF(constructor);
162 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self,
163 PyObject *Py_UNUSED(ignored))
165 return PyUnicode_FromString(self->data->oid);
168 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self,
169 PyObject *Py_UNUSED(ignored))
171 return PyBool_FromLong(self->data->critical);
174 static int py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
177 PyErr_SetString(PyExc_AttributeError, "cannot delete critical flag");
180 if (PyObject_IsTrue(value)) {
181 self->data->critical = true;
183 self->data->critical = false;
188 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
191 const char * const kwnames[] = { "ldb", "data", NULL };
192 struct ldb_control *parsed_controls;
193 PyLdbControlObject *ret;
196 struct ldb_context *ldb_ctx;
198 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
199 discard_const_p(char *, kwnames),
200 &PyLdb, &py_ldb, &data))
203 mem_ctx = talloc_new(NULL);
204 if (mem_ctx == NULL) {
209 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(py_ldb);
210 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
212 if (!parsed_controls) {
213 talloc_free(mem_ctx);
214 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
218 ret = PyObject_New(PyLdbControlObject, type);
221 talloc_free(mem_ctx);
225 ret->mem_ctx = mem_ctx;
227 ret->data = talloc_move(mem_ctx, &parsed_controls);
228 if (ret->data == NULL) {
231 talloc_free(mem_ctx);
235 return (PyObject *)ret;
238 static PyGetSetDef py_ldb_control_getset[] = {
240 .name = discard_const_p(char, "oid"),
241 .get = (getter)py_ldb_control_get_oid,
244 .name = discard_const_p(char, "critical"),
245 .get = (getter)py_ldb_control_get_critical,
246 .set = (setter)py_ldb_control_set_critical,
251 static PyTypeObject PyLdbControl = {
252 .tp_name = "ldb.control",
253 .tp_dealloc = (destructor)py_ldb_control_dealloc,
254 .tp_getattro = PyObject_GenericGetAttr,
255 .tp_basicsize = sizeof(PyLdbControlObject),
256 .tp_getset = py_ldb_control_getset,
257 .tp_doc = "LDB control.",
258 .tp_str = (reprfunc)py_ldb_control_str,
259 .tp_new = py_ldb_control_new,
260 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
263 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
265 PyObject *exc = NULL;
266 if (ret == LDB_ERR_PYTHON_EXCEPTION) {
267 return; /* Python exception should already be set, just keep that */
269 exc = Py_BuildValue("(i,s)", ret,
270 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx));
273 * Py_BuildValue failed, and will have set its own exception.
274 * It isn't the one we wanted, but it will have to do.
275 * This is all very unexpected.
277 fprintf(stderr, "could not make LdbError %d!\n", ret);
280 PyErr_SetObject(error, exc);
284 static PyObject *py_ldb_bytes_str(PyBytesObject *self)
289 if (!PyBytes_Check(self)) {
290 PyErr_Format(PyExc_TypeError,"Unexpected type");
293 result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size);
295 PyErr_Format(PyExc_TypeError, "Failed to extract bytes");
298 return PyUnicode_FromStringAndSize(msg, size);
301 static PyTypeObject PyLdbBytesType = {
302 PyVarObject_HEAD_INIT(NULL, 0)
303 .tp_name = "ldb.bytes",
304 .tp_doc = "str/bytes (with custom str)",
305 .tp_str = (reprfunc)py_ldb_bytes_str,
306 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
309 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
311 return PyLdbBytes_FromStringAndSize((const char *)val->data, val->length);
314 static PyObject *PyStr_FromLdbValue(const struct ldb_val *val)
316 return PyUnicode_FromStringAndSize((const char *)val->data, val->length);
320 * Create a Python object from a ldb_result.
322 * @param result LDB result to convert
323 * @return Python object with converted result (a list object)
325 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
327 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
328 PyLdbControlObject *ctrl;
329 if (ctl_ctx == NULL) {
334 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
336 talloc_free(ctl_ctx);
340 ctrl->mem_ctx = ctl_ctx;
341 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
342 if (ctrl->data == NULL) {
347 return (PyObject*) ctrl;
351 * Create a Python object from a ldb_result.
353 * @param result LDB result to convert
354 * @return Python object with converted result (a list object)
356 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
358 PyLdbResultObject *ret;
359 PyObject *list, *controls, *referals;
362 if (result == NULL) {
366 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
372 list = PyList_New(result->count);
379 for (i = 0; i < result->count; i++) {
380 PyObject *pymessage = PyLdbMessage_FromMessage(result->msgs[i]);
381 if (pymessage == NULL) {
386 PyList_SetItem(list, i, pymessage);
389 ret->mem_ctx = talloc_new(NULL);
390 if (ret->mem_ctx == NULL) {
399 if (result->controls) {
401 while (result->controls[i]) {
404 controls = PyList_New(i);
405 if (controls == NULL) {
411 for (i=0; result->controls[i]; i++) {
412 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
420 PyList_SetItem(controls, i, ctrl);
424 * No controls so we keep an empty list
426 controls = PyList_New(0);
427 if (controls == NULL) {
435 ret->controls = controls;
439 while (result->refs && result->refs[i]) {
443 referals = PyList_New(i);
444 if (referals == NULL) {
451 for (i = 0;result->refs && result->refs[i]; i++) {
452 PyList_SetItem(referals, i, PyUnicode_FromString(result->refs[i]));
454 ret->referals = referals;
455 return (PyObject *)ret;
458 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self,
459 PyObject *Py_UNUSED(ignored))
461 return PyBool_FromLong(ldb_dn_validate(self->dn));
464 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self,
465 PyObject *Py_UNUSED(ignored))
467 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
470 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self,
471 PyObject *Py_UNUSED(ignored))
473 return PyBool_FromLong(ldb_dn_is_special(self->dn));
476 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self,
477 PyObject *Py_UNUSED(ignored))
479 return PyBool_FromLong(ldb_dn_is_null(self->dn));
482 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self,
483 PyObject *Py_UNUSED(ignored))
485 return PyUnicode_FromString(ldb_dn_get_casefold(self->dn));
488 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self,
489 PyObject *Py_UNUSED(ignored))
491 return PyUnicode_FromString(ldb_dn_get_linearized(self->dn));
494 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self,
495 PyObject *Py_UNUSED(ignored))
497 return PyUnicode_FromString(ldb_dn_canonical_string(self->dn, self->dn));
500 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self,
501 PyObject *Py_UNUSED(ignored))
503 return PyUnicode_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
506 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
508 const char * const kwnames[] = { "mode", NULL };
510 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
511 discard_const_p(char *, kwnames),
514 return PyUnicode_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
517 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
520 const struct ldb_val *val;
522 if (!PyArg_ParseTuple(args, "s", &name))
524 val = ldb_dn_get_extended_component(self->dn, name);
529 return PyBytes_FromStringAndSize((const char *)val->data, val->length);
532 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
536 uint8_t *value = NULL;
539 if (!PyArg_ParseTuple(args, "sz#", &name, (char **)&value, &size))
543 err = ldb_dn_set_extended_component(self->dn, name, NULL);
546 val.data = (uint8_t *)value;
548 err = ldb_dn_set_extended_component(self->dn, name, &val);
551 if (err != LDB_SUCCESS) {
552 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
559 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
561 PyObject *str = PyUnicode_FromString(ldb_dn_get_linearized(self->dn));
562 PyObject *repr, *result;
565 repr = PyObject_Repr(str);
570 result = PyUnicode_FromFormat("Dn(%s)", PyUnicode_AsUTF8(repr));
576 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
580 if (!PyArg_ParseTuple(args, "s", &name))
583 return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
586 static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
589 if (!pyldb_Dn_Check(dn2)) {
590 Py_INCREF(Py_NotImplemented);
591 return Py_NotImplemented;
593 ret = ldb_dn_compare(pyldb_Dn_AS_DN(dn1), pyldb_Dn_AS_DN(dn2));
594 return richcmp(ret, op);
597 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self,
598 PyObject *Py_UNUSED(ignored))
600 struct ldb_dn *dn = pyldb_Dn_AS_DN((PyObject *)self);
601 struct ldb_dn *parent;
602 PyLdbDnObject *py_ret;
603 TALLOC_CTX *mem_ctx = NULL;
605 if (ldb_dn_get_comp_num(dn) < 1) {
609 mem_ctx = talloc_new(NULL);
610 if (mem_ctx == NULL) {
615 parent = ldb_dn_get_parent(mem_ctx, dn);
616 if (parent == NULL) {
618 talloc_free(mem_ctx);
622 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
623 if (py_ret == NULL) {
625 talloc_free(mem_ctx);
628 py_ret->mem_ctx = mem_ctx;
630 return (PyObject *)py_ret;
633 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
636 struct ldb_dn *dn, *other;
638 if (!PyArg_ParseTuple(args, "O", &py_other))
641 dn = pyldb_Dn_AS_DN((PyObject *)self);
643 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
646 ok = ldb_dn_add_child(dn, other);
648 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, NULL);
655 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
658 struct ldb_dn *other, *dn;
660 if (!PyArg_ParseTuple(args, "O", &py_other))
663 dn = pyldb_Dn_AS_DN((PyObject *)self);
665 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
668 ok = ldb_dn_add_base(dn, other);
670 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, NULL);
677 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
682 if (!PyArg_ParseTuple(args, "i", &i))
685 dn = pyldb_Dn_AS_DN((PyObject *)self);
687 ok = ldb_dn_remove_base_components(dn, i);
689 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, NULL);
696 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
699 struct ldb_dn *dn, *base;
700 if (!PyArg_ParseTuple(args, "O", &py_base))
703 dn = pyldb_Dn_AS_DN((PyObject *)self);
705 if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
708 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
711 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
715 unsigned int num = 0;
717 if (!PyArg_ParseTuple(args, "I", &num))
720 dn = pyldb_Dn_AS_DN((PyObject *)self);
722 name = ldb_dn_get_component_name(dn, num);
727 return PyUnicode_FromString(name);
730 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
733 const struct ldb_val *val;
734 unsigned int num = 0;
736 if (!PyArg_ParseTuple(args, "I", &num))
739 dn = pyldb_Dn_AS_DN((PyObject *)self);
741 val = ldb_dn_get_component_val(dn, num);
746 return PyStr_FromLdbValue(val);
749 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
751 unsigned int num = 0;
752 char *name = NULL, *value = NULL;
753 struct ldb_val val = { 0 };
757 if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size))
760 val.data = (unsigned char*) value;
763 err = ldb_dn_set_component(self->dn, num, name, val);
764 if (err != LDB_SUCCESS) {
765 PyErr_SetString(PyExc_TypeError, "Failed to set component");
772 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self,
773 PyObject *Py_UNUSED(ignored))
778 dn = pyldb_Dn_AS_DN((PyObject *)self);
780 name = ldb_dn_get_rdn_name(dn);
785 return PyUnicode_FromString(name);
788 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self,
789 PyObject *Py_UNUSED(ignored))
792 const struct ldb_val *val;
794 dn = pyldb_Dn_AS_DN((PyObject *)self);
796 val = ldb_dn_get_rdn_val(dn);
801 return PyStr_FromLdbValue(val);
804 static PyMethodDef py_ldb_dn_methods[] = {
805 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
806 "S.validate() -> bool\n"
807 "Validate DN is correct." },
808 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
809 "S.is_valid() -> bool\n" },
810 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
811 "S.is_special() -> bool\n"
812 "Check whether this is a special LDB DN." },
813 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
814 "Check whether this is a null DN." },
815 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
817 { "get_linearized", PY_DISCARD_FUNC_SIG(PyCFunction,
818 py_ldb_dn_get_linearized),
821 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
822 "S.canonical_str() -> string\n"
823 "Canonical version of this DN (like a posix path)." },
824 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
825 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
826 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
827 "S.canonical_ex_str() -> string\n"
828 "Canonical version of this DN (like a posix path, with terminating newline)." },
829 { "extended_str", PY_DISCARD_FUNC_SIG(PyCFunction,
830 py_ldb_dn_extended_str),
831 METH_VARARGS | METH_KEYWORDS,
832 "S.extended_str(mode=1) -> string\n"
833 "Extended version of this DN" },
834 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
836 "Get the parent for this DN." },
837 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
838 "S.add_child(dn) -> bool\n"
839 "Add a child DN to this DN." },
840 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
841 "S.add_base(dn) -> bool\n"
842 "Add a base DN to this DN." },
843 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
844 "S.remove_base_components(int) -> bool\n"
845 "Remove a number of DN components from the base of this DN." },
846 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
847 "S.check_special(name) -> bool\n\n"
848 "Check if name is a special DN name"},
849 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
850 "S.get_extended_component(name) -> string\n\n"
851 "returns a DN extended component as a binary string"},
852 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
853 "S.set_extended_component(name, value) -> None\n\n"
854 "set a DN extended component as a binary string"},
855 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
856 "S.get_component_name(num) -> string\n"
857 "get the attribute name of the specified component" },
858 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
859 "S.get_component_value(num) -> string\n"
860 "get the attribute value of the specified component as a binary string" },
861 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
862 "S.set_component(num, name, value) -> None\n"
863 "set the attribute name and value of the specified component" },
864 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
865 "S.get_rdn_name() -> string\n"
866 "get the RDN attribute name" },
867 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
868 "S.get_rdn_value() -> string\n"
869 "get the RDN attribute value as a binary string" },
873 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
875 return ldb_dn_get_comp_num(pyldb_Dn_AS_DN((PyObject *)self));
879 copy a DN as a python object
881 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
883 TALLOC_CTX *mem_ctx = NULL;
884 struct ldb_dn *new_dn = NULL;
885 PyLdbDnObject *py_ret;
887 mem_ctx = talloc_new(NULL);
888 if (mem_ctx == NULL) {
889 return PyErr_NoMemory();
892 new_dn = ldb_dn_copy(mem_ctx, dn);
893 if (new_dn == NULL) {
894 talloc_free(mem_ctx);
895 return PyErr_NoMemory();
898 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
899 if (py_ret == NULL) {
900 talloc_free(mem_ctx);
904 py_ret->mem_ctx = mem_ctx;
906 return (PyObject *)py_ret;
909 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
911 TALLOC_CTX *mem_ctx = NULL;
912 struct ldb_dn *dn = pyldb_Dn_AS_DN((PyObject *)self),
914 struct ldb_dn *new_dn = NULL;
915 PyLdbDnObject *py_ret;
917 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
920 mem_ctx = talloc_new(NULL);
921 if (mem_ctx == NULL) {
922 return PyErr_NoMemory();
925 new_dn = ldb_dn_copy(mem_ctx, dn);
926 if (new_dn == NULL) {
927 talloc_free(mem_ctx);
928 return PyErr_NoMemory();
931 if (!ldb_dn_add_base(new_dn, other)) {
932 PyErr_SetString(PyExc_RuntimeError, "unable to concatenate DNs");
933 talloc_free(mem_ctx);
937 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
938 if (py_ret == NULL) {
939 talloc_free(mem_ctx);
943 py_ret->mem_ctx = mem_ctx;
946 return (PyObject *)py_ret;
949 static PySequenceMethods py_ldb_dn_seq = {
950 .sq_length = (lenfunc)py_ldb_dn_len,
951 .sq_concat = (binaryfunc)py_ldb_dn_concat,
954 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
956 struct ldb_dn *ret = NULL;
958 PyObject *py_ldb = NULL;
959 struct ldb_context *ldb_ctx = NULL;
960 TALLOC_CTX *mem_ctx = NULL;
961 PyLdbDnObject *py_ret = NULL;
962 const char * const kwnames[] = { "ldb", "dn", NULL };
964 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!"PYARG_STR_UNI,
965 discard_const_p(char *, kwnames),
966 &PyLdb, &py_ldb, "utf8", &str))
969 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(py_ldb);
971 mem_ctx = talloc_new(NULL);
972 if (mem_ctx == NULL) {
977 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
978 if (!ldb_dn_validate(ret)) {
979 talloc_free(mem_ctx);
980 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
984 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
985 if (py_ret == NULL) {
986 talloc_free(mem_ctx);
990 py_ret->mem_ctx = mem_ctx;
994 PyMem_Free(discard_const_p(char, str));
996 return (PyObject *)py_ret;
999 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
1001 talloc_free(self->mem_ctx);
1005 static PyTypeObject PyLdbDn = {
1006 .tp_name = "ldb.Dn",
1007 .tp_methods = py_ldb_dn_methods,
1008 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
1009 .tp_repr = (reprfunc)py_ldb_dn_repr,
1010 .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp,
1011 .tp_as_sequence = &py_ldb_dn_seq,
1012 .tp_doc = "A LDB distinguished name.",
1013 .tp_new = py_ldb_dn_new,
1014 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
1015 .tp_basicsize = sizeof(PyLdbDnObject),
1016 .tp_flags = Py_TPFLAGS_DEFAULT,
1020 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
1021 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
1023 PyObject *fn = (PyObject *)context;
1024 PyObject *result = NULL;
1025 result = PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyUnicode_FromFormatV(fmt, ap));
1029 static PyObject *py_ldb_debug_func;
1031 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
1034 struct ldb_context *ldb_ctx;
1036 if (!PyArg_ParseTuple(args, "O", &cb))
1039 if (py_ldb_debug_func != NULL) {
1040 Py_DECREF(py_ldb_debug_func);
1044 /* FIXME: DECREF cb when exiting program */
1045 py_ldb_debug_func = cb;
1046 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1047 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
1048 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
1054 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
1057 if (!PyArg_ParseTuple(args, "I", &perms))
1060 ldb_set_create_perms(pyldb_Ldb_AS_LDBCONTEXT(self), perms);
1065 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
1068 if (!PyArg_ParseTuple(args, "s", &modules_dir))
1071 ldb_set_modules_dir(pyldb_Ldb_AS_LDBCONTEXT(self), modules_dir);
1076 static PyObject *py_ldb_transaction_start(PyLdbObject *self,
1077 PyObject *Py_UNUSED(ignored))
1079 struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1081 ldb_err = ldb_transaction_start(ldb_ctx);
1082 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1086 static PyObject *py_ldb_transaction_commit(PyLdbObject *self,
1087 PyObject *Py_UNUSED(ignored))
1089 struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1091 ldb_err = ldb_transaction_commit(ldb_ctx);
1092 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1096 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self,
1097 PyObject *Py_UNUSED(ignored))
1099 struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1101 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
1102 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1106 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self,
1107 PyObject *Py_UNUSED(ignored))
1109 struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1111 ldb_err = ldb_transaction_cancel(ldb_ctx);
1112 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1116 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self,
1117 PyObject *Py_UNUSED(ignored))
1119 struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1121 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
1122 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1126 static PyObject *py_ldb_repr(PyLdbObject *self)
1128 return PyUnicode_FromString("<ldb connection>");
1131 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self,
1132 PyObject *Py_UNUSED(ignored))
1134 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AS_LDBCONTEXT(self));
1137 return py_ldb_dn_copy(dn);
1141 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self,
1142 PyObject *Py_UNUSED(ignored))
1144 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AS_LDBCONTEXT(self));
1147 return py_ldb_dn_copy(dn);
1150 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self,
1151 PyObject *Py_UNUSED(ignored))
1153 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AS_LDBCONTEXT(self));
1156 return py_ldb_dn_copy(dn);
1159 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self,
1160 PyObject *Py_UNUSED(ignored))
1162 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AS_LDBCONTEXT(self));
1165 return py_ldb_dn_copy(dn);
1168 static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
1169 const char *paramname)
1173 if (!PyList_Check(list)) {
1174 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
1177 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1183 for (i = 0; i < PyList_Size(list); i++) {
1184 const char *str = NULL;
1186 PyObject *item = PyList_GetItem(list, i);
1187 if (!PyUnicode_Check(item)) {
1188 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
1192 str = PyUnicode_AsUTF8AndSize(item, &size);
1197 ret[i] = talloc_strndup(ret, str, size);
1203 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1205 const char * const kwnames[] = { "url", "flags", "options", NULL };
1207 PyObject *py_options = Py_None;
1208 const char **options;
1209 unsigned int flags = 0;
1211 struct ldb_context *ldb;
1213 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1214 discard_const_p(char *, kwnames),
1215 &url, &flags, &py_options))
1218 ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
1220 if (py_options == Py_None) {
1223 options = PyList_AsStrList(ldb, py_options, "options");
1224 if (options == NULL)
1229 ret = ldb_connect(ldb, url, flags, options);
1230 if (ret != LDB_SUCCESS) {
1231 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1232 talloc_free(options);
1236 ldb_set_flags(ldb, flags);
1239 talloc_free(options);
1243 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1245 TALLOC_CTX *mem_ctx = NULL;
1247 struct ldb_context *ldb;
1249 mem_ctx = talloc_new(NULL);
1250 if (mem_ctx == NULL) {
1251 return PyErr_NoMemory();
1254 ldb = ldb_init(mem_ctx, NULL);
1256 talloc_free(mem_ctx);
1261 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1263 talloc_free(mem_ctx);
1267 ret->mem_ctx = mem_ctx;
1270 return (PyObject *)ret;
1273 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1276 unsigned int flags = 0;
1277 PyObject *py_options = Py_None;
1279 const char **options;
1280 const char * const kwnames[] = { "url", "flags", "options", NULL };
1281 struct ldb_context *ldb_ctx;
1283 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|IO",
1284 discard_const_p(char *, kwnames),
1285 &url, &flags, &py_options))
1288 if (py_options == Py_None) {
1291 options = PyList_AsStrList(NULL, py_options, "options");
1292 if (options == NULL)
1296 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1297 ret = ldb_connect(ldb_ctx, url, flags, options);
1298 talloc_free(options);
1300 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1305 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1308 PyObject *py_controls = Py_None;
1309 struct ldb_context *ldb_ctx;
1310 struct ldb_request *req;
1311 struct ldb_control **parsed_controls;
1312 struct ldb_message *msg;
1314 TALLOC_CTX *mem_ctx;
1316 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1318 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1319 discard_const_p(char *, kwnames),
1320 &py_msg, &py_controls, &validate))
1323 mem_ctx = talloc_new(NULL);
1324 if (mem_ctx == NULL) {
1328 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1330 if (py_controls == Py_None) {
1331 parsed_controls = NULL;
1333 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1334 if (controls == NULL) {
1335 talloc_free(mem_ctx);
1338 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1339 if (controls[0] != NULL && parsed_controls == NULL) {
1340 talloc_free(mem_ctx);
1341 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, ldb_ctx);
1344 talloc_free(controls);
1347 if (!PyLdbMessage_Check(py_msg)) {
1348 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1349 talloc_free(mem_ctx);
1352 msg = pyldb_Message_AsMessage(py_msg);
1355 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1356 if (ret != LDB_SUCCESS) {
1357 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1358 talloc_free(mem_ctx);
1363 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1364 NULL, ldb_op_default_callback, NULL);
1365 if (ret != LDB_SUCCESS) {
1366 PyErr_SetString(PyExc_TypeError, "failed to build request");
1367 talloc_free(mem_ctx);
1371 /* do request and autostart a transaction */
1372 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1374 ret = ldb_transaction_start(ldb_ctx);
1375 if (ret != LDB_SUCCESS) {
1376 talloc_free(mem_ctx);
1377 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1381 ret = ldb_request(ldb_ctx, req);
1382 if (ret == LDB_SUCCESS) {
1383 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1386 if (ret == LDB_SUCCESS) {
1387 ret = ldb_transaction_commit(ldb_ctx);
1389 ldb_transaction_cancel(ldb_ctx);
1392 talloc_free(mem_ctx);
1393 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1400 * Obtain a ldb message from a Python Dictionary object.
1402 * @param mem_ctx Memory context
1403 * @param py_obj Python Dictionary object
1404 * @param ldb_ctx LDB context
1405 * @param mod_flags Flags to be set on every message element
1406 * @return ldb_message on success or NULL on failure
1408 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1410 struct ldb_context *ldb_ctx,
1411 unsigned int mod_flags)
1413 struct ldb_message *msg;
1414 unsigned int msg_pos = 0;
1415 Py_ssize_t dict_pos = 0;
1416 PyObject *key, *value;
1417 struct ldb_message_element *msg_el;
1418 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1420 msg = ldb_msg_new(mem_ctx);
1425 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1426 if (msg->elements == NULL) {
1433 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1434 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1438 if (msg->dn == NULL) {
1439 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1444 PyErr_SetString(PyExc_TypeError, "no dn set");
1449 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1450 const char *key_str = PyUnicode_AsUTF8(key);
1451 if (ldb_attr_cmp(key_str, "dn") != 0) {
1452 msg_el = PyObject_AsMessageElement(msg->elements, value,
1453 mod_flags, key_str);
1454 if (msg_el == NULL) {
1455 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1459 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1462 * PyObject_AsMessageElement might have returned a
1463 * reference to an existing MessageElement, and so left
1464 * the name and flags unchanged. Thus if those members
1465 * aren’t set, we’ll assume that the user forgot to
1468 if (msg->elements[msg_pos].name == NULL) {
1469 /* No name was set — set it now. */
1470 msg->elements[msg_pos].name = talloc_strdup(msg->elements, key_str);
1471 if (msg->elements[msg_pos].name == NULL) {
1477 if (msg->elements[msg_pos].flags == 0) {
1478 /* No flags were set — set them now. */
1479 msg->elements[msg_pos].flags = mod_flags;
1486 msg->num_elements = msg_pos;
1491 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1495 struct ldb_context *ldb_ctx;
1496 struct ldb_request *req;
1497 struct ldb_message *msg = NULL;
1498 PyObject *py_controls = Py_None;
1499 TALLOC_CTX *mem_ctx;
1500 struct ldb_control **parsed_controls;
1501 const char * const kwnames[] = { "message", "controls", NULL };
1503 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1504 discard_const_p(char *, kwnames),
1505 &py_obj, &py_controls))
1508 mem_ctx = talloc_new(NULL);
1509 if (mem_ctx == NULL) {
1513 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1515 if (py_controls == Py_None) {
1516 parsed_controls = NULL;
1518 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1519 if (controls == NULL) {
1520 talloc_free(mem_ctx);
1523 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1524 if (controls[0] != NULL && parsed_controls == NULL) {
1525 talloc_free(mem_ctx);
1526 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, ldb_ctx);
1529 talloc_free(controls);
1532 if (PyLdbMessage_Check(py_obj)) {
1533 msg = pyldb_Message_AsMessage(py_obj);
1534 } else if (PyDict_Check(py_obj)) {
1535 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1537 PyErr_SetString(PyExc_TypeError,
1538 "Dictionary or LdbMessage object expected!");
1542 /* we should have a PyErr already set */
1543 talloc_free(mem_ctx);
1547 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1548 if (ret != LDB_SUCCESS) {
1549 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1550 talloc_free(mem_ctx);
1554 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1555 NULL, ldb_op_default_callback, NULL);
1556 if (ret != LDB_SUCCESS) {
1557 PyErr_SetString(PyExc_TypeError, "failed to build request");
1558 talloc_free(mem_ctx);
1562 /* do request and autostart a transaction */
1563 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1565 ret = ldb_transaction_start(ldb_ctx);
1566 if (ret != LDB_SUCCESS) {
1567 talloc_free(mem_ctx);
1568 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1572 ret = ldb_request(ldb_ctx, req);
1573 if (ret == LDB_SUCCESS) {
1574 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1577 if (ret == LDB_SUCCESS) {
1578 ret = ldb_transaction_commit(ldb_ctx);
1580 ldb_transaction_cancel(ldb_ctx);
1583 talloc_free(mem_ctx);
1584 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1589 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1594 struct ldb_context *ldb_ctx;
1595 struct ldb_request *req;
1596 PyObject *py_controls = Py_None;
1597 TALLOC_CTX *mem_ctx;
1598 struct ldb_control **parsed_controls;
1599 const char * const kwnames[] = { "dn", "controls", NULL };
1601 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1602 discard_const_p(char *, kwnames),
1603 &py_dn, &py_controls))
1606 mem_ctx = talloc_new(NULL);
1607 if (mem_ctx == NULL) {
1611 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1613 if (py_controls == Py_None) {
1614 parsed_controls = NULL;
1616 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1617 if (controls == NULL) {
1618 talloc_free(mem_ctx);
1621 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1622 if (controls[0] != NULL && parsed_controls == NULL) {
1623 talloc_free(mem_ctx);
1624 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, ldb_ctx);
1627 talloc_free(controls);
1630 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1631 talloc_free(mem_ctx);
1635 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1636 NULL, ldb_op_default_callback, NULL);
1637 if (ret != LDB_SUCCESS) {
1638 PyErr_SetString(PyExc_TypeError, "failed to build request");
1639 talloc_free(mem_ctx);
1643 /* do request and autostart a transaction */
1644 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1646 ret = ldb_transaction_start(ldb_ctx);
1647 if (ret != LDB_SUCCESS) {
1648 talloc_free(mem_ctx);
1649 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1653 ret = ldb_request(ldb_ctx, req);
1654 if (ret == LDB_SUCCESS) {
1655 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1658 if (ret == LDB_SUCCESS) {
1659 ret = ldb_transaction_commit(ldb_ctx);
1661 ldb_transaction_cancel(ldb_ctx);
1664 talloc_free(mem_ctx);
1665 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1670 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1672 PyObject *py_dn1, *py_dn2;
1673 struct ldb_dn *dn1, *dn2;
1675 TALLOC_CTX *mem_ctx;
1676 PyObject *py_controls = Py_None;
1677 struct ldb_control **parsed_controls;
1678 struct ldb_context *ldb_ctx;
1679 struct ldb_request *req;
1680 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1682 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1684 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1685 discard_const_p(char *, kwnames),
1686 &py_dn1, &py_dn2, &py_controls))
1690 mem_ctx = talloc_new(NULL);
1691 if (mem_ctx == NULL) {
1696 if (py_controls == Py_None) {
1697 parsed_controls = NULL;
1699 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1700 if (controls == NULL) {
1701 talloc_free(mem_ctx);
1704 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1705 if (controls[0] != NULL && parsed_controls == NULL) {
1706 talloc_free(mem_ctx);
1707 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, ldb_ctx);
1710 talloc_free(controls);
1714 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1715 talloc_free(mem_ctx);
1719 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1720 talloc_free(mem_ctx);
1724 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1725 NULL, ldb_op_default_callback, NULL);
1726 if (ret != LDB_SUCCESS) {
1727 PyErr_SetString(PyExc_TypeError, "failed to build request");
1728 talloc_free(mem_ctx);
1732 /* do request and autostart a transaction */
1733 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1735 ret = ldb_transaction_start(ldb_ctx);
1736 if (ret != LDB_SUCCESS) {
1737 talloc_free(mem_ctx);
1738 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1742 ret = ldb_request(ldb_ctx, req);
1743 if (ret == LDB_SUCCESS) {
1744 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1747 if (ret == LDB_SUCCESS) {
1748 ret = ldb_transaction_commit(ldb_ctx);
1750 ldb_transaction_cancel(ldb_ctx);
1753 talloc_free(mem_ctx);
1754 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1759 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1762 if (!PyArg_ParseTuple(args, "s", &name))
1765 ldb_schema_attribute_remove(pyldb_Ldb_AS_LDBCONTEXT(self), name);
1770 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1772 char *attribute, *syntax;
1775 struct ldb_context *ldb_ctx;
1777 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1780 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
1781 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1783 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1788 static PyObject *ldb_ldif_to_pyobject(struct ldb_context *ldb, struct ldb_ldif *ldif)
1790 PyObject *obj = NULL;
1791 PyObject *result = NULL;
1797 switch (ldif->changetype) {
1798 case LDB_CHANGETYPE_NONE:
1799 case LDB_CHANGETYPE_ADD:
1800 obj = PyLdbMessage_FromMessage(ldif->msg);
1802 case LDB_CHANGETYPE_MODIFY:
1803 obj = PyLdbMessage_FromMessage(ldif->msg);
1805 case LDB_CHANGETYPE_DELETE:
1806 if (ldif->msg->num_elements != 0) {
1807 PyErr_Format(PyExc_ValueError,
1808 "CHANGETYPE(DELETE) with num_elements=%u",
1809 ldif->msg->num_elements);
1812 obj = pyldb_Dn_FromDn(ldif->msg->dn);
1814 case LDB_CHANGETYPE_MODRDN: {
1815 struct ldb_dn *olddn = NULL;
1816 PyObject *olddn_obj = NULL;
1817 bool deleteoldrdn = false;
1818 PyObject *deleteoldrdn_obj = NULL;
1819 struct ldb_dn *newdn = NULL;
1820 PyObject *newdn_obj = NULL;
1823 ret = ldb_ldif_parse_modrdn(ldb,
1831 if (ret != LDB_SUCCESS) {
1832 PyErr_Format(PyExc_ValueError,
1833 "ldb_ldif_parse_modrdn() failed");
1837 olddn_obj = pyldb_Dn_FromDn(olddn);
1838 if (olddn_obj == NULL) {
1842 deleteoldrdn_obj = Py_True;
1844 deleteoldrdn_obj = Py_False;
1846 newdn_obj = pyldb_Dn_FromDn(newdn);
1847 if (newdn_obj == NULL) {
1848 deleteoldrdn_obj = NULL;
1849 Py_CLEAR(olddn_obj);
1853 obj = Py_BuildValue(discard_const_p(char, "{s:O,s:O,s:O}"),
1855 "deleteoldrdn", deleteoldrdn_obj,
1856 "newdn", newdn_obj);
1857 Py_CLEAR(olddn_obj);
1858 deleteoldrdn_obj = NULL;
1859 Py_CLEAR(newdn_obj);
1863 PyErr_Format(PyExc_NotImplementedError,
1864 "Unsupported LDB_CHANGETYPE(%u)",
1873 /* We don't want this being attached * to the 'ldb' any more */
1874 result = Py_BuildValue(discard_const_p(char, "(iO)"),
1882 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1886 struct ldb_ldif ldif;
1889 TALLOC_CTX *mem_ctx;
1891 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1894 if (!PyLdbMessage_Check(py_msg)) {
1895 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1899 ldif.msg = pyldb_Message_AsMessage(py_msg);
1900 ldif.changetype = changetype;
1902 mem_ctx = talloc_new(NULL);
1903 if (mem_ctx == NULL) {
1904 return PyErr_NoMemory();
1907 string = ldb_ldif_write_string(pyldb_Ldb_AS_LDBCONTEXT(self), mem_ctx, &ldif);
1909 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1910 talloc_free(mem_ctx);
1914 ret = PyUnicode_FromString(string);
1916 talloc_free(mem_ctx);
1921 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1923 PyObject *list, *ret;
1924 struct ldb_ldif *ldif;
1926 struct ldb_dn *last_dn = NULL;
1928 TALLOC_CTX *mem_ctx;
1930 if (!PyArg_ParseTuple(args, "s", &s))
1933 mem_ctx = talloc_new(NULL);
1938 list = PyList_New(0);
1940 talloc_free(mem_ctx);
1944 while (s && *s != '\0') {
1945 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1946 talloc_steal(mem_ctx, ldif);
1949 PyObject *py_ldif = ldb_ldif_to_pyobject(self->ldb_ctx, ldif);
1950 if (py_ldif == NULL) {
1952 if (PyErr_Occurred() == NULL) {
1953 PyErr_BadArgument();
1955 talloc_free(mem_ctx);
1958 res = PyList_Append(list, py_ldif);
1962 talloc_free(mem_ctx);
1965 last_dn = ldif->msg->dn;
1967 const char *last_dn_str = NULL;
1968 const char *err_string = NULL;
1969 if (last_dn == NULL) {
1970 PyErr_SetString(PyExc_ValueError,
1971 "unable to parse LDIF "
1972 "string at first chunk");
1974 talloc_free(mem_ctx);
1979 = ldb_dn_get_linearized(last_dn);
1982 = talloc_asprintf(mem_ctx,
1983 "unable to parse ldif "
1987 PyErr_SetString(PyExc_ValueError,
1989 talloc_free(mem_ctx);
1994 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1995 ret = PyObject_GetIter(list);
2000 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
2003 PyObject *py_msg_old;
2004 PyObject *py_msg_new;
2005 struct ldb_message *diff;
2006 struct ldb_context *ldb;
2008 TALLOC_CTX *mem_ctx = NULL;
2010 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
2013 if (!PyLdbMessage_Check(py_msg_old)) {
2014 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
2018 if (!PyLdbMessage_Check(py_msg_new)) {
2019 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
2023 mem_ctx = talloc_new(NULL);
2024 if (mem_ctx == NULL) {
2029 ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
2030 ldb_ret = ldb_msg_difference(ldb, mem_ctx,
2031 pyldb_Message_AsMessage(py_msg_old),
2032 pyldb_Message_AsMessage(py_msg_new),
2034 if (ldb_ret != LDB_SUCCESS) {
2035 talloc_free(mem_ctx);
2036 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
2040 diff = ldb_msg_copy(mem_ctx, diff);
2042 talloc_free(mem_ctx);
2047 py_ret = PyLdbMessage_FromMessage(diff);
2049 talloc_free(mem_ctx);
2054 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
2056 const struct ldb_schema_attribute *a;
2057 struct ldb_val old_val;
2058 struct ldb_val new_val;
2059 TALLOC_CTX *mem_ctx;
2066 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
2069 result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
2070 old_val.length = size;
2073 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
2077 a = ldb_schema_attribute_by_name(pyldb_Ldb_AS_LDBCONTEXT(self), element_name);
2083 mem_ctx = talloc_new(NULL);
2084 if (mem_ctx == NULL) {
2089 if (a->syntax->ldif_write_fn(pyldb_Ldb_AS_LDBCONTEXT(self), mem_ctx, &old_val, &new_val) != 0) {
2090 talloc_free(mem_ctx);
2094 ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
2096 talloc_free(mem_ctx);
2101 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2103 PyObject *py_base = Py_None;
2104 int scope = LDB_SCOPE_DEFAULT;
2106 PyObject *py_attrs = Py_None;
2107 PyObject *py_controls = Py_None;
2108 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
2110 struct ldb_result *res;
2111 struct ldb_request *req;
2113 struct ldb_context *ldb_ctx;
2114 struct ldb_control **parsed_controls;
2115 struct ldb_dn *base;
2117 TALLOC_CTX *mem_ctx;
2119 /* type "int" rather than "enum" for "scope" is intentional */
2120 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
2121 discard_const_p(char *, kwnames),
2122 &py_base, &scope, &expr, &py_attrs, &py_controls))
2126 mem_ctx = talloc_new(NULL);
2127 if (mem_ctx == NULL) {
2131 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
2133 if (py_attrs == Py_None) {
2136 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
2137 if (attrs == NULL) {
2138 talloc_free(mem_ctx);
2143 if (py_base == Py_None) {
2144 base = ldb_get_default_basedn(ldb_ctx);
2146 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
2147 talloc_free(mem_ctx);
2152 if (py_controls == Py_None) {
2153 parsed_controls = NULL;
2155 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
2156 if (controls == NULL) {
2157 talloc_free(mem_ctx);
2160 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
2161 if (controls[0] != NULL && parsed_controls == NULL) {
2162 talloc_free(mem_ctx);
2163 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, ldb_ctx);
2166 talloc_free(controls);
2169 res = talloc_zero(mem_ctx, struct ldb_result);
2172 talloc_free(mem_ctx);
2176 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
2183 ldb_search_default_callback,
2186 if (ret != LDB_SUCCESS) {
2187 talloc_free(mem_ctx);
2188 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2192 talloc_steal(req, attrs);
2194 ret = ldb_request(ldb_ctx, req);
2196 if (ret == LDB_SUCCESS) {
2197 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
2200 if (ret != LDB_SUCCESS) {
2201 talloc_free(mem_ctx);
2202 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2206 py_ret = PyLdbResult_FromResult(res);
2208 talloc_free(mem_ctx);
2213 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
2215 if (reply->py_iter != NULL) {
2216 DLIST_REMOVE(reply->py_iter->state.next, reply);
2217 if (reply->py_iter->state.result == reply) {
2218 reply->py_iter->state.result = NULL;
2220 reply->py_iter = NULL;
2223 Py_CLEAR(reply->obj);
2228 static int py_ldb_search_iterator_callback(struct ldb_request *req,
2229 struct ldb_reply *ares)
2231 PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
2232 struct ldb_result result = { .msgs = NULL };
2233 struct py_ldb_search_iterator_reply *reply = NULL;
2236 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2239 if (ares->error != LDB_SUCCESS) {
2240 int ret = ares->error;
2242 return ldb_request_done(req, ret);
2245 reply = talloc_zero(py_iter->mem_ctx,
2246 struct py_ldb_search_iterator_reply);
2247 if (reply == NULL) {
2249 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2251 reply->py_iter = py_iter;
2252 talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
2254 switch (ares->type) {
2255 case LDB_REPLY_ENTRY:
2256 reply->obj = PyLdbMessage_FromMessage(ares->message);
2257 if (reply->obj == NULL) {
2259 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2261 DLIST_ADD_END(py_iter->state.next, reply);
2265 case LDB_REPLY_REFERRAL:
2266 reply->obj = PyUnicode_FromString(ares->referral);
2267 if (reply->obj == NULL) {
2269 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2271 DLIST_ADD_END(py_iter->state.next, reply);
2275 case LDB_REPLY_DONE:
2276 result = (struct ldb_result) { .controls = ares->controls };
2277 reply->obj = PyLdbResult_FromResult(&result);
2278 if (reply->obj == NULL) {
2280 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2282 py_iter->state.result = reply;
2284 return ldb_request_done(req, LDB_SUCCESS);
2288 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2291 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2293 PyObject *py_base = Py_None;
2294 int scope = LDB_SCOPE_DEFAULT;
2297 PyObject *py_attrs = Py_None;
2298 PyObject *py_controls = Py_None;
2299 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
2302 struct ldb_context *ldb_ctx;
2303 struct ldb_control **parsed_controls;
2304 struct ldb_dn *base;
2305 PyLdbSearchIteratorObject *py_iter;
2307 /* type "int" rather than "enum" for "scope" is intentional */
2308 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
2309 discard_const_p(char *, kwnames),
2310 &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
2313 py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
2314 if (py_iter == NULL) {
2318 py_iter->ldb = self;
2320 ZERO_STRUCT(py_iter->state);
2321 py_iter->mem_ctx = talloc_new(NULL);
2322 if (py_iter->mem_ctx == NULL) {
2328 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
2330 if (py_attrs == Py_None) {
2333 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2334 if (attrs == NULL) {
2341 if (py_base == Py_None) {
2342 base = ldb_get_default_basedn(ldb_ctx);
2344 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2351 if (py_controls == Py_None) {
2352 parsed_controls = NULL;
2354 const char **controls = NULL;
2356 controls = PyList_AsStrList(py_iter->mem_ctx,
2357 py_controls, "controls");
2358 if (controls == NULL) {
2364 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2367 if (controls[0] != NULL && parsed_controls == NULL) {
2369 PyErr_SetLdbError(PyExc_LdbError, LDB_ERR_OPERATIONS_ERROR, ldb_ctx);
2372 talloc_free(controls);
2375 ret = ldb_build_search_req(&py_iter->state.req,
2384 py_ldb_search_iterator_callback,
2386 if (ret != LDB_SUCCESS) {
2388 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2392 ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2394 ret = ldb_request(ldb_ctx, py_iter->state.req);
2395 if (ret != LDB_SUCCESS) {
2397 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2401 return (PyObject *)py_iter;
2404 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2409 if (!PyArg_ParseTuple(args, "s", &name))
2412 data = ldb_get_opaque(pyldb_Ldb_AS_LDBCONTEXT(self), name);
2417 /* FIXME: More interpretation */
2422 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2427 if (!PyArg_ParseTuple(args, "sO", &name, &data))
2430 /* FIXME: More interpretation */
2432 ldb_set_opaque(pyldb_Ldb_AS_LDBCONTEXT(self), name, data);
2437 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2439 struct ldb_context *ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
2443 if (!PyArg_ParseTuple(args, "i", &type))
2446 /* FIXME: More interpretation */
2448 ret = ldb_sequence_number(ldb, type, &value);
2450 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2452 return PyLong_FromLongLong(value);
2455 static PyObject *py_ldb_whoami(PyLdbObject *self, PyObject *args)
2457 struct ldb_context *ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
2458 struct ldb_result *res = NULL;
2459 struct ldb_extended *ext_res = NULL;
2463 ret = ldb_extended(ldb, LDB_EXTENDED_WHOAMI_OID, NULL, &res);
2464 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2466 ext_res = res->extended;
2467 if (ext_res == NULL) {
2468 PyErr_SetString(PyExc_TypeError, "Got no exop reply");
2472 if (strcmp(ext_res->oid, LDB_EXTENDED_WHOAMI_OID) != 0) {
2473 PyErr_SetString(PyExc_TypeError, "Got wrong reply OID");
2477 len = talloc_get_size(ext_res->data);
2482 return PyUnicode_FromStringAndSize(ext_res->data, len);
2486 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2488 .read_fn = ldb_handler_copy,
2489 .write_clear_fn = ldb_handler_copy,
2490 .write_hex_fn = ldb_handler_copy,
2493 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self,
2494 PyObject *Py_UNUSED(ignored))
2496 struct ldb_context *ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
2499 ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2501 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2507 static PyMethodDef py_ldb_methods[] = {
2508 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
2509 "S.set_debug(callback) -> None\n"
2510 "Set callback for LDB debug messages.\n"
2511 "The callback should accept a debug level and debug text." },
2512 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
2513 "S.set_create_perms(mode) -> None\n"
2514 "Set mode to use when creating new LDB files." },
2515 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2516 "S.set_modules_dir(path) -> None\n"
2517 "Set path LDB should search for modules" },
2518 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
2519 "S.transaction_start() -> None\n"
2520 "Start a new transaction." },
2521 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2522 "S.transaction_prepare_commit() -> None\n"
2523 "prepare to commit a new transaction (2-stage commit)." },
2524 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
2525 "S.transaction_commit() -> None\n"
2526 "commit a new transaction." },
2527 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
2528 "S.transaction_cancel() -> None\n"
2529 "cancel a new transaction." },
2530 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
2532 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2534 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2536 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2538 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2540 { "connect", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_connect),
2541 METH_VARARGS|METH_KEYWORDS,
2542 "S.connect(url, flags=0, options=None) -> None\n"
2543 "Connect to a LDB URL." },
2544 { "modify", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_modify),
2545 METH_VARARGS|METH_KEYWORDS,
2546 "S.modify(message, controls=None, validate=False) -> None\n"
2547 "Modify an entry." },
2548 { "add", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_add),
2549 METH_VARARGS|METH_KEYWORDS,
2550 "S.add(message, controls=None) -> None\n"
2552 { "delete", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_delete),
2553 METH_VARARGS|METH_KEYWORDS,
2554 "S.delete(dn, controls=None) -> None\n"
2555 "Remove an entry." },
2556 { "rename", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_rename),
2557 METH_VARARGS|METH_KEYWORDS,
2558 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2559 "Rename an entry." },
2560 { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_search),
2561 METH_VARARGS|METH_KEYWORDS,
2562 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2563 "Search in a database.\n"
2565 ":param base: Optional base DN to search\n"
2566 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2567 ":param expression: Optional search expression\n"
2568 ":param attrs: Attributes to return (defaults to all)\n"
2569 ":param controls: Optional list of controls\n"
2570 ":return: ldb.Result object\n"
2572 { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction,
2573 py_ldb_search_iterator),
2574 METH_VARARGS|METH_KEYWORDS,
2575 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2576 "Search in a database.\n"
2578 ":param base: Optional base DN to search\n"
2579 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2580 ":param expression: Optional search expression\n"
2581 ":param attrs: Attributes to return (defaults to all)\n"
2582 ":param controls: Optional list of controls\n"
2583 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2584 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2586 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2588 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2590 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2592 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2593 "S.parse_ldif(ldif) -> iter(messages)\n"
2594 "Parse a string formatted using LDIF." },
2595 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2596 "S.write_ldif(message, changetype) -> ldif\n"
2597 "Print the message as a string formatted using LDIF." },
2598 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2599 "S.msg_diff(Message) -> Message\n"
2600 "Return an LDB Message of the difference between two Message objects." },
2601 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2602 "S.get_opaque(name) -> value\n"
2603 "Get an opaque value set on this LDB connection. \n"
2604 ":note: The returned value may not be useful in Python."
2606 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2607 "S.set_opaque(name, value) -> None\n"
2608 "Set an opaque value on this LDB connection. \n"
2609 ":note: Passing incorrect values may cause crashes." },
2610 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2611 "S.sequence_number(type) -> value\n"
2612 "Return the value of the sequence according to the requested type" },
2614 (PyCFunction)py_ldb_whoami,
2616 "S.whoami() -> value\n"
2617 "Return the RFC4532 whoami string",
2619 { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2620 "S._register_test_extensions() -> None\n"
2621 "Register internal extensions used in testing" },
2625 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2627 struct ldb_context *ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self);
2629 struct ldb_result *result;
2633 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2637 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2639 if (ret != LDB_SUCCESS) {
2640 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2644 count = result->count;
2646 talloc_free(result);
2649 PyErr_Format(PyExc_RuntimeError,
2650 "Searching for [%s] dn gave %u results!",
2651 ldb_dn_get_linearized(dn),
2659 static PySequenceMethods py_ldb_seq = {
2660 .sq_contains = (objobjproc)py_ldb_contains,
2663 static void py_ldb_dealloc(PyLdbObject *self)
2665 talloc_free(self->mem_ctx);
2666 Py_TYPE(self)->tp_free(self);
2669 static PyTypeObject PyLdb = {
2670 .tp_name = "ldb.Ldb",
2671 .tp_methods = py_ldb_methods,
2672 .tp_repr = (reprfunc)py_ldb_repr,
2673 .tp_new = py_ldb_new,
2674 .tp_init = (initproc)py_ldb_init,
2675 .tp_dealloc = (destructor)py_ldb_dealloc,
2676 .tp_getattro = PyObject_GenericGetAttr,
2677 .tp_basicsize = sizeof(PyLdbObject),
2678 .tp_doc = "Connection to a LDB database.",
2679 .tp_as_sequence = &py_ldb_seq,
2680 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2683 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2685 talloc_free(self->mem_ctx);
2686 Py_CLEAR(self->msgs);
2687 Py_CLEAR(self->referals);
2688 Py_CLEAR(self->controls);
2689 Py_TYPE(self)->tp_free(self);
2692 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2694 Py_INCREF(self->msgs);
2698 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2700 Py_INCREF(self->controls);
2701 return self->controls;
2704 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2706 Py_INCREF(self->referals);
2707 return self->referals;
2710 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2713 if (self->msgs == NULL) {
2714 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2717 size = PyList_Size(self->msgs);
2718 return PyLong_FromLong(size);
2721 static PyGetSetDef py_ldb_result_getset[] = {
2723 .name = discard_const_p(char, "controls"),
2724 .get = (getter)py_ldb_result_get_controls,
2727 .name = discard_const_p(char, "msgs"),
2728 .get = (getter)py_ldb_result_get_msgs,
2731 .name = discard_const_p(char, "referals"),
2732 .get = (getter)py_ldb_result_get_referals,
2735 .name = discard_const_p(char, "count"),
2736 .get = (getter)py_ldb_result_get_count,
2741 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2743 return PyObject_GetIter(self->msgs);
2746 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2748 return PySequence_Size(self->msgs);
2751 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2753 return PySequence_GetItem(self->msgs, idx);
2756 static PySequenceMethods py_ldb_result_seq = {
2757 .sq_length = (lenfunc)py_ldb_result_len,
2758 .sq_item = (ssizeargfunc)py_ldb_result_find,
2761 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2763 return PyUnicode_FromString("<ldb result>");
2767 static PyTypeObject PyLdbResult = {
2768 .tp_name = "ldb.Result",
2769 .tp_repr = (reprfunc)py_ldb_result_repr,
2770 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2771 .tp_iter = (getiterfunc)py_ldb_result_iter,
2772 .tp_getset = py_ldb_result_getset,
2773 .tp_getattro = PyObject_GenericGetAttr,
2774 .tp_basicsize = sizeof(PyLdbResultObject),
2775 .tp_as_sequence = &py_ldb_result_seq,
2776 .tp_doc = "LDB result.",
2777 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2780 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2782 Py_CLEAR(self->state.exception);
2783 TALLOC_FREE(self->mem_ctx);
2784 ZERO_STRUCT(self->state);
2785 Py_CLEAR(self->ldb);
2786 Py_TYPE(self)->tp_free(self);
2789 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2791 PyObject *py_ret = NULL;
2793 if (self->state.req == NULL) {
2794 PyErr_SetString(PyExc_RuntimeError,
2795 "ldb.SearchIterator request already finished");
2800 * TODO: do we want a non-blocking mode?
2801 * In future we may add an optional 'nonblocking'
2802 * argument to search_iterator().
2804 * For now we keep it simple and wait for at
2808 while (self->state.next == NULL) {
2811 if (self->state.result != NULL) {
2813 * We (already) got a final result from the server.
2815 * We stop the iteration and let
2816 * py_ldb_search_iterator_result() will deliver
2817 * the result details.
2819 TALLOC_FREE(self->state.req);
2820 PyErr_SetNone(PyExc_StopIteration);
2824 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2825 if (ret != LDB_SUCCESS) {
2826 struct ldb_context *ldb_ctx;
2827 TALLOC_FREE(self->state.req);
2828 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(self->ldb);
2830 * We stop the iteration and let
2831 * py_ldb_search_iterator_result() will deliver
2834 self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2835 ret, ldb_errstring(ldb_ctx));
2836 PyErr_SetNone(PyExc_StopIteration);
2841 py_ret = self->state.next->obj;
2842 self->state.next->obj = NULL;
2843 /* no TALLOC_FREE() as self->state.next is a list */
2844 talloc_free(self->state.next);
2848 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self,
2849 PyObject *Py_UNUSED(ignored))
2851 PyObject *py_ret = NULL;
2853 if (self->state.req != NULL) {
2854 PyErr_SetString(PyExc_RuntimeError,
2855 "ldb.SearchIterator request running");
2859 if (self->state.next != NULL) {
2860 PyErr_SetString(PyExc_RuntimeError,
2861 "ldb.SearchIterator not fully consumed.");
2865 if (self->state.exception != NULL) {
2866 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2867 Py_DECREF(self->state.exception);
2868 self->state.exception = NULL;
2872 if (self->state.result == NULL) {
2873 PyErr_SetString(PyExc_RuntimeError,
2874 "ldb.SearchIterator result already consumed");
2878 py_ret = self->state.result->obj;
2879 self->state.result->obj = NULL;
2880 TALLOC_FREE(self->state.result);
2884 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self,
2885 PyObject *Py_UNUSED(ignored))
2887 if (self->state.req == NULL) {
2888 PyErr_SetString(PyExc_RuntimeError,
2889 "ldb.SearchIterator request already finished");
2893 Py_CLEAR(self->state.exception);
2894 TALLOC_FREE(self->mem_ctx);
2895 ZERO_STRUCT(self->state);
2899 static PyMethodDef py_ldb_search_iterator_methods[] = {
2900 { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2901 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2902 { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2907 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2909 return PyUnicode_FromString("<ldb search iterator>");
2912 static PyTypeObject PyLdbSearchIterator = {
2913 .tp_name = "ldb.SearchIterator",
2914 .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2915 .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2916 .tp_iter = PyObject_SelfIter,
2917 .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2918 .tp_methods = py_ldb_search_iterator_methods,
2919 .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2920 .tp_doc = "LDB search_iterator.",
2921 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2925 * Create a ldb_message_element from a Python object.
2927 * This will accept any sequence objects that contains strings, or
2930 * A reference to set_obj might be borrowed.
2932 * @param mem_ctx Memory context
2933 * @param set_obj Python object to convert
2934 * @param flags ldb_message_element flags to set, if a new element is returned
2935 * @param attr_name Name of the attribute to set, if a new element is returned
2936 * @return New ldb_message_element, allocated as child of mem_ctx
2938 static struct ldb_message_element *PyObject_AsMessageElement(
2939 TALLOC_CTX *mem_ctx,
2942 const char *attr_name)
2944 struct ldb_message_element *me;
2945 const char *msg = NULL;
2949 if (pyldb_MessageElement_Check(set_obj)) {
2950 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2951 /* We have to talloc_reference() the memory context, not the pointer
2952 * which may not actually be it's own context */
2953 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2954 return pyldb_MessageElement_AsMessageElement(set_obj);
2959 me = talloc(mem_ctx, struct ldb_message_element);
2965 me->name = talloc_strdup(me, attr_name);
2966 if (me->name == NULL) {
2972 if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) {
2974 me->values = talloc_array(me, struct ldb_val, me->num_values);
2975 if (PyBytes_Check(set_obj)) {
2977 result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
2984 msg = PyUnicode_AsUTF8AndSize(set_obj, &size);
2990 me->values[0].data = talloc_memdup(me,
2991 (const uint8_t *)msg,
2993 me->values[0].length = size;
2994 } else if (PySequence_Check(set_obj)) {
2996 me->num_values = PySequence_Size(set_obj);
2997 me->values = talloc_array(me, struct ldb_val, me->num_values);
2998 for (i = 0; i < me->num_values; i++) {
2999 PyObject *obj = PySequence_GetItem(set_obj, i);
3000 if (PyBytes_Check(obj)) {
3002 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
3008 } else if (PyUnicode_Check(obj)) {
3009 msg = PyUnicode_AsUTF8AndSize(obj, &size);
3015 PyErr_Format(PyExc_TypeError,
3016 "Expected string as element %zd in list", i);
3020 me->values[i].data = talloc_memdup(me,
3021 (const uint8_t *)msg,
3023 me->values[i].length = size;
3026 PyErr_Format(PyExc_TypeError,
3027 "String or List type expected for '%s' attribute", attr_name);
3036 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
3037 struct ldb_message_element *me)
3042 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3043 result = PyList_New(me->num_values);
3044 if (result == NULL) {
3048 for (i = 0; i < me->num_values; i++) {
3049 PyObject *obj = NULL;
3052 obj = PyObject_FromLdbValue(&me->values[i]);
3058 ret = PyList_SetItem(result, i, obj);
3069 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
3072 if (!PyArg_ParseTuple(args, "I", &i))
3074 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
3077 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
3080 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
3082 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3083 return PyLong_FromLong(el->flags);
3086 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
3089 struct ldb_message_element *el;
3090 if (!PyArg_ParseTuple(args, "I", &flags))
3093 el = pyldb_MessageElement_AsMessageElement(self);
3098 static PyMethodDef py_ldb_msg_element_methods[] = {
3099 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
3100 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
3101 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
3105 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
3107 return pyldb_MessageElement_AsMessageElement(self)->num_values;
3110 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
3112 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3113 if (idx < 0 || idx >= el->num_values) {
3114 PyErr_SetString(PyExc_IndexError, "Out of range");
3117 return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
3120 static PySequenceMethods py_ldb_msg_element_seq = {
3121 .sq_length = (lenfunc)py_ldb_msg_element_len,
3122 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
3125 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3128 if (!pyldb_MessageElement_Check(other)) {
3129 Py_INCREF(Py_NotImplemented);
3130 return Py_NotImplemented;
3132 ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3133 pyldb_MessageElement_AsMessageElement(other));
3134 return richcmp(ret, op);
3137 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3139 PyObject *el = ldb_msg_element_to_set(NULL,
3140 pyldb_MessageElement_AsMessageElement(self));
3141 PyObject *ret = PyObject_GetIter(el);
3146 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3148 TALLOC_CTX *ret_mem_ctx = NULL;
3149 PyLdbMessageElementObject *ret;
3151 ret_mem_ctx = talloc_new(NULL);
3152 if (ret_mem_ctx == NULL) {
3153 return PyErr_NoMemory();
3156 if (talloc_reference(ret_mem_ctx, mem_ctx) == NULL) {
3157 talloc_free(ret_mem_ctx);
3162 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3164 talloc_free(ret_mem_ctx);
3168 ret->mem_ctx = ret_mem_ctx;
3170 return (PyObject *)ret;
3173 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3175 PyObject *py_elements = NULL;
3176 struct ldb_message_element *el;
3177 unsigned int flags = 0;
3179 const char * const kwnames[] = { "elements", "flags", "name", NULL };
3180 PyLdbMessageElementObject *ret;
3181 TALLOC_CTX *mem_ctx;
3182 const char *msg = NULL;
3186 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3187 discard_const_p(char *, kwnames),
3188 &py_elements, &flags, &name))
3191 mem_ctx = talloc_new(NULL);
3192 if (mem_ctx == NULL) {
3197 el = talloc_zero(mem_ctx, struct ldb_message_element);
3200 talloc_free(mem_ctx);
3204 if (py_elements != NULL) {
3206 if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) {
3209 el->values = talloc_array(el, struct ldb_val, 1);
3210 if (el->values == NULL) {
3211 talloc_free(mem_ctx);
3215 if (PyBytes_Check(py_elements)) {
3216 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3219 msg = PyUnicode_AsUTF8AndSize(py_elements, &size);
3220 result = (msg == NULL) ? -1 : 0;
3223 talloc_free(mem_ctx);
3226 el->values[0].data = talloc_memdup(el->values,
3227 (const uint8_t *)msg, size + 1);
3228 el->values[0].length = size;
3229 } else if (PySequence_Check(py_elements)) {
3230 el->num_values = PySequence_Size(py_elements);
3231 el->values = talloc_array(el, struct ldb_val, el->num_values);
3232 if (el->values == NULL) {
3233 talloc_free(mem_ctx);
3237 for (i = 0; i < el->num_values; i++) {
3238 PyObject *item = PySequence_GetItem(py_elements, i);
3240 talloc_free(mem_ctx);
3243 if (PyBytes_Check(item)) {
3245 result = PyBytes_AsStringAndSize(item, &_msg, &size);
3247 } else if (PyUnicode_Check(item)) {
3248 msg = PyUnicode_AsUTF8AndSize(item, &size);
3249 result = (msg == NULL) ? -1 : 0;
3251 PyErr_Format(PyExc_TypeError,
3252 "Expected string as element %zd in list", i);
3256 talloc_free(mem_ctx);
3259 el->values[i].data = talloc_memdup(el,
3260 (const uint8_t *)msg, size+1);
3261 el->values[i].length = size;
3264 PyErr_SetString(PyExc_TypeError,
3265 "Expected string or list");
3266 talloc_free(mem_ctx);
3273 el->name = talloc_strdup(el, name);
3274 if (el->name == NULL) {
3275 talloc_free(mem_ctx);
3276 return PyErr_NoMemory();
3280 ret = PyObject_New(PyLdbMessageElementObject, type);
3282 talloc_free(mem_ctx);
3286 ret->mem_ctx = mem_ctx;
3288 return (PyObject *)ret;
3291 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3293 char *element_str = NULL;
3295 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3296 PyObject *ret, *repr;
3298 for (i = 0; i < el->num_values; i++) {
3299 PyObject *o = py_ldb_msg_element_find(self, i);
3300 repr = PyObject_Repr(o);
3301 if (element_str == NULL)
3302 element_str = talloc_strdup(NULL, PyUnicode_AsUTF8(repr));
3304 element_str = talloc_asprintf_append(element_str, ",%s", PyUnicode_AsUTF8(repr));
3307 if (element_str == NULL) {
3308 return PyErr_NoMemory();
3312 if (element_str != NULL) {
3313 ret = PyUnicode_FromFormat("MessageElement([%s])", element_str);
3314 talloc_free(element_str);
3316 ret = PyUnicode_FromString("MessageElement([])");
3322 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3324 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3326 if (el->num_values == 1)
3327 return PyUnicode_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3332 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3334 talloc_free(self->mem_ctx);
3338 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3340 return wrap_text("MessageElementTextWrapper", self);
3343 static PyGetSetDef py_ldb_msg_element_getset[] = {
3345 .name = discard_const_p(char, "text"),
3346 .get = (getter)py_ldb_msg_element_get_text,
3351 static PyTypeObject PyLdbMessageElement = {
3352 .tp_name = "ldb.MessageElement",
3353 .tp_basicsize = sizeof(PyLdbMessageElementObject),
3354 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3355 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3356 .tp_str = (reprfunc)py_ldb_msg_element_str,
3357 .tp_methods = py_ldb_msg_element_methods,
3358 .tp_getset = py_ldb_msg_element_getset,
3359 .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3360 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3361 .tp_as_sequence = &py_ldb_msg_element_seq,
3362 .tp_new = py_ldb_msg_element_new,
3363 .tp_flags = Py_TPFLAGS_DEFAULT,
3364 .tp_doc = "An element of a Message",
3368 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3373 struct ldb_message *msg;
3374 struct ldb_context *ldb_ctx;
3375 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3377 if (!PyArg_ParseTuple(args, "O!O!|I",
3378 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3383 /* mask only flags we are going to use */
3384 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3386 PyErr_SetString(PyExc_ValueError,
3387 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3388 " expected as mod_flag value");
3392 ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT(py_ldb);
3394 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3399 py_ret = PyLdbMessage_FromMessage(msg);
3401 talloc_unlink(ldb_ctx, msg);
3406 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3409 if (!PyArg_ParseTuple(args, "s", &name))
3412 ldb_msg_remove_attr(self->msg, name);
3417 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self,
3418 PyObject *Py_UNUSED(ignored))
3420 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3421 Py_ssize_t i, j = 0;
3422 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3427 if (msg->dn != NULL) {
3428 PyObject *py_dn = NULL;
3431 py_dn = PyUnicode_FromString("dn");
3432 if (py_dn == NULL) {
3437 ret = PyList_SetItem(obj, j, py_dn);
3446 for (i = 0; i < msg->num_elements; i++) {
3447 PyObject *py_name = NULL;
3450 py_name = PyUnicode_FromString(msg->elements[i].name);
3451 if (py_name == NULL) {
3456 ret = PyList_SetItem(obj, j, py_name);
3468 static int py_ldb_msg_contains(PyLdbMessageObject *self, PyObject *py_name)
3470 struct ldb_message_element *el = NULL;
3471 const char *name = NULL;
3472 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3473 name = PyUnicode_AsUTF8(py_name);
3477 if (!ldb_attr_cmp(name, "dn")) {
3480 el = ldb_msg_find_element(msg, name);
3481 return el != NULL ? 1 : 0;
3484 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3486 struct ldb_message_element *el = NULL;
3487 const char *name = NULL;
3488 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3489 name = PyUnicode_AsUTF8(py_name);
3493 if (!ldb_attr_cmp(name, "dn")) {
3494 return pyldb_Dn_FromDn(msg->dn);
3496 el = ldb_msg_find_element(msg, name);
3498 PyErr_SetString(PyExc_KeyError, "No such element");
3502 return PyLdbMessageElement_FromMessageElement(el, msg->elements);
3505 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3507 PyObject *def = NULL;
3508 const char *kwnames[] = { "name", "default", "idx", NULL };
3509 const char *name = NULL;
3511 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3512 struct ldb_message_element *el;
3514 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3515 discard_const_p(char *, kwnames), &name, &def, &idx)) {
3519 if (strcasecmp(name, "dn") == 0) {
3520 return pyldb_Dn_FromDn(msg->dn);
3523 el = ldb_msg_find_element(msg, name);
3525 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3534 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3537 return PyObject_FromLdbValue(&el->values[idx]);
3540 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self,
3541 PyObject *Py_UNUSED(ignored))
3543 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3544 Py_ssize_t i, j = 0;
3545 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3547 return PyErr_NoMemory();
3549 if (msg->dn != NULL) {
3550 PyObject *value = NULL;
3551 PyObject *obj = pyldb_Dn_FromDn(msg->dn);
3553 value = Py_BuildValue("(sO)", "dn", obj);
3555 if (value == NULL) {
3559 res = PyList_SetItem(l, 0, value);
3566 for (i = 0; i < msg->num_elements; i++, j++) {
3567 PyObject *value = NULL;
3568 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3570 value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3572 if (value == NULL ) {
3576 res = PyList_SetItem(l, j, value);
3585 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self,
3586 PyObject *Py_UNUSED(ignored))
3588 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3590 PyObject *l = PyList_New(msg->num_elements);
3594 for (i = 0; i < msg->num_elements; i++) {
3595 PyObject *msg_el = NULL;
3598 msg_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3599 if (msg_el == NULL) {
3604 ret = PyList_SetItem(l, i, msg_el);
3614 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3616 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3617 PyLdbMessageElementObject *py_element;
3619 struct ldb_message_element *el;
3620 struct ldb_message_element *el_new;
3622 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
3625 el = py_element->el;
3627 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3630 if (el->name == NULL) {
3631 PyErr_SetString(PyExc_ValueError,
3632 "The element has no name");
3635 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3636 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3638 /* now deep copy all attribute values */
3639 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3640 if (el_new->values == NULL) {
3644 el_new->num_values = el->num_values;
3646 for (i = 0; i < el->num_values; i++) {
3647 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
3648 if (el_new->values[i].data == NULL
3649 && el->values[i].length != 0) {
3658 static PyMethodDef py_ldb_msg_methods[] = {
3659 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
3660 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3661 "Class method to create ldb.Message object from Dictionary.\n"
3662 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3663 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
3664 "S.keys() -> list\n\n"
3665 "Return sequence of all attribute names." },
3666 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
3667 "S.remove(name)\n\n"
3668 "Remove all entries for attributes with the specified name."},
3669 { "get", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_msg_get),
3670 METH_VARARGS | METH_KEYWORDS,
3671 "msg.get(name,default=None,idx=None) -> string\n"
3672 "idx is the index into the values array\n"
3673 "if idx is None, then a list is returned\n"
3674 "if idx is not None, then the element with that index is returned\n"
3675 "if you pass the special name 'dn' then the DN object is returned\n"},
3676 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
3677 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
3678 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
3679 "S.add(element)\n\n"
3680 "Add an element to this message." },
3684 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
3686 PyObject *list, *iter;
3688 list = py_ldb_msg_keys(self, NULL);
3689 iter = PyObject_GetIter(list);
3694 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
3696 const char *attr_name;
3698 attr_name = PyUnicode_AsUTF8(name);
3699 if (attr_name == NULL) {
3700 PyErr_SetNone(PyExc_TypeError);
3704 if (value == NULL) {
3706 ldb_msg_remove_attr(self->msg, attr_name);
3709 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
3710 value, 0, attr_name);
3714 if (el->name == NULL) {
3716 * If ‘value’ is a MessageElement,
3717 * PyObject_AsMessageElement() will have returned a
3718 * reference to it without setting the name. We don’t
3719 * want to modify the original object to set the name
3720 * ourselves, but making a copy would result in
3721 * different behaviour for a caller relying on a
3722 * reference being kept. Rather than continue with a
3723 * NULL name (and probably fail later on), let’s catch
3724 * this potential mistake early.
3726 PyErr_SetString(PyExc_ValueError, "MessageElement has no name set");
3727 talloc_unlink(self->msg, el);
3730 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
3731 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
3732 if (ret != LDB_SUCCESS) {
3733 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
3734 talloc_unlink(self->msg, el);
3741 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
3743 return pyldb_Message_AsMessage(self)->num_elements;
3746 static PySequenceMethods py_ldb_msg_sequence = {
3747 .sq_contains = (objobjproc)py_ldb_msg_contains,
3750 static PyMappingMethods py_ldb_msg_mapping = {
3751 .mp_length = (lenfunc)py_ldb_msg_length,
3752 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
3753 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
3756 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3758 const char * const kwnames[] = { "dn", NULL };
3759 struct ldb_message *ret;
3760 TALLOC_CTX *mem_ctx;
3761 PyObject *pydn = NULL;
3762 PyLdbMessageObject *py_ret;
3764 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
3765 discard_const_p(char *, kwnames),
3769 mem_ctx = talloc_new(NULL);
3770 if (mem_ctx == NULL) {
3775 ret = ldb_msg_new(mem_ctx);
3777 talloc_free(mem_ctx);
3784 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
3785 talloc_free(mem_ctx);
3788 ret->dn = talloc_reference(ret, dn);
3789 if (ret->dn == NULL) {
3790 talloc_free(mem_ctx);
3791 return PyErr_NoMemory();
3795 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
3796 if (py_ret == NULL) {
3798 talloc_free(mem_ctx);
3802 py_ret->mem_ctx = mem_ctx;
3804 return (PyObject *)py_ret;
3807 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
3809 TALLOC_CTX *mem_ctx = NULL;
3810 struct ldb_message *msg_ref = NULL;
3811 PyLdbMessageObject *ret;
3813 mem_ctx = talloc_new(NULL);
3814 if (mem_ctx == NULL) {
3815 return PyErr_NoMemory();
3818 msg_ref = talloc_reference(mem_ctx, msg);
3819 if (msg_ref == NULL) {
3820 talloc_free(mem_ctx);
3821 return PyErr_NoMemory();
3824 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3826 talloc_free(mem_ctx);
3830 ret->mem_ctx = mem_ctx;
3832 return (PyObject *)ret;
3835 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3837 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3838 return pyldb_Dn_FromDn(msg->dn);
3841 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3843 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3844 struct ldb_dn *dn = NULL;
3845 if (value == NULL) {
3846 PyErr_SetString(PyExc_AttributeError, "cannot delete dn");
3849 if (!pyldb_Dn_Check(value)) {
3850 PyErr_SetString(PyExc_TypeError, "expected dn");
3854 dn = talloc_reference(msg, pyldb_Dn_AS_DN(value));
3864 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
3866 return wrap_text("MessageTextWrapper", self);
3869 static PyGetSetDef py_ldb_msg_getset[] = {
3871 .name = discard_const_p(char, "dn"),
3872 .get = (getter)py_ldb_msg_get_dn,
3873 .set = (setter)py_ldb_msg_set_dn,
3876 .name = discard_const_p(char, "text"),
3877 .get = (getter)py_ldb_msg_get_text,
3882 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3884 PyObject *dict = PyDict_New(), *ret, *repr;
3885 const char *repr_str = NULL;
3889 if (PyDict_Update(dict, (PyObject *)self) != 0) {
3893 repr = PyObject_Repr(dict);
3898 repr_str = PyUnicode_AsUTF8(repr);
3899 if (repr_str == NULL) {
3904 ret = PyUnicode_FromFormat("Message(%s)", repr_str);
3910 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3912 talloc_free(self->mem_ctx);
3916 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3917 PyLdbMessageObject *py_msg2, int op)
3919 struct ldb_message *msg1, *msg2;
3923 if (!PyLdbMessage_Check(py_msg2)) {
3924 Py_INCREF(Py_NotImplemented);
3925 return Py_NotImplemented;
3928 msg1 = pyldb_Message_AsMessage(py_msg1),
3929 msg2 = pyldb_Message_AsMessage(py_msg2);
3931 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3932 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3934 return richcmp(ret, op);
3938 ret = msg1->num_elements - msg2->num_elements;
3940 return richcmp(ret, op);
3943 for (i = 0; i < msg1->num_elements; i++) {
3944 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3945 &msg2->elements[i]);
3947 return richcmp(ret, op);
3950 ret = ldb_msg_element_compare(&msg1->elements[i],
3951 &msg2->elements[i]);
3953 return richcmp(ret, op);
3957 return richcmp(0, op);
3960 static PyTypeObject PyLdbMessage = {
3961 .tp_name = "ldb.Message",
3962 .tp_methods = py_ldb_msg_methods,
3963 .tp_getset = py_ldb_msg_getset,
3964 .tp_as_sequence = &py_ldb_msg_sequence,
3965 .tp_as_mapping = &py_ldb_msg_mapping,
3966 .tp_basicsize = sizeof(PyLdbMessageObject),
3967 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3968 .tp_new = py_ldb_msg_new,
3969 .tp_repr = (reprfunc)py_ldb_msg_repr,
3970 .tp_flags = Py_TPFLAGS_DEFAULT,
3971 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3972 .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3973 .tp_doc = "A LDB Message",
3976 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3978 talloc_free(self->mem_ctx);
3982 static PyTypeObject PyLdbTree = {
3983 .tp_name = "ldb.Tree",
3984 .tp_basicsize = sizeof(PyLdbTreeObject),
3985 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3986 .tp_flags = Py_TPFLAGS_DEFAULT,
3987 .tp_doc = "A search tree",
3990 static PyObject *py_timestring(PyObject *module, PyObject *args)
3992 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3993 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3997 if (!PyArg_ParseTuple(args, "l", &t_val))
3999 tresult = ldb_timestring(NULL, (time_t) t_val);
4000 if (tresult == NULL) {
4002 * Most likely EOVERFLOW from gmtime()
4004 PyErr_SetFromErrno(PyExc_OSError);
4007 ret = PyUnicode_FromString(tresult);
4008 talloc_free(tresult);
4012 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
4016 if (!PyArg_ParseTuple(args, "s", &str)) {
4019 t = ldb_string_to_time(str);
4021 if (t == 0 && errno != 0) {
4022 PyErr_SetFromErrno(PyExc_ValueError);
4025 return PyLong_FromLong(t);
4028 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4031 if (!PyArg_ParseTuple(args, "s", &name))
4033 return PyBool_FromLong(ldb_valid_attr_name(name));
4037 encode a string using RFC2254 rules
4039 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4041 char *str, *encoded;
4042 Py_ssize_t size = 0;
4046 if (!PyArg_ParseTuple(args, "s#", &str, &size))
4048 val.data = (uint8_t *)str;
4051 encoded = ldb_binary_encode(NULL, val);
4052 if (encoded == NULL) {
4053 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4056 ret = PyUnicode_FromString(encoded);
4057 talloc_free(encoded);
4062 decode a string using RFC2254 rules
4064 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4070 if (!PyArg_ParseTuple(args, "s", &str))
4073 val = ldb_binary_decode(NULL, str);
4074 if (val.data == NULL) {
4075 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4078 ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4079 talloc_free(val.data);
4083 static PyMethodDef py_ldb_global_methods[] = {
4084 { "timestring", py_timestring, METH_VARARGS,
4085 "S.timestring(int) -> string\n\n"
4086 "Generate a LDAP time string from a UNIX timestamp" },
4087 { "string_to_time", py_string_to_time, METH_VARARGS,
4088 "S.string_to_time(string) -> int\n\n"
4089 "Parse a LDAP time string into a UNIX timestamp." },
4090 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4091 "S.valid_attr_name(name) -> bool\n\n"
4092 "Check whether the supplied name is a valid attribute name." },
4093 { "binary_encode", py_binary_encode, METH_VARARGS,
4094 "S.binary_encode(string) -> string\n\n"
4095 "Perform a RFC2254 binary encoding on a string" },
4096 { "binary_decode", py_binary_decode, METH_VARARGS,
4097 "S.binary_decode(string) -> string\n\n"
4098 "Perform a RFC2254 binary decode on a string" },
4102 #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."
4104 static struct PyModuleDef moduledef = {
4105 PyModuleDef_HEAD_INIT,
4107 .m_doc = MODULE_DOC,
4109 .m_methods = py_ldb_global_methods,
4112 static PyObject* module_init(void)
4116 PyLdbBytesType.tp_base = &PyBytes_Type;
4117 if (PyType_Ready(&PyLdbBytesType) < 0) {
4121 if (PyType_Ready(&PyLdbDn) < 0)
4124 if (PyType_Ready(&PyLdbMessage) < 0)
4127 if (PyType_Ready(&PyLdbMessageElement) < 0)
4130 if (PyType_Ready(&PyLdb) < 0)
4133 if (PyType_Ready(&PyLdbTree) < 0)
4136 if (PyType_Ready(&PyLdbResult) < 0)
4139 if (PyType_Ready(&PyLdbSearchIterator) < 0)
4142 if (PyType_Ready(&PyLdbControl) < 0)
4145 m = PyModule_Create(&moduledef);
4149 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4151 ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4152 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4153 ADD_LDB_INT(SEQ_NEXT);
4154 ADD_LDB_INT(SCOPE_DEFAULT);
4155 ADD_LDB_INT(SCOPE_BASE);
4156 ADD_LDB_INT(SCOPE_ONELEVEL);
4157 ADD_LDB_INT(SCOPE_SUBTREE);
4159 ADD_LDB_INT(CHANGETYPE_NONE);
4160 ADD_LDB_INT(CHANGETYPE_ADD);
4161 ADD_LDB_INT(CHANGETYPE_DELETE);
4162 ADD_LDB_INT(CHANGETYPE_MODIFY);
4163 ADD_LDB_INT(CHANGETYPE_MODRDN);
4165 ADD_LDB_INT(FLAG_MOD_ADD);
4166 ADD_LDB_INT(FLAG_MOD_REPLACE);
4167 ADD_LDB_INT(FLAG_MOD_DELETE);
4168 ADD_LDB_INT(FLAG_FORCE_NO_BASE64_LDIF);
4170 ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4171 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4172 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4173 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4175 ADD_LDB_INT(SUCCESS);
4176 ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4177 ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4178 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4179 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4180 ADD_LDB_INT(ERR_COMPARE_FALSE);
4181 ADD_LDB_INT(ERR_COMPARE_TRUE);
4182 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4183 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4184 ADD_LDB_INT(ERR_REFERRAL);
4185 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4186 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4187 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4188 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4189 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4190 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4191 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4192 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4193 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4194 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4195 ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4196 ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4197 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4198 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4199 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4200 ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4201 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4202 ADD_LDB_INT(ERR_BUSY);
4203 ADD_LDB_INT(ERR_UNAVAILABLE);
4204 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4205 ADD_LDB_INT(ERR_LOOP_DETECT);
4206 ADD_LDB_INT(ERR_NAMING_VIOLATION);
4207 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4208 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4209 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4210 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4211 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4212 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4213 ADD_LDB_INT(ERR_OTHER);
4215 ADD_LDB_INT(FLG_RDONLY);
4216 ADD_LDB_INT(FLG_NOSYNC);
4217 ADD_LDB_INT(FLG_RECONNECT);
4218 ADD_LDB_INT(FLG_NOMMAP);
4219 ADD_LDB_INT(FLG_SHOW_BINARY);
4220 ADD_LDB_INT(FLG_ENABLE_TRACING);
4221 ADD_LDB_INT(FLG_DONT_CREATE_DB);
4223 ADD_LDB_INT(PACKING_FORMAT);
4224 ADD_LDB_INT(PACKING_FORMAT_V2);
4226 /* Historical misspelling */
4227 PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
4229 PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
4231 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
4232 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
4235 Py_INCREF(&PyLdbDn);
4236 Py_INCREF(&PyLdbMessage);
4237 Py_INCREF(&PyLdbMessageElement);
4238 Py_INCREF(&PyLdbTree);
4239 Py_INCREF(&PyLdbResult);
4240 Py_INCREF(&PyLdbControl);
4242 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
4243 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
4244 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
4245 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
4246 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
4247 PyModule_AddObject(m, "Result", (PyObject *)&PyLdbResult);
4248 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
4250 PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
4252 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4254 ADD_LDB_STRING(SYNTAX_DN);
4255 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
4256 ADD_LDB_STRING(SYNTAX_INTEGER);
4257 ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER);
4258 ADD_LDB_STRING(SYNTAX_BOOLEAN);
4259 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
4260 ADD_LDB_STRING(SYNTAX_UTC_TIME);
4261 ADD_LDB_STRING(OID_COMPARATOR_AND);
4262 ADD_LDB_STRING(OID_COMPARATOR_OR);
4267 PyMODINIT_FUNC PyInit_ldb(void);
4268 PyMODINIT_FUNC PyInit_ldb(void)
4270 return module_init();