2 Unix SMB/CIFS implementation.
4 Python interface to ldb.
6 Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7 Copyright (C) 2006 Simo Sorce <idra@samba.org>
8 Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9 Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10 Copyright (C) 2009-2011 Andrew Tridgell
11 Copyright (C) 2009-2011 Andrew Bartlett
13 ** NOTE! The following LGPL license applies to the ldb
14 ** library. This does NOT imply that all of Samba is released
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public
19 License as published by the Free Software Foundation; either
20 version 3 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 #include "ldb_private.h"
33 #include "ldb_handlers.h"
35 #include "dlinklist.h"
37 /* discard signature of 'func' in favour of 'target_sig' */
38 #define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func
40 struct py_ldb_search_iterator_reply;
47 struct ldb_request *req;
48 struct py_ldb_search_iterator_reply *next;
49 struct py_ldb_search_iterator_reply *result;
52 } PyLdbSearchIteratorObject;
54 struct py_ldb_search_iterator_reply {
55 struct py_ldb_search_iterator_reply *prev, *next;
56 PyLdbSearchIteratorObject *py_iter;
61 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
62 static PyObject *PyExc_LdbError;
64 static PyTypeObject PyLdbControl;
65 static PyTypeObject PyLdbResult;
66 static PyTypeObject PyLdbSearchIterator;
67 static PyTypeObject PyLdbMessage;
68 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
69 static PyTypeObject PyLdbModule;
70 static PyTypeObject PyLdbDn;
71 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
72 static PyTypeObject PyLdb;
73 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
74 static PyTypeObject PyLdbMessageElement;
75 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
77 static PyTypeObject PyLdbTree;
78 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
79 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
80 static struct ldb_message_element *PyObject_AsMessageElement(
84 const char *attr_name);
85 static PyTypeObject PyLdbBytesType;
87 #if PY_MAJOR_VERSION >= 3
88 #define PyStr_Check PyUnicode_Check
89 #define PyStr_FromString PyUnicode_FromString
90 #define PyStr_FromStringAndSize PyUnicode_FromStringAndSize
91 #define PyStr_FromFormat PyUnicode_FromFormat
92 #define PyStr_FromFormatV PyUnicode_FromFormatV
93 #define PyStr_AsUTF8 PyUnicode_AsUTF8
94 #define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize
95 #define PyInt_FromLong PyLong_FromLong
97 #define PYARG_STR_UNI "es"
99 static PyObject *PyLdbBytes_FromStringAndSize(const char *msg, int size)
101 PyObject* result = NULL;
102 PyObject* args = NULL;
103 args = Py_BuildValue("(y#)", msg, size);
104 result = PyLdbBytesType.tp_new(&PyLdbBytesType, args, NULL);
109 #define PyStr_Check PyString_Check
110 #define PyStr_FromString PyString_FromString
111 #define PyStr_FromStringAndSize PyString_FromStringAndSize
112 #define PyStr_FromFormat PyString_FromFormat
113 #define PyStr_FromFormatV PyString_FromFormatV
114 #define PyStr_AsUTF8 PyString_AsString
115 #define PyLdbBytes_FromStringAndSize PyString_FromStringAndSize
117 #define PYARG_STR_UNI "et"
119 const char *PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr);
121 PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr)
123 const char * ret = PyString_AsString(pystr);
126 *sizeptr = PyString_Size(pystr);
131 static PyObject *richcmp(int cmp_val, int op)
135 case Py_LT: ret = cmp_val < 0; break;
136 case Py_LE: ret = cmp_val <= 0; break;
137 case Py_EQ: ret = cmp_val == 0; break;
138 case Py_NE: ret = cmp_val != 0; break;
139 case Py_GT: ret = cmp_val > 0; break;
140 case Py_GE: ret = cmp_val >= 0; break;
142 Py_INCREF(Py_NotImplemented);
143 return Py_NotImplemented;
145 return PyBool_FromLong(ret);
149 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
151 if (self->data != NULL) {
152 char* control = ldb_control_to_string(self->mem_ctx, self->data);
153 if (control == NULL) {
157 return PyStr_FromString(control);
159 return PyStr_FromString("ldb control");
163 static void py_ldb_control_dealloc(PyLdbControlObject *self)
165 if (self->mem_ctx != NULL) {
166 talloc_free(self->mem_ctx);
169 Py_TYPE(self)->tp_free(self);
172 /* Create a text (rather than bytes) interface for a LDB result object */
173 static PyObject *wrap_text(const char *type, PyObject *wrapped)
175 PyObject *mod, *cls, *constructor, *inst;
176 mod = PyImport_ImportModule("_ldb_text");
179 cls = PyObject_GetAttrString(mod, type);
185 constructor = PyObject_GetAttrString(cls, "_wrap");
187 if (constructor == NULL) {
190 inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped);
191 Py_DECREF(constructor);
195 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self,
196 PyObject *Py_UNUSED(ignored))
198 return PyStr_FromString(self->data->oid);
201 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self,
202 PyObject *Py_UNUSED(ignored))
204 return PyBool_FromLong(self->data->critical);
207 static int py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
209 if (PyObject_IsTrue(value)) {
210 self->data->critical = true;
212 self->data->critical = false;
217 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
220 const char * const kwnames[] = { "ldb", "data", NULL };
221 struct ldb_control *parsed_controls;
222 PyLdbControlObject *ret;
225 struct ldb_context *ldb_ctx;
227 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
228 discard_const_p(char *, kwnames),
229 &PyLdb, &py_ldb, &data))
232 mem_ctx = talloc_new(NULL);
233 if (mem_ctx == NULL) {
238 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
239 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
241 if (!parsed_controls) {
242 talloc_free(mem_ctx);
243 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
247 ret = PyObject_New(PyLdbControlObject, type);
250 talloc_free(mem_ctx);
254 ret->mem_ctx = mem_ctx;
256 ret->data = talloc_move(mem_ctx, &parsed_controls);
257 if (ret->data == NULL) {
260 talloc_free(mem_ctx);
264 return (PyObject *)ret;
267 static PyGetSetDef py_ldb_control_getset[] = {
269 .name = discard_const_p(char, "oid"),
270 .get = (getter)py_ldb_control_get_oid,
273 .name = discard_const_p(char, "critical"),
274 .get = (getter)py_ldb_control_get_critical,
275 .set = (setter)py_ldb_control_set_critical,
280 static PyTypeObject PyLdbControl = {
281 .tp_name = "ldb.control",
282 .tp_dealloc = (destructor)py_ldb_control_dealloc,
283 .tp_getattro = PyObject_GenericGetAttr,
284 .tp_basicsize = sizeof(PyLdbControlObject),
285 .tp_getset = py_ldb_control_getset,
286 .tp_doc = "LDB control.",
287 .tp_str = (reprfunc)py_ldb_control_str,
288 .tp_new = py_ldb_control_new,
289 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
292 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
294 if (ret == LDB_ERR_PYTHON_EXCEPTION)
295 return; /* Python exception should already be set, just keep that */
297 PyErr_SetObject(error,
298 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
299 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
301 static PyObject *py_ldb_bytes_str(PyBytesObject *self)
306 if (!PyBytes_Check(self)) {
307 PyErr_Format(PyExc_TypeError,"Unexpected type");
310 result = PyBytes_AsStringAndSize((PyObject *)self, &msg, &size);
312 PyErr_Format(PyExc_TypeError, "Failed to extract bytes");
315 return PyUnicode_FromStringAndSize(msg, size);
318 static PyTypeObject PyLdbBytesType = {
319 PyVarObject_HEAD_INIT(NULL, 0)
320 .tp_name = "ldb.bytes",
321 .tp_doc = "str/bytes (with custom str)",
322 .tp_str = (reprfunc)py_ldb_bytes_str,
323 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
326 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
328 return PyLdbBytes_FromStringAndSize((const char *)val->data, val->length);
331 static PyObject *PyStr_FromLdbValue(const struct ldb_val *val)
333 return PyStr_FromStringAndSize((const char *)val->data, val->length);
337 * Create a Python object from a ldb_result.
339 * @param result LDB result to convert
340 * @return Python object with converted result (a list object)
342 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
344 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
345 PyLdbControlObject *ctrl;
346 if (ctl_ctx == NULL) {
351 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
353 talloc_free(ctl_ctx);
357 ctrl->mem_ctx = ctl_ctx;
358 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
359 if (ctrl->data == NULL) {
364 return (PyObject*) ctrl;
368 * Create a Python object from a ldb_result.
370 * @param result LDB result to convert
371 * @return Python object with converted result (a list object)
373 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
375 PyLdbResultObject *ret;
376 PyObject *list, *controls, *referals;
379 if (result == NULL) {
383 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
389 list = PyList_New(result->count);
396 for (i = 0; i < result->count; i++) {
397 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
400 ret->mem_ctx = talloc_new(NULL);
401 if (ret->mem_ctx == NULL) {
410 if (result->controls) {
412 while (result->controls[i]) {
415 controls = PyList_New(i);
416 if (controls == NULL) {
421 for (i=0; result->controls[i]; i++) {
422 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
429 PyList_SetItem(controls, i, ctrl);
433 * No controls so we keep an empty list
435 controls = PyList_New(0);
436 if (controls == NULL) {
443 ret->controls = controls;
447 while (result->refs && result->refs[i]) {
451 referals = PyList_New(i);
452 if (referals == NULL) {
458 for (i = 0;result->refs && result->refs[i]; i++) {
459 PyList_SetItem(referals, i, PyStr_FromString(result->refs[i]));
461 ret->referals = referals;
462 return (PyObject *)ret;
466 * Create a LDB Result from a Python object.
467 * If conversion fails, NULL will be returned and a Python exception set.
469 * Note: the result object only includes the messages at the moment; extended
470 * result, controls and referrals are ignored.
472 * @param mem_ctx Memory context in which to allocate the LDB Result
473 * @param obj Python object to convert
474 * @return a ldb_result, or NULL if the conversion failed
476 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
479 struct ldb_result *res;
485 res = talloc_zero(mem_ctx, struct ldb_result);
486 res->count = PyList_Size(obj);
487 res->msgs = talloc_array(res, struct ldb_message *, res->count);
488 for (i = 0; i < res->count; i++) {
489 PyObject *item = PyList_GetItem(obj, i);
490 res->msgs[i] = pyldb_Message_AsMessage(item);
495 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self,
496 PyObject *Py_UNUSED(ignored))
498 return PyBool_FromLong(ldb_dn_validate(self->dn));
501 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self,
502 PyObject *Py_UNUSED(ignored))
504 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
507 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self,
508 PyObject *Py_UNUSED(ignored))
510 return PyBool_FromLong(ldb_dn_is_special(self->dn));
513 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self,
514 PyObject *Py_UNUSED(ignored))
516 return PyBool_FromLong(ldb_dn_is_null(self->dn));
519 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self,
520 PyObject *Py_UNUSED(ignored))
522 return PyStr_FromString(ldb_dn_get_casefold(self->dn));
525 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
527 return PyStr_FromString(ldb_dn_get_linearized(self->dn));
530 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self,
531 PyObject *Py_UNUSED(ignored))
533 return PyStr_FromString(ldb_dn_canonical_string(self->dn, self->dn));
536 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self,
537 PyObject *Py_UNUSED(ignored))
539 return PyStr_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
542 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
544 const char * const kwnames[] = { "mode", NULL };
546 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
547 discard_const_p(char *, kwnames),
550 return PyStr_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
553 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
556 const struct ldb_val *val;
558 if (!PyArg_ParseTuple(args, "s", &name))
560 val = ldb_dn_get_extended_component(self->dn, name);
565 return PyBytes_FromStringAndSize((const char *)val->data, val->length);
568 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
572 uint8_t *value = NULL;
575 if (!PyArg_ParseTuple(args, "sz#", &name, (char **)&value, &size))
579 err = ldb_dn_set_extended_component(self->dn, name, NULL);
582 val.data = (uint8_t *)value;
584 err = ldb_dn_set_extended_component(self->dn, name, &val);
587 if (err != LDB_SUCCESS) {
588 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
595 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
597 PyObject *str = PyStr_FromString(ldb_dn_get_linearized(self->dn));
598 PyObject *repr, *result;
601 repr = PyObject_Repr(str);
606 result = PyStr_FromFormat("Dn(%s)", PyStr_AsUTF8(repr));
612 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
616 if (!PyArg_ParseTuple(args, "s", &name))
619 return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
622 static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
625 if (!pyldb_Dn_Check(dn2)) {
626 Py_INCREF(Py_NotImplemented);
627 return Py_NotImplemented;
629 ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2));
630 return richcmp(ret, op);
633 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self,
634 PyObject *Py_UNUSED(ignored))
636 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
637 struct ldb_dn *parent;
638 PyLdbDnObject *py_ret;
639 TALLOC_CTX *mem_ctx = talloc_new(NULL);
641 parent = ldb_dn_get_parent(mem_ctx, dn);
642 if (parent == NULL) {
643 talloc_free(mem_ctx);
647 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
648 if (py_ret == NULL) {
650 talloc_free(mem_ctx);
653 py_ret->mem_ctx = mem_ctx;
655 return (PyObject *)py_ret;
658 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
661 struct ldb_dn *dn, *other;
662 if (!PyArg_ParseTuple(args, "O", &py_other))
665 dn = pyldb_Dn_AsDn((PyObject *)self);
667 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
670 return PyBool_FromLong(ldb_dn_add_child(dn, other));
673 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
676 struct ldb_dn *other, *dn;
677 if (!PyArg_ParseTuple(args, "O", &py_other))
680 dn = pyldb_Dn_AsDn((PyObject *)self);
682 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
685 return PyBool_FromLong(ldb_dn_add_base(dn, other));
688 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
692 if (!PyArg_ParseTuple(args, "i", &i))
695 dn = pyldb_Dn_AsDn((PyObject *)self);
697 return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
700 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
703 struct ldb_dn *dn, *base;
704 if (!PyArg_ParseTuple(args, "O", &py_base))
707 dn = pyldb_Dn_AsDn((PyObject *)self);
709 if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
712 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
715 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
719 unsigned int num = 0;
721 if (!PyArg_ParseTuple(args, "I", &num))
724 dn = pyldb_Dn_AsDn((PyObject *)self);
726 name = ldb_dn_get_component_name(dn, num);
731 return PyStr_FromString(name);
734 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
737 const struct ldb_val *val;
738 unsigned int num = 0;
740 if (!PyArg_ParseTuple(args, "I", &num))
743 dn = pyldb_Dn_AsDn((PyObject *)self);
745 val = ldb_dn_get_component_val(dn, num);
750 return PyStr_FromLdbValue(val);
753 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
755 unsigned int num = 0;
756 char *name = NULL, *value = NULL;
757 struct ldb_val val = { NULL, };
761 if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size))
764 val.data = (unsigned char*) value;
767 err = ldb_dn_set_component(self->dn, num, name, val);
768 if (err != LDB_SUCCESS) {
769 PyErr_SetString(PyExc_TypeError, "Failed to set component");
776 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self,
777 PyObject *Py_UNUSED(ignored))
782 dn = pyldb_Dn_AsDn((PyObject *)self);
784 name = ldb_dn_get_rdn_name(dn);
789 return PyStr_FromString(name);
792 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self,
793 PyObject *Py_UNUSED(ignored))
796 const struct ldb_val *val;
798 dn = pyldb_Dn_AsDn((PyObject *)self);
800 val = ldb_dn_get_rdn_val(dn);
805 return PyStr_FromLdbValue(val);
808 static PyMethodDef py_ldb_dn_methods[] = {
809 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
810 "S.validate() -> bool\n"
811 "Validate DN is correct." },
812 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
813 "S.is_valid() -> bool\n" },
814 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
815 "S.is_special() -> bool\n"
816 "Check whether this is a special LDB DN." },
817 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
818 "Check whether this is a null DN." },
819 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
821 { "get_linearized", PY_DISCARD_FUNC_SIG(PyCFunction,
822 py_ldb_dn_get_linearized),
825 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
826 "S.canonical_str() -> string\n"
827 "Canonical version of this DN (like a posix path)." },
828 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
829 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
830 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
831 "S.canonical_ex_str() -> string\n"
832 "Canonical version of this DN (like a posix path, with terminating newline)." },
833 { "extended_str", PY_DISCARD_FUNC_SIG(PyCFunction,
834 py_ldb_dn_extended_str),
835 METH_VARARGS | METH_KEYWORDS,
836 "S.extended_str(mode=1) -> string\n"
837 "Extended version of this DN" },
838 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
840 "Get the parent for this DN." },
841 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
842 "S.add_child(dn) -> None\n"
843 "Add a child DN to this DN." },
844 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
845 "S.add_base(dn) -> None\n"
846 "Add a base DN to this DN." },
847 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
848 "S.remove_base_components(int) -> bool\n"
849 "Remove a number of DN components from the base of this DN." },
850 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
851 "S.check_special(name) -> bool\n\n"
852 "Check if name is a special DN name"},
853 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
854 "S.get_extended_component(name) -> string\n\n"
855 "returns a DN extended component as a binary string"},
856 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
857 "S.set_extended_component(name, value) -> None\n\n"
858 "set a DN extended component as a binary string"},
859 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
860 "S.get_component_name(num) -> string\n"
861 "get the attribute name of the specified component" },
862 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
863 "S.get_component_value(num) -> string\n"
864 "get the attribute value of the specified component as a binary string" },
865 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
866 "S.get_component_value(num, name, value) -> None\n"
867 "set the attribute name and value of the specified component" },
868 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
869 "S.get_rdn_name() -> string\n"
870 "get the RDN attribute name" },
871 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
872 "S.get_rdn_value() -> string\n"
873 "get the RDN attribute value as a binary string" },
877 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
879 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
883 copy a DN as a python object
885 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
887 PyLdbDnObject *py_ret;
889 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
890 if (py_ret == NULL) {
894 py_ret->mem_ctx = talloc_new(NULL);
895 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
896 return (PyObject *)py_ret;
899 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
901 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
903 PyLdbDnObject *py_ret;
905 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
908 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
909 if (py_ret == NULL) {
913 py_ret->mem_ctx = talloc_new(NULL);
914 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
915 ldb_dn_add_base(py_ret->dn, other);
916 return (PyObject *)py_ret;
919 static PySequenceMethods py_ldb_dn_seq = {
920 .sq_length = (lenfunc)py_ldb_dn_len,
921 .sq_concat = (binaryfunc)py_ldb_dn_concat,
924 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
926 struct ldb_dn *ret = NULL;
928 PyObject *py_ldb = NULL;
929 struct ldb_context *ldb_ctx = NULL;
930 TALLOC_CTX *mem_ctx = NULL;
931 PyLdbDnObject *py_ret = NULL;
932 const char * const kwnames[] = { "ldb", "dn", NULL };
934 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O"PYARG_STR_UNI,
935 discard_const_p(char *, kwnames),
936 &py_ldb, "utf8", &str))
939 if (!PyLdb_Check(py_ldb)) {
940 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
944 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
946 mem_ctx = talloc_new(NULL);
947 if (mem_ctx == NULL) {
952 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
953 if (!ldb_dn_validate(ret)) {
954 talloc_free(mem_ctx);
955 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
959 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
960 if (py_ret == NULL) {
961 talloc_free(mem_ctx);
965 py_ret->mem_ctx = mem_ctx;
969 PyMem_Free(discard_const_p(char, str));
971 return (PyObject *)py_ret;
974 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
976 talloc_free(self->mem_ctx);
980 static PyTypeObject PyLdbDn = {
982 .tp_methods = py_ldb_dn_methods,
983 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
984 .tp_repr = (reprfunc)py_ldb_dn_repr,
985 .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp,
986 .tp_as_sequence = &py_ldb_dn_seq,
987 .tp_doc = "A LDB distinguished name.",
988 .tp_new = py_ldb_dn_new,
989 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
990 .tp_basicsize = sizeof(PyLdbDnObject),
991 .tp_flags = Py_TPFLAGS_DEFAULT,
995 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
996 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
998 PyObject *fn = (PyObject *)context;
999 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyStr_FromFormatV(fmt, ap));
1002 static PyObject *py_ldb_debug_func;
1004 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
1007 struct ldb_context *ldb_ctx;
1009 if (!PyArg_ParseTuple(args, "O", &cb))
1012 if (py_ldb_debug_func != NULL) {
1013 Py_DECREF(py_ldb_debug_func);
1017 /* FIXME: DECREF cb when exiting program */
1018 py_ldb_debug_func = cb;
1019 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1020 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
1021 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
1027 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
1030 if (!PyArg_ParseTuple(args, "I", &perms))
1033 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
1038 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
1041 if (!PyArg_ParseTuple(args, "s", &modules_dir))
1044 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
1049 static PyObject *py_ldb_transaction_start(PyLdbObject *self,
1050 PyObject *Py_UNUSED(ignored))
1052 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1054 ldb_err = ldb_transaction_start(ldb_ctx);
1055 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1059 static PyObject *py_ldb_transaction_commit(PyLdbObject *self,
1060 PyObject *Py_UNUSED(ignored))
1062 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1064 ldb_err = ldb_transaction_commit(ldb_ctx);
1065 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1069 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self,
1070 PyObject *Py_UNUSED(ignored))
1072 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1074 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
1075 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1079 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self,
1080 PyObject *Py_UNUSED(ignored))
1082 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1084 ldb_err = ldb_transaction_cancel(ldb_ctx);
1085 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1089 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self,
1090 PyObject *Py_UNUSED(ignored))
1092 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1094 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
1095 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1099 static PyObject *py_ldb_repr(PyLdbObject *self)
1101 return PyStr_FromString("<ldb connection>");
1104 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self,
1105 PyObject *Py_UNUSED(ignored))
1107 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
1110 return py_ldb_dn_copy(dn);
1114 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self,
1115 PyObject *Py_UNUSED(ignored))
1117 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
1120 return py_ldb_dn_copy(dn);
1123 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self,
1124 PyObject *Py_UNUSED(ignored))
1126 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
1129 return py_ldb_dn_copy(dn);
1132 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self,
1133 PyObject *Py_UNUSED(ignored))
1135 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
1138 return py_ldb_dn_copy(dn);
1141 static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
1142 const char *paramname)
1146 if (!PyList_Check(list)) {
1147 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
1150 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1156 for (i = 0; i < PyList_Size(list); i++) {
1157 const char *str = NULL;
1159 PyObject *item = PyList_GetItem(list, i);
1160 if (!(PyStr_Check(item) || PyUnicode_Check(item))) {
1161 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
1165 str = PyStr_AsUTF8AndSize(item, &size);
1170 ret[i] = talloc_strndup(ret, str, size);
1176 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1178 const char * const kwnames[] = { "url", "flags", "options", NULL };
1180 PyObject *py_options = Py_None;
1181 const char **options;
1182 unsigned int flags = 0;
1184 struct ldb_context *ldb;
1186 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1187 discard_const_p(char *, kwnames),
1188 &url, &flags, &py_options))
1191 ldb = pyldb_Ldb_AsLdbContext(self);
1193 if (py_options == Py_None) {
1196 options = PyList_AsStrList(ldb, py_options, "options");
1197 if (options == NULL)
1202 ret = ldb_connect(ldb, url, flags, options);
1203 if (ret != LDB_SUCCESS) {
1204 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1209 talloc_free(options);
1213 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1216 struct ldb_context *ldb;
1217 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1222 ret->mem_ctx = talloc_new(NULL);
1223 ldb = ldb_init(ret->mem_ctx, NULL);
1231 return (PyObject *)ret;
1234 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1237 unsigned int flags = 0;
1238 PyObject *py_options = Py_None;
1240 const char **options;
1241 const char * const kwnames[] = { "url", "flags", "options", NULL };
1242 struct ldb_context *ldb_ctx;
1244 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|IO",
1245 discard_const_p(char *, kwnames),
1246 &url, &flags, &py_options))
1249 if (py_options == Py_None) {
1252 options = PyList_AsStrList(NULL, py_options, "options");
1253 if (options == NULL)
1257 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1258 ret = ldb_connect(ldb_ctx, url, flags, options);
1259 talloc_free(options);
1261 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1266 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1269 PyObject *py_controls = Py_None;
1270 struct ldb_context *ldb_ctx;
1271 struct ldb_request *req;
1272 struct ldb_control **parsed_controls;
1273 struct ldb_message *msg;
1275 TALLOC_CTX *mem_ctx;
1277 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1279 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1280 discard_const_p(char *, kwnames),
1281 &py_msg, &py_controls, &validate))
1284 mem_ctx = talloc_new(NULL);
1285 if (mem_ctx == NULL) {
1289 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1291 if (py_controls == Py_None) {
1292 parsed_controls = NULL;
1294 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1295 if (controls == NULL) {
1296 talloc_free(mem_ctx);
1299 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1300 talloc_free(controls);
1303 if (!PyLdbMessage_Check(py_msg)) {
1304 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1305 talloc_free(mem_ctx);
1308 msg = pyldb_Message_AsMessage(py_msg);
1311 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1312 if (ret != LDB_SUCCESS) {
1313 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1314 talloc_free(mem_ctx);
1319 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1320 NULL, ldb_op_default_callback, NULL);
1321 if (ret != LDB_SUCCESS) {
1322 PyErr_SetString(PyExc_TypeError, "failed to build request");
1323 talloc_free(mem_ctx);
1327 /* do request and autostart a transaction */
1328 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1330 ret = ldb_transaction_start(ldb_ctx);
1331 if (ret != LDB_SUCCESS) {
1332 talloc_free(mem_ctx);
1333 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1337 ret = ldb_request(ldb_ctx, req);
1338 if (ret == LDB_SUCCESS) {
1339 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1342 if (ret == LDB_SUCCESS) {
1343 ret = ldb_transaction_commit(ldb_ctx);
1345 ldb_transaction_cancel(ldb_ctx);
1348 talloc_free(mem_ctx);
1349 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1356 * Obtain a ldb message from a Python Dictionary object.
1358 * @param mem_ctx Memory context
1359 * @param py_obj Python Dictionary object
1360 * @param ldb_ctx LDB context
1361 * @param mod_flags Flags to be set on every message element
1362 * @return ldb_message on success or NULL on failure
1364 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1366 struct ldb_context *ldb_ctx,
1367 unsigned int mod_flags)
1369 struct ldb_message *msg;
1370 unsigned int msg_pos = 0;
1371 Py_ssize_t dict_pos = 0;
1372 PyObject *key, *value;
1373 struct ldb_message_element *msg_el;
1374 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1376 msg = ldb_msg_new(mem_ctx);
1381 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1384 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1385 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1388 if (msg->dn == NULL) {
1389 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1393 PyErr_SetString(PyExc_TypeError, "no dn set");
1397 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1398 const char *key_str = PyStr_AsUTF8(key);
1399 if (ldb_attr_cmp(key_str, "dn") != 0) {
1400 msg_el = PyObject_AsMessageElement(msg->elements, value,
1401 mod_flags, key_str);
1402 if (msg_el == NULL) {
1403 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1406 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1411 msg->num_elements = msg_pos;
1416 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1420 struct ldb_context *ldb_ctx;
1421 struct ldb_request *req;
1422 struct ldb_message *msg = NULL;
1423 PyObject *py_controls = Py_None;
1424 TALLOC_CTX *mem_ctx;
1425 struct ldb_control **parsed_controls;
1426 const char * const kwnames[] = { "message", "controls", NULL };
1428 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1429 discard_const_p(char *, kwnames),
1430 &py_obj, &py_controls))
1433 mem_ctx = talloc_new(NULL);
1434 if (mem_ctx == NULL) {
1438 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1440 if (py_controls == Py_None) {
1441 parsed_controls = NULL;
1443 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1444 if (controls == NULL) {
1445 talloc_free(mem_ctx);
1448 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1449 talloc_free(controls);
1452 if (PyLdbMessage_Check(py_obj)) {
1453 msg = pyldb_Message_AsMessage(py_obj);
1454 } else if (PyDict_Check(py_obj)) {
1455 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1457 PyErr_SetString(PyExc_TypeError,
1458 "Dictionary or LdbMessage object expected!");
1462 /* we should have a PyErr already set */
1463 talloc_free(mem_ctx);
1467 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1468 if (ret != LDB_SUCCESS) {
1469 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1470 talloc_free(mem_ctx);
1474 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1475 NULL, ldb_op_default_callback, NULL);
1476 if (ret != LDB_SUCCESS) {
1477 PyErr_SetString(PyExc_TypeError, "failed to build request");
1478 talloc_free(mem_ctx);
1482 /* do request and autostart a transaction */
1483 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1485 ret = ldb_transaction_start(ldb_ctx);
1486 if (ret != LDB_SUCCESS) {
1487 talloc_free(mem_ctx);
1488 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1492 ret = ldb_request(ldb_ctx, req);
1493 if (ret == LDB_SUCCESS) {
1494 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1497 if (ret == LDB_SUCCESS) {
1498 ret = ldb_transaction_commit(ldb_ctx);
1500 ldb_transaction_cancel(ldb_ctx);
1503 talloc_free(mem_ctx);
1504 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1509 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1514 struct ldb_context *ldb_ctx;
1515 struct ldb_request *req;
1516 PyObject *py_controls = Py_None;
1517 TALLOC_CTX *mem_ctx;
1518 struct ldb_control **parsed_controls;
1519 const char * const kwnames[] = { "dn", "controls", NULL };
1521 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1522 discard_const_p(char *, kwnames),
1523 &py_dn, &py_controls))
1526 mem_ctx = talloc_new(NULL);
1527 if (mem_ctx == NULL) {
1531 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1533 if (py_controls == Py_None) {
1534 parsed_controls = NULL;
1536 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1537 if (controls == NULL) {
1538 talloc_free(mem_ctx);
1541 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1542 talloc_free(controls);
1545 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1546 talloc_free(mem_ctx);
1550 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1551 NULL, ldb_op_default_callback, NULL);
1552 if (ret != LDB_SUCCESS) {
1553 PyErr_SetString(PyExc_TypeError, "failed to build request");
1554 talloc_free(mem_ctx);
1558 /* do request and autostart a transaction */
1559 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1561 ret = ldb_transaction_start(ldb_ctx);
1562 if (ret != LDB_SUCCESS) {
1563 talloc_free(mem_ctx);
1564 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1568 ret = ldb_request(ldb_ctx, req);
1569 if (ret == LDB_SUCCESS) {
1570 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1573 if (ret == LDB_SUCCESS) {
1574 ret = ldb_transaction_commit(ldb_ctx);
1576 ldb_transaction_cancel(ldb_ctx);
1579 talloc_free(mem_ctx);
1580 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1585 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1587 PyObject *py_dn1, *py_dn2;
1588 struct ldb_dn *dn1, *dn2;
1590 TALLOC_CTX *mem_ctx;
1591 PyObject *py_controls = Py_None;
1592 struct ldb_control **parsed_controls;
1593 struct ldb_context *ldb_ctx;
1594 struct ldb_request *req;
1595 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1597 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1599 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1600 discard_const_p(char *, kwnames),
1601 &py_dn1, &py_dn2, &py_controls))
1605 mem_ctx = talloc_new(NULL);
1606 if (mem_ctx == NULL) {
1611 if (py_controls == Py_None) {
1612 parsed_controls = NULL;
1614 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1615 if (controls == NULL) {
1616 talloc_free(mem_ctx);
1619 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1620 talloc_free(controls);
1624 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1625 talloc_free(mem_ctx);
1629 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1630 talloc_free(mem_ctx);
1634 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1635 NULL, ldb_op_default_callback, NULL);
1636 if (ret != LDB_SUCCESS) {
1637 PyErr_SetString(PyExc_TypeError, "failed to build request");
1638 talloc_free(mem_ctx);
1642 /* do request and autostart a transaction */
1643 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1645 ret = ldb_transaction_start(ldb_ctx);
1646 if (ret != LDB_SUCCESS) {
1647 talloc_free(mem_ctx);
1648 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1652 ret = ldb_request(ldb_ctx, req);
1653 if (ret == LDB_SUCCESS) {
1654 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1657 if (ret == LDB_SUCCESS) {
1658 ret = ldb_transaction_commit(ldb_ctx);
1660 ldb_transaction_cancel(ldb_ctx);
1663 talloc_free(mem_ctx);
1664 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1669 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1672 if (!PyArg_ParseTuple(args, "s", &name))
1675 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1680 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1682 char *attribute, *syntax;
1685 struct ldb_context *ldb_ctx;
1687 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1690 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1691 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1693 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1698 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1703 /* We don't want this attached to the 'ldb' any more */
1704 PyObject *obj = PyLdbMessage_FromMessage(ldif->msg);
1706 Py_BuildValue(discard_const_p(char, "(iO)"),
1715 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1719 struct ldb_ldif ldif;
1722 TALLOC_CTX *mem_ctx;
1724 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1727 if (!PyLdbMessage_Check(py_msg)) {
1728 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1732 ldif.msg = pyldb_Message_AsMessage(py_msg);
1733 ldif.changetype = changetype;
1735 mem_ctx = talloc_new(NULL);
1737 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1739 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1743 ret = PyStr_FromString(string);
1745 talloc_free(mem_ctx);
1750 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1752 PyObject *list, *ret;
1753 struct ldb_ldif *ldif;
1755 struct ldb_dn *last_dn = NULL;
1757 TALLOC_CTX *mem_ctx;
1759 if (!PyArg_ParseTuple(args, "s", &s))
1762 mem_ctx = talloc_new(NULL);
1767 list = PyList_New(0);
1768 while (s && *s != '\0') {
1769 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1770 talloc_steal(mem_ctx, ldif);
1773 PyObject *py_ldif = ldb_ldif_to_pyobject(ldif);
1774 if (py_ldif == NULL) {
1776 PyErr_BadArgument();
1777 talloc_free(mem_ctx);
1780 res = PyList_Append(list, py_ldif);
1784 talloc_free(mem_ctx);
1787 last_dn = ldif->msg->dn;
1789 const char *last_dn_str = NULL;
1790 const char *err_string = NULL;
1791 if (last_dn == NULL) {
1792 PyErr_SetString(PyExc_ValueError,
1793 "unable to parse LDIF "
1794 "string at first chunk");
1796 talloc_free(mem_ctx);
1801 = ldb_dn_get_linearized(last_dn);
1804 = talloc_asprintf(mem_ctx,
1805 "unable to parse ldif "
1809 PyErr_SetString(PyExc_ValueError,
1811 talloc_free(mem_ctx);
1816 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1817 ret = PyObject_GetIter(list);
1822 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1825 PyObject *py_msg_old;
1826 PyObject *py_msg_new;
1827 struct ldb_message *diff;
1828 struct ldb_context *ldb;
1831 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1834 if (!PyLdbMessage_Check(py_msg_old)) {
1835 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1839 if (!PyLdbMessage_Check(py_msg_new)) {
1840 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1844 ldb = pyldb_Ldb_AsLdbContext(self);
1845 ldb_ret = ldb_msg_difference(ldb, ldb,
1846 pyldb_Message_AsMessage(py_msg_old),
1847 pyldb_Message_AsMessage(py_msg_new),
1849 if (ldb_ret != LDB_SUCCESS) {
1850 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1854 py_ret = PyLdbMessage_FromMessage(diff);
1856 talloc_unlink(ldb, diff);
1861 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1863 const struct ldb_schema_attribute *a;
1864 struct ldb_val old_val;
1865 struct ldb_val new_val;
1866 TALLOC_CTX *mem_ctx;
1873 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1876 result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1877 old_val.length = size;
1880 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1884 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1890 mem_ctx = talloc_new(NULL);
1891 if (mem_ctx == NULL) {
1896 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1897 talloc_free(mem_ctx);
1901 ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1903 talloc_free(mem_ctx);
1908 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1910 PyObject *py_base = Py_None;
1911 int scope = LDB_SCOPE_DEFAULT;
1913 PyObject *py_attrs = Py_None;
1914 PyObject *py_controls = Py_None;
1915 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1917 struct ldb_result *res;
1918 struct ldb_request *req;
1920 struct ldb_context *ldb_ctx;
1921 struct ldb_control **parsed_controls;
1922 struct ldb_dn *base;
1924 TALLOC_CTX *mem_ctx;
1926 /* type "int" rather than "enum" for "scope" is intentional */
1927 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1928 discard_const_p(char *, kwnames),
1929 &py_base, &scope, &expr, &py_attrs, &py_controls))
1933 mem_ctx = talloc_new(NULL);
1934 if (mem_ctx == NULL) {
1938 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1940 if (py_attrs == Py_None) {
1943 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1944 if (attrs == NULL) {
1945 talloc_free(mem_ctx);
1950 if (py_base == Py_None) {
1951 base = ldb_get_default_basedn(ldb_ctx);
1953 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1954 talloc_free(mem_ctx);
1959 if (py_controls == Py_None) {
1960 parsed_controls = NULL;
1962 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1963 if (controls == NULL) {
1964 talloc_free(mem_ctx);
1967 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1968 talloc_free(controls);
1971 res = talloc_zero(mem_ctx, struct ldb_result);
1974 talloc_free(mem_ctx);
1978 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1985 ldb_search_default_callback,
1988 if (ret != LDB_SUCCESS) {
1989 talloc_free(mem_ctx);
1990 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1994 talloc_steal(req, attrs);
1996 ret = ldb_request(ldb_ctx, req);
1998 if (ret == LDB_SUCCESS) {
1999 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
2002 if (ret != LDB_SUCCESS) {
2003 talloc_free(mem_ctx);
2004 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2008 py_ret = PyLdbResult_FromResult(res);
2010 talloc_free(mem_ctx);
2015 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
2017 if (reply->py_iter != NULL) {
2018 DLIST_REMOVE(reply->py_iter->state.next, reply);
2019 if (reply->py_iter->state.result == reply) {
2020 reply->py_iter->state.result = NULL;
2022 reply->py_iter = NULL;
2025 if (reply->obj != NULL) {
2026 Py_DECREF(reply->obj);
2033 static int py_ldb_search_iterator_callback(struct ldb_request *req,
2034 struct ldb_reply *ares)
2036 PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
2037 struct ldb_result result = { .msgs = NULL };
2038 struct py_ldb_search_iterator_reply *reply = NULL;
2041 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2044 if (ares->error != LDB_SUCCESS) {
2045 int ret = ares->error;
2047 return ldb_request_done(req, ret);
2050 reply = talloc_zero(py_iter->mem_ctx,
2051 struct py_ldb_search_iterator_reply);
2052 if (reply == NULL) {
2054 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2056 reply->py_iter = py_iter;
2057 talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
2059 switch (ares->type) {
2060 case LDB_REPLY_ENTRY:
2061 reply->obj = PyLdbMessage_FromMessage(ares->message);
2062 if (reply->obj == NULL) {
2064 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2066 DLIST_ADD_END(py_iter->state.next, reply);
2070 case LDB_REPLY_REFERRAL:
2071 reply->obj = PyStr_FromString(ares->referral);
2072 if (reply->obj == NULL) {
2074 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2076 DLIST_ADD_END(py_iter->state.next, reply);
2080 case LDB_REPLY_DONE:
2081 result = (struct ldb_result) { .controls = ares->controls };
2082 reply->obj = PyLdbResult_FromResult(&result);
2083 if (reply->obj == NULL) {
2085 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2087 py_iter->state.result = reply;
2089 return ldb_request_done(req, LDB_SUCCESS);
2093 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2096 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2098 PyObject *py_base = Py_None;
2099 int scope = LDB_SCOPE_DEFAULT;
2102 PyObject *py_attrs = Py_None;
2103 PyObject *py_controls = Py_None;
2104 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
2107 struct ldb_context *ldb_ctx;
2108 struct ldb_control **parsed_controls;
2109 struct ldb_dn *base;
2110 PyLdbSearchIteratorObject *py_iter;
2112 /* type "int" rather than "enum" for "scope" is intentional */
2113 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
2114 discard_const_p(char *, kwnames),
2115 &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
2118 py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
2119 if (py_iter == NULL) {
2123 py_iter->ldb = self;
2125 ZERO_STRUCT(py_iter->state);
2126 py_iter->mem_ctx = talloc_new(NULL);
2127 if (py_iter->mem_ctx == NULL) {
2133 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2135 if (py_attrs == Py_None) {
2138 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2139 if (attrs == NULL) {
2146 if (py_base == Py_None) {
2147 base = ldb_get_default_basedn(ldb_ctx);
2149 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2156 if (py_controls == Py_None) {
2157 parsed_controls = NULL;
2159 const char **controls = NULL;
2161 controls = PyList_AsStrList(py_iter->mem_ctx,
2162 py_controls, "controls");
2163 if (controls == NULL) {
2169 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2172 if (controls[0] != NULL && parsed_controls == NULL) {
2177 talloc_free(controls);
2180 ret = ldb_build_search_req(&py_iter->state.req,
2189 py_ldb_search_iterator_callback,
2191 if (ret != LDB_SUCCESS) {
2193 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2197 ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2199 ret = ldb_request(ldb_ctx, py_iter->state.req);
2200 if (ret != LDB_SUCCESS) {
2202 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2206 return (PyObject *)py_iter;
2209 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2214 if (!PyArg_ParseTuple(args, "s", &name))
2217 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
2222 /* FIXME: More interpretation */
2227 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2232 if (!PyArg_ParseTuple(args, "sO", &name, &data))
2235 /* FIXME: More interpretation */
2237 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
2242 static PyObject *py_ldb_modules(PyLdbObject *self,
2243 PyObject *Py_UNUSED(ignored))
2245 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2246 PyObject *ret = PyList_New(0);
2247 struct ldb_module *mod;
2250 return PyErr_NoMemory();
2252 for (mod = ldb->modules; mod; mod = mod->next) {
2253 PyObject *item = PyLdbModule_FromModule(mod);
2256 PyErr_SetString(PyExc_RuntimeError,
2257 "Failed to load LdbModule");
2261 res = PyList_Append(ret, item);
2272 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2274 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2278 if (!PyArg_ParseTuple(args, "i", &type))
2281 /* FIXME: More interpretation */
2283 ret = ldb_sequence_number(ldb, type, &value);
2285 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2287 return PyLong_FromLongLong(value);
2291 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2293 .read_fn = ldb_handler_copy,
2294 .write_clear_fn = ldb_handler_copy,
2295 .write_hex_fn = ldb_handler_copy,
2298 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self,
2299 PyObject *Py_UNUSED(ignored))
2301 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2304 ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2306 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2312 static PyMethodDef py_ldb_methods[] = {
2313 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
2314 "S.set_debug(callback) -> None\n"
2315 "Set callback for LDB debug messages.\n"
2316 "The callback should accept a debug level and debug text." },
2317 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
2318 "S.set_create_perms(mode) -> None\n"
2319 "Set mode to use when creating new LDB files." },
2320 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2321 "S.set_modules_dir(path) -> None\n"
2322 "Set path LDB should search for modules" },
2323 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
2324 "S.transaction_start() -> None\n"
2325 "Start a new transaction." },
2326 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2327 "S.transaction_prepare_commit() -> None\n"
2328 "prepare to commit a new transaction (2-stage commit)." },
2329 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
2330 "S.transaction_commit() -> None\n"
2331 "commit a new transaction." },
2332 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
2333 "S.transaction_cancel() -> None\n"
2334 "cancel a new transaction." },
2335 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
2337 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2339 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2341 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2343 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2345 { "connect", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_connect),
2346 METH_VARARGS|METH_KEYWORDS,
2347 "S.connect(url, flags=0, options=None) -> None\n"
2348 "Connect to a LDB URL." },
2349 { "modify", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_modify),
2350 METH_VARARGS|METH_KEYWORDS,
2351 "S.modify(message, controls=None, validate=False) -> None\n"
2352 "Modify an entry." },
2353 { "add", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_add),
2354 METH_VARARGS|METH_KEYWORDS,
2355 "S.add(message, controls=None) -> None\n"
2357 { "delete", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_delete),
2358 METH_VARARGS|METH_KEYWORDS,
2359 "S.delete(dn, controls=None) -> None\n"
2360 "Remove an entry." },
2361 { "rename", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_rename),
2362 METH_VARARGS|METH_KEYWORDS,
2363 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2364 "Rename an entry." },
2365 { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_search),
2366 METH_VARARGS|METH_KEYWORDS,
2367 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2368 "Search in a database.\n"
2370 ":param base: Optional base DN to search\n"
2371 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2372 ":param expression: Optional search expression\n"
2373 ":param attrs: Attributes to return (defaults to all)\n"
2374 ":param controls: Optional list of controls\n"
2375 ":return: ldb.Result object\n"
2377 { "search_iterator", PY_DISCARD_FUNC_SIG(PyCFunction,
2378 py_ldb_search_iterator),
2379 METH_VARARGS|METH_KEYWORDS,
2380 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2381 "Search in a database.\n"
2383 ":param base: Optional base DN to search\n"
2384 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2385 ":param expression: Optional search expression\n"
2386 ":param attrs: Attributes to return (defaults to all)\n"
2387 ":param controls: Optional list of controls\n"
2388 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2389 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2391 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2393 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2395 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2397 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2398 "S.parse_ldif(ldif) -> iter(messages)\n"
2399 "Parse a string formatted using LDIF." },
2400 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2401 "S.write_ldif(message, changetype) -> ldif\n"
2402 "Print the message as a string formatted using LDIF." },
2403 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2404 "S.msg_diff(Message) -> Message\n"
2405 "Return an LDB Message of the difference between two Message objects." },
2406 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2407 "S.get_opaque(name) -> value\n"
2408 "Get an opaque value set on this LDB connection. \n"
2409 ":note: The returned value may not be useful in Python."
2411 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2412 "S.set_opaque(name, value) -> None\n"
2413 "Set an opaque value on this LDB connection. \n"
2414 ":note: Passing incorrect values may cause crashes." },
2415 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2416 "S.modules() -> list\n"
2417 "Return the list of modules on this LDB connection " },
2418 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2419 "S.sequence_number(type) -> value\n"
2420 "Return the value of the sequence according to the requested type" },
2421 { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2422 "S._register_test_extensions() -> None\n"
2423 "Register internal extensions used in testing" },
2427 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2429 PyLdbModuleObject *ret;
2431 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2436 ret->mem_ctx = talloc_new(NULL);
2437 ret->mod = talloc_reference(ret->mem_ctx, mod);
2438 return (PyObject *)ret;
2441 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2443 struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2447 return PyLdbModule_FromModule(mod);
2450 static PyGetSetDef py_ldb_getset[] = {
2452 .name = discard_const_p(char, "firstmodule"),
2453 .get = (getter)py_ldb_get_firstmodule,
2458 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2460 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2462 struct ldb_result *result;
2466 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2470 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2472 if (ret != LDB_SUCCESS) {
2473 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2477 count = result->count;
2479 talloc_free(result);
2482 PyErr_Format(PyExc_RuntimeError,
2483 "Searching for [%s] dn gave %u results!",
2484 ldb_dn_get_linearized(dn),
2492 static PySequenceMethods py_ldb_seq = {
2493 .sq_contains = (objobjproc)py_ldb_contains,
2496 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2500 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2505 ret->mem_ctx = talloc_new(NULL);
2506 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2507 return (PyObject *)ret;
2510 static void py_ldb_dealloc(PyLdbObject *self)
2512 talloc_free(self->mem_ctx);
2513 Py_TYPE(self)->tp_free(self);
2516 static PyTypeObject PyLdb = {
2517 .tp_name = "ldb.Ldb",
2518 .tp_methods = py_ldb_methods,
2519 .tp_repr = (reprfunc)py_ldb_repr,
2520 .tp_new = py_ldb_new,
2521 .tp_init = (initproc)py_ldb_init,
2522 .tp_dealloc = (destructor)py_ldb_dealloc,
2523 .tp_getset = py_ldb_getset,
2524 .tp_getattro = PyObject_GenericGetAttr,
2525 .tp_basicsize = sizeof(PyLdbObject),
2526 .tp_doc = "Connection to a LDB database.",
2527 .tp_as_sequence = &py_ldb_seq,
2528 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2531 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2533 talloc_free(self->mem_ctx);
2534 Py_DECREF(self->msgs);
2535 Py_DECREF(self->referals);
2536 Py_DECREF(self->controls);
2537 Py_TYPE(self)->tp_free(self);
2540 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2542 Py_INCREF(self->msgs);
2546 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2548 Py_INCREF(self->controls);
2549 return self->controls;
2552 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2554 Py_INCREF(self->referals);
2555 return self->referals;
2558 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2561 if (self->msgs == NULL) {
2562 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2565 size = PyList_Size(self->msgs);
2566 return PyInt_FromLong(size);
2569 static PyGetSetDef py_ldb_result_getset[] = {
2571 .name = discard_const_p(char, "controls"),
2572 .get = (getter)py_ldb_result_get_controls,
2575 .name = discard_const_p(char, "msgs"),
2576 .get = (getter)py_ldb_result_get_msgs,
2579 .name = discard_const_p(char, "referals"),
2580 .get = (getter)py_ldb_result_get_referals,
2583 .name = discard_const_p(char, "count"),
2584 .get = (getter)py_ldb_result_get_count,
2589 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2591 return PyObject_GetIter(self->msgs);
2594 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2596 return PySequence_Size(self->msgs);
2599 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2601 return PySequence_GetItem(self->msgs, idx);
2604 static PySequenceMethods py_ldb_result_seq = {
2605 .sq_length = (lenfunc)py_ldb_result_len,
2606 .sq_item = (ssizeargfunc)py_ldb_result_find,
2609 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2611 return PyStr_FromString("<ldb result>");
2615 static PyTypeObject PyLdbResult = {
2616 .tp_name = "ldb.Result",
2617 .tp_repr = (reprfunc)py_ldb_result_repr,
2618 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2619 .tp_iter = (getiterfunc)py_ldb_result_iter,
2620 .tp_getset = py_ldb_result_getset,
2621 .tp_getattro = PyObject_GenericGetAttr,
2622 .tp_basicsize = sizeof(PyLdbResultObject),
2623 .tp_as_sequence = &py_ldb_result_seq,
2624 .tp_doc = "LDB result.",
2625 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2628 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2630 Py_XDECREF(self->state.exception);
2631 TALLOC_FREE(self->mem_ctx);
2632 ZERO_STRUCT(self->state);
2633 Py_DECREF(self->ldb);
2634 Py_TYPE(self)->tp_free(self);
2637 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2639 PyObject *py_ret = NULL;
2641 if (self->state.req == NULL) {
2642 PyErr_SetString(PyExc_RuntimeError,
2643 "ldb.SearchIterator request already finished");
2648 * TODO: do we want a non-blocking mode?
2649 * In future we may add an optional 'nonblocking'
2650 * argument to search_iterator().
2652 * For now we keep it simple and wait for at
2656 while (self->state.next == NULL) {
2659 if (self->state.result != NULL) {
2661 * We (already) got a final result from the server.
2663 * We stop the iteration and let
2664 * py_ldb_search_iterator_result() will deliver
2665 * the result details.
2667 TALLOC_FREE(self->state.req);
2668 PyErr_SetNone(PyExc_StopIteration);
2672 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2673 if (ret != LDB_SUCCESS) {
2674 struct ldb_context *ldb_ctx;
2675 TALLOC_FREE(self->state.req);
2676 ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb);
2678 * We stop the iteration and let
2679 * py_ldb_search_iterator_result() will deliver
2682 self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2683 ret, ldb_errstring(ldb_ctx));
2684 PyErr_SetNone(PyExc_StopIteration);
2689 py_ret = self->state.next->obj;
2690 self->state.next->obj = NULL;
2691 /* no TALLOC_FREE() as self->state.next is a list */
2692 talloc_free(self->state.next);
2696 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self,
2697 PyObject *Py_UNUSED(ignored))
2699 PyObject *py_ret = NULL;
2701 if (self->state.req != NULL) {
2702 PyErr_SetString(PyExc_RuntimeError,
2703 "ldb.SearchIterator request running");
2707 if (self->state.next != NULL) {
2708 PyErr_SetString(PyExc_RuntimeError,
2709 "ldb.SearchIterator not fully consumed.");
2713 if (self->state.exception != NULL) {
2714 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2715 self->state.exception = NULL;
2719 if (self->state.result == NULL) {
2720 PyErr_SetString(PyExc_RuntimeError,
2721 "ldb.SearchIterator result already consumed");
2725 py_ret = self->state.result->obj;
2726 self->state.result->obj = NULL;
2727 TALLOC_FREE(self->state.result);
2731 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self,
2732 PyObject *Py_UNUSED(ignored))
2734 if (self->state.req == NULL) {
2735 PyErr_SetString(PyExc_RuntimeError,
2736 "ldb.SearchIterator request already finished");
2740 Py_XDECREF(self->state.exception);
2741 TALLOC_FREE(self->mem_ctx);
2742 ZERO_STRUCT(self->state);
2746 static PyMethodDef py_ldb_search_iterator_methods[] = {
2747 { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2748 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2749 { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2754 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2756 return PyStr_FromString("<ldb search iterator>");
2759 static PyTypeObject PyLdbSearchIterator = {
2760 .tp_name = "ldb.SearchIterator",
2761 .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2762 .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2763 .tp_iter = PyObject_SelfIter,
2764 .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2765 .tp_methods = py_ldb_search_iterator_methods,
2766 .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2767 .tp_doc = "LDB search_iterator.",
2768 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2771 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2773 return PyStr_FromFormat("<ldb module '%s'>",
2774 pyldb_Module_AsModule(self)->ops->name);
2777 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2779 return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
2782 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self,
2783 PyObject *Py_UNUSED(ignored))
2785 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2789 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self,
2790 PyObject *Py_UNUSED(ignored))
2792 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2796 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self,
2797 PyObject *Py_UNUSED(ignored))
2799 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2803 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2805 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2807 struct ldb_request *req;
2808 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2809 struct ldb_module *mod;
2810 const char * const*attrs;
2812 /* type "int" rather than "enum" for "scope" is intentional */
2813 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2814 discard_const_p(char *, kwnames),
2815 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2820 if (py_attrs == Py_None) {
2823 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2828 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2829 scope, NULL /* expr */, attrs,
2830 NULL /* controls */, NULL, NULL, NULL);
2832 talloc_steal(req, attrs);
2834 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2836 req->op.search.res = NULL;
2838 ret = mod->ops->search(mod, req);
2840 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2842 py_ret = PyLdbResult_FromResult(req->op.search.res);
2850 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2852 struct ldb_request *req;
2853 PyObject *py_message;
2855 struct ldb_module *mod;
2857 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2860 req = talloc_zero(NULL, struct ldb_request);
2861 req->operation = LDB_ADD;
2862 req->op.add.message = pyldb_Message_AsMessage(py_message);
2864 mod = pyldb_Module_AsModule(self);
2865 ret = mod->ops->add(mod, req);
2867 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2872 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2875 struct ldb_request *req;
2876 PyObject *py_message;
2877 struct ldb_module *mod;
2879 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2882 req = talloc_zero(NULL, struct ldb_request);
2883 req->operation = LDB_MODIFY;
2884 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2886 mod = pyldb_Module_AsModule(self);
2887 ret = mod->ops->modify(mod, req);
2889 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2894 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2897 struct ldb_request *req;
2900 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2903 req = talloc_zero(NULL, struct ldb_request);
2904 req->operation = LDB_DELETE;
2905 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2907 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2909 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2914 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2917 struct ldb_request *req;
2918 PyObject *py_dn1, *py_dn2;
2920 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2923 req = talloc_zero(NULL, struct ldb_request);
2925 req->operation = LDB_RENAME;
2926 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2927 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2929 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2931 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2936 static PyMethodDef py_ldb_module_methods[] = {
2937 { "search", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_module_search),
2938 METH_VARARGS|METH_KEYWORDS, NULL },
2939 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2940 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2941 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2942 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2943 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2944 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2945 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2949 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2951 talloc_free(self->mem_ctx);
2955 static PyTypeObject PyLdbModule = {
2956 .tp_name = "ldb.LdbModule",
2957 .tp_methods = py_ldb_module_methods,
2958 .tp_repr = (reprfunc)py_ldb_module_repr,
2959 .tp_str = (reprfunc)py_ldb_module_str,
2960 .tp_basicsize = sizeof(PyLdbModuleObject),
2961 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2962 .tp_flags = Py_TPFLAGS_DEFAULT,
2963 .tp_doc = "LDB module (extension)",
2968 * Create a ldb_message_element from a Python object.
2970 * This will accept any sequence objects that contains strings, or
2973 * A reference to set_obj will be borrowed.
2975 * @param mem_ctx Memory context
2976 * @param set_obj Python object to convert
2977 * @param flags ldb_message_element flags to set
2978 * @param attr_name Name of the attribute
2979 * @return New ldb_message_element, allocated as child of mem_ctx
2981 static struct ldb_message_element *PyObject_AsMessageElement(
2982 TALLOC_CTX *mem_ctx,
2985 const char *attr_name)
2987 struct ldb_message_element *me;
2988 const char *msg = NULL;
2992 if (pyldb_MessageElement_Check(set_obj)) {
2993 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2994 /* We have to talloc_reference() the memory context, not the pointer
2995 * which may not actually be it's own context */
2996 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2997 return pyldb_MessageElement_AsMessageElement(set_obj);
3002 me = talloc(mem_ctx, struct ldb_message_element);
3008 me->name = talloc_strdup(me, attr_name);
3010 if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) {
3012 me->values = talloc_array(me, struct ldb_val, me->num_values);
3013 if (PyBytes_Check(set_obj)) {
3015 result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
3022 msg = PyStr_AsUTF8AndSize(set_obj, &size);
3028 me->values[0].data = talloc_memdup(me,
3029 (const uint8_t *)msg,
3031 me->values[0].length = size;
3032 } else if (PySequence_Check(set_obj)) {
3034 me->num_values = PySequence_Size(set_obj);
3035 me->values = talloc_array(me, struct ldb_val, me->num_values);
3036 for (i = 0; i < me->num_values; i++) {
3037 PyObject *obj = PySequence_GetItem(set_obj, i);
3038 if (PyBytes_Check(obj)) {
3040 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
3046 } else if (PyUnicode_Check(obj)) {
3047 msg = PyStr_AsUTF8AndSize(obj, &size);
3053 PyErr_Format(PyExc_TypeError,
3054 "Expected string as element %zd in list", i);
3058 me->values[i].data = talloc_memdup(me,
3059 (const uint8_t *)msg,
3061 me->values[i].length = size;
3064 PyErr_Format(PyExc_TypeError,
3065 "String or List type expected for '%s' attribute", attr_name);
3074 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
3075 struct ldb_message_element *me)
3080 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3081 result = PyList_New(me->num_values);
3083 for (i = 0; i < me->num_values; i++) {
3084 PyList_SetItem(result, i,
3085 PyObject_FromLdbValue(&me->values[i]));
3091 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
3094 if (!PyArg_ParseTuple(args, "I", &i))
3096 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
3099 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
3102 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
3104 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3105 return PyInt_FromLong(el->flags);
3108 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
3111 struct ldb_message_element *el;
3112 if (!PyArg_ParseTuple(args, "I", &flags))
3115 el = pyldb_MessageElement_AsMessageElement(self);
3120 static PyMethodDef py_ldb_msg_element_methods[] = {
3121 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
3122 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
3123 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
3127 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
3129 return pyldb_MessageElement_AsMessageElement(self)->num_values;
3132 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
3134 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3135 if (idx < 0 || idx >= el->num_values) {
3136 PyErr_SetString(PyExc_IndexError, "Out of range");
3139 return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
3142 static PySequenceMethods py_ldb_msg_element_seq = {
3143 .sq_length = (lenfunc)py_ldb_msg_element_len,
3144 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
3147 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3150 if (!pyldb_MessageElement_Check(other)) {
3151 Py_INCREF(Py_NotImplemented);
3152 return Py_NotImplemented;
3154 ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3155 pyldb_MessageElement_AsMessageElement(other));
3156 return richcmp(ret, op);
3159 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3161 PyObject *el = ldb_msg_element_to_set(NULL,
3162 pyldb_MessageElement_AsMessageElement(self));
3163 PyObject *ret = PyObject_GetIter(el);
3168 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3170 PyLdbMessageElementObject *ret;
3171 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3176 ret->mem_ctx = talloc_new(NULL);
3177 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
3182 return (PyObject *)ret;
3185 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3187 PyObject *py_elements = NULL;
3188 struct ldb_message_element *el;
3189 unsigned int flags = 0;
3191 const char * const kwnames[] = { "elements", "flags", "name", NULL };
3192 PyLdbMessageElementObject *ret;
3193 TALLOC_CTX *mem_ctx;
3194 const char *msg = NULL;
3198 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3199 discard_const_p(char *, kwnames),
3200 &py_elements, &flags, &name))
3203 mem_ctx = talloc_new(NULL);
3204 if (mem_ctx == NULL) {
3209 el = talloc_zero(mem_ctx, struct ldb_message_element);
3212 talloc_free(mem_ctx);
3216 if (py_elements != NULL) {
3218 if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) {
3221 el->values = talloc_array(el, struct ldb_val, 1);
3222 if (el->values == NULL) {
3223 talloc_free(mem_ctx);
3227 if (PyBytes_Check(py_elements)) {
3228 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3231 msg = PyStr_AsUTF8AndSize(py_elements, &size);
3232 result = (msg == NULL) ? -1 : 0;
3235 talloc_free(mem_ctx);
3238 el->values[0].data = talloc_memdup(el->values,
3239 (const uint8_t *)msg, size + 1);
3240 el->values[0].length = size;
3241 } else if (PySequence_Check(py_elements)) {
3242 el->num_values = PySequence_Size(py_elements);
3243 el->values = talloc_array(el, struct ldb_val, el->num_values);
3244 if (el->values == NULL) {
3245 talloc_free(mem_ctx);
3249 for (i = 0; i < el->num_values; i++) {
3250 PyObject *item = PySequence_GetItem(py_elements, i);
3252 talloc_free(mem_ctx);
3255 if (PyBytes_Check(item)) {
3257 result = PyBytes_AsStringAndSize(item, &_msg, &size);
3259 } else if (PyUnicode_Check(item)) {
3260 msg = PyStr_AsUTF8AndSize(item, &size);
3261 result = (msg == NULL) ? -1 : 0;
3263 PyErr_Format(PyExc_TypeError,
3264 "Expected string as element %zd in list", i);
3268 talloc_free(mem_ctx);
3271 el->values[i].data = talloc_memdup(el,
3272 (const uint8_t *)msg, size+1);
3273 el->values[i].length = size;
3276 PyErr_SetString(PyExc_TypeError,
3277 "Expected string or list");
3278 talloc_free(mem_ctx);
3284 el->name = talloc_strdup(el, name);
3286 ret = PyObject_New(PyLdbMessageElementObject, type);
3288 talloc_free(mem_ctx);
3292 ret->mem_ctx = mem_ctx;
3294 return (PyObject *)ret;
3297 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3299 char *element_str = NULL;
3301 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3302 PyObject *ret, *repr;
3304 for (i = 0; i < el->num_values; i++) {
3305 PyObject *o = py_ldb_msg_element_find(self, i);
3306 repr = PyObject_Repr(o);
3307 if (element_str == NULL)
3308 element_str = talloc_strdup(NULL, PyStr_AsUTF8(repr));
3310 element_str = talloc_asprintf_append(element_str, ",%s", PyStr_AsUTF8(repr));
3314 if (element_str != NULL) {
3315 ret = PyStr_FromFormat("MessageElement([%s])", element_str);
3316 talloc_free(element_str);
3318 ret = PyStr_FromString("MessageElement([])");
3324 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3326 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3328 if (el->num_values == 1)
3329 return PyStr_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3334 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3336 talloc_free(self->mem_ctx);
3340 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3342 return wrap_text("MessageElementTextWrapper", self);
3345 static PyGetSetDef py_ldb_msg_element_getset[] = {
3347 .name = discard_const_p(char, "text"),
3348 .get = (getter)py_ldb_msg_element_get_text,
3353 static PyTypeObject PyLdbMessageElement = {
3354 .tp_name = "ldb.MessageElement",
3355 .tp_basicsize = sizeof(PyLdbMessageElementObject),
3356 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3357 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3358 .tp_str = (reprfunc)py_ldb_msg_element_str,
3359 .tp_methods = py_ldb_msg_element_methods,
3360 .tp_getset = py_ldb_msg_element_getset,
3361 .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3362 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3363 .tp_as_sequence = &py_ldb_msg_element_seq,
3364 .tp_new = py_ldb_msg_element_new,
3365 .tp_flags = Py_TPFLAGS_DEFAULT,
3366 .tp_doc = "An element of a Message",
3370 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3375 struct ldb_message *msg;
3376 struct ldb_context *ldb_ctx;
3377 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3379 if (!PyArg_ParseTuple(args, "O!O!|I",
3380 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3385 if (!PyLdb_Check(py_ldb)) {
3386 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
3390 /* mask only flags we are going to use */
3391 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3393 PyErr_SetString(PyExc_ValueError,
3394 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3395 " expected as mod_flag value");
3399 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
3401 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3406 py_ret = PyLdbMessage_FromMessage(msg);
3408 talloc_unlink(ldb_ctx, msg);
3413 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3416 if (!PyArg_ParseTuple(args, "s", &name))
3419 ldb_msg_remove_attr(self->msg, name);
3424 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self,
3425 PyObject *Py_UNUSED(ignored))
3427 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3428 Py_ssize_t i, j = 0;
3429 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3430 if (msg->dn != NULL) {
3431 PyList_SetItem(obj, j, PyStr_FromString("dn"));
3434 for (i = 0; i < msg->num_elements; i++) {
3435 PyList_SetItem(obj, j, PyStr_FromString(msg->elements[i].name));
3441 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
3443 struct ldb_message_element *el;
3445 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3446 name = PyStr_AsUTF8(py_name);
3448 PyErr_SetNone(PyExc_TypeError);
3451 if (!ldb_attr_cmp(name, "dn"))
3452 return pyldb_Dn_FromDn(msg->dn);
3453 el = ldb_msg_find_element(msg, name);
3457 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3460 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3462 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
3464 PyErr_SetString(PyExc_KeyError, "No such element");
3470 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3472 PyObject *def = NULL;
3473 const char *kwnames[] = { "name", "default", "idx", NULL };
3474 const char *name = NULL;
3476 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3477 struct ldb_message_element *el;
3479 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3480 discard_const_p(char *, kwnames), &name, &def, &idx)) {
3484 if (strcasecmp(name, "dn") == 0) {
3485 return pyldb_Dn_FromDn(msg->dn);
3488 el = ldb_msg_find_element(msg, name);
3490 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3499 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3502 return PyObject_FromLdbValue(&el->values[idx]);
3505 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self,
3506 PyObject *Py_UNUSED(ignored))
3508 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3509 Py_ssize_t i, j = 0;
3510 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3512 return PyErr_NoMemory();
3514 if (msg->dn != NULL) {
3515 PyObject *value = NULL;
3516 PyObject *obj = pyldb_Dn_FromDn(msg->dn);
3518 value = Py_BuildValue("(sO)", "dn", obj);
3520 if (value == NULL) {
3524 res = PyList_SetItem(l, 0, value);
3531 for (i = 0; i < msg->num_elements; i++, j++) {
3532 PyObject *value = NULL;
3533 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3536 value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3537 if (value == NULL ) {
3541 res = PyList_SetItem(l, 0, value);
3550 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self,
3551 PyObject *Py_UNUSED(ignored))
3553 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3555 PyObject *l = PyList_New(msg->num_elements);
3556 for (i = 0; i < msg->num_elements; i++) {
3557 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
3562 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3564 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3565 PyLdbMessageElementObject *py_element;
3567 struct ldb_message_element *el;
3568 struct ldb_message_element *el_new;
3570 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
3573 el = py_element->el;
3575 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3578 if (el->name == NULL) {
3579 PyErr_SetString(PyExc_ValueError,
3580 "The element has no name");
3583 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3584 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3586 /* now deep copy all attribute values */
3587 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3588 if (el_new->values == NULL) {
3592 el_new->num_values = el->num_values;
3594 for (i = 0; i < el->num_values; i++) {
3595 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
3596 if (el_new->values[i].data == NULL
3597 && el->values[i].length != 0) {
3606 static PyMethodDef py_ldb_msg_methods[] = {
3607 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
3608 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3609 "Class method to create ldb.Message object from Dictionary.\n"
3610 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3611 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
3612 "S.keys() -> list\n\n"
3613 "Return sequence of all attribute names." },
3614 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
3615 "S.remove(name)\n\n"
3616 "Remove all entries for attributes with the specified name."},
3617 { "get", PY_DISCARD_FUNC_SIG(PyCFunction, py_ldb_msg_get),
3618 METH_VARARGS | METH_KEYWORDS,
3619 "msg.get(name,default=None,idx=None) -> string\n"
3620 "idx is the index into the values array\n"
3621 "if idx is None, then a list is returned\n"
3622 "if idx is not None, then the element with that index is returned\n"
3623 "if you pass the special name 'dn' then the DN object is returned\n"},
3624 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
3625 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
3626 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
3627 "S.add(element)\n\n"
3628 "Add an element to this message." },
3632 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
3634 PyObject *list, *iter;
3636 list = py_ldb_msg_keys(self, NULL);
3637 iter = PyObject_GetIter(list);
3642 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
3644 const char *attr_name;
3646 attr_name = PyStr_AsUTF8(name);
3647 if (attr_name == NULL) {
3648 PyErr_SetNone(PyExc_TypeError);
3652 if (value == NULL) {
3654 ldb_msg_remove_attr(self->msg, attr_name);
3657 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
3658 value, 0, attr_name);
3662 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
3663 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
3664 if (ret != LDB_SUCCESS) {
3665 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
3672 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
3674 return pyldb_Message_AsMessage(self)->num_elements;
3677 static PyMappingMethods py_ldb_msg_mapping = {
3678 .mp_length = (lenfunc)py_ldb_msg_length,
3679 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
3680 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
3683 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3685 const char * const kwnames[] = { "dn", NULL };
3686 struct ldb_message *ret;
3687 TALLOC_CTX *mem_ctx;
3688 PyObject *pydn = NULL;
3689 PyLdbMessageObject *py_ret;
3691 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
3692 discard_const_p(char *, kwnames),
3696 mem_ctx = talloc_new(NULL);
3697 if (mem_ctx == NULL) {
3702 ret = ldb_msg_new(mem_ctx);
3704 talloc_free(mem_ctx);
3711 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
3712 talloc_free(mem_ctx);
3715 ret->dn = talloc_reference(ret, dn);
3718 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
3719 if (py_ret == NULL) {
3721 talloc_free(mem_ctx);
3725 py_ret->mem_ctx = mem_ctx;
3727 return (PyObject *)py_ret;
3730 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
3732 PyLdbMessageObject *ret;
3734 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3739 ret->mem_ctx = talloc_new(NULL);
3740 ret->msg = talloc_reference(ret->mem_ctx, msg);
3741 return (PyObject *)ret;
3744 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3746 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3747 return pyldb_Dn_FromDn(msg->dn);
3750 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3752 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3753 if (!pyldb_Dn_Check(value)) {
3754 PyErr_SetString(PyExc_TypeError, "expected dn");
3758 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3762 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
3764 return wrap_text("MessageTextWrapper", self);
3767 static PyGetSetDef py_ldb_msg_getset[] = {
3769 .name = discard_const_p(char, "dn"),
3770 .get = (getter)py_ldb_msg_get_dn,
3771 .set = (setter)py_ldb_msg_set_dn,
3774 .name = discard_const_p(char, "text"),
3775 .get = (getter)py_ldb_msg_get_text,
3780 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3782 PyObject *dict = PyDict_New(), *ret, *repr;
3783 if (PyDict_Update(dict, (PyObject *)self) != 0)
3785 repr = PyObject_Repr(dict);
3790 ret = PyStr_FromFormat("Message(%s)", PyStr_AsUTF8(repr));
3796 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3798 talloc_free(self->mem_ctx);
3802 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3803 PyLdbMessageObject *py_msg2, int op)
3805 struct ldb_message *msg1, *msg2;
3809 if (!PyLdbMessage_Check(py_msg2)) {
3810 Py_INCREF(Py_NotImplemented);
3811 return Py_NotImplemented;
3814 msg1 = pyldb_Message_AsMessage(py_msg1),
3815 msg2 = pyldb_Message_AsMessage(py_msg2);
3817 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3818 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3820 return richcmp(ret, op);
3824 ret = msg1->num_elements - msg2->num_elements;
3826 return richcmp(ret, op);
3829 for (i = 0; i < msg1->num_elements; i++) {
3830 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3831 &msg2->elements[i]);
3833 return richcmp(ret, op);
3836 ret = ldb_msg_element_compare(&msg1->elements[i],
3837 &msg2->elements[i]);
3839 return richcmp(ret, op);
3843 return richcmp(0, op);
3846 static PyTypeObject PyLdbMessage = {
3847 .tp_name = "ldb.Message",
3848 .tp_methods = py_ldb_msg_methods,
3849 .tp_getset = py_ldb_msg_getset,
3850 .tp_as_mapping = &py_ldb_msg_mapping,
3851 .tp_basicsize = sizeof(PyLdbMessageObject),
3852 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3853 .tp_new = py_ldb_msg_new,
3854 .tp_repr = (reprfunc)py_ldb_msg_repr,
3855 .tp_flags = Py_TPFLAGS_DEFAULT,
3856 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3857 .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3858 .tp_doc = "A LDB Message",
3861 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3863 PyLdbTreeObject *ret;
3865 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3871 ret->mem_ctx = talloc_new(NULL);
3872 ret->tree = talloc_reference(ret->mem_ctx, tree);
3873 return (PyObject *)ret;
3876 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3878 talloc_free(self->mem_ctx);
3882 static PyTypeObject PyLdbTree = {
3883 .tp_name = "ldb.Tree",
3884 .tp_basicsize = sizeof(PyLdbTreeObject),
3885 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3886 .tp_flags = Py_TPFLAGS_DEFAULT,
3887 .tp_doc = "A search tree",
3891 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3893 PyObject *py_ldb = (PyObject *)mod->private_data;
3894 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3896 py_base = pyldb_Dn_FromDn(req->op.search.base);
3898 if (py_base == NULL)
3899 return LDB_ERR_OPERATIONS_ERROR;
3901 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3903 if (py_tree == NULL)
3904 return LDB_ERR_OPERATIONS_ERROR;
3906 if (req->op.search.attrs == NULL) {
3910 for (len = 0; req->op.search.attrs[len]; len++);
3911 py_attrs = PyList_New(len);
3912 for (i = 0; i < len; i++)
3913 PyList_SetItem(py_attrs, i, PyStr_FromString(req->op.search.attrs[i]));
3916 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3917 discard_const_p(char, "OiOO"),
3918 py_base, req->op.search.scope, py_tree, py_attrs);
3920 Py_DECREF(py_attrs);
3924 if (py_result == NULL) {
3925 return LDB_ERR_PYTHON_EXCEPTION;
3928 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3929 if (req->op.search.res == NULL) {
3930 return LDB_ERR_PYTHON_EXCEPTION;
3933 Py_DECREF(py_result);
3938 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3940 PyObject *py_ldb = (PyObject *)mod->private_data;
3941 PyObject *py_result, *py_msg;
3943 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3945 if (py_msg == NULL) {
3946 return LDB_ERR_OPERATIONS_ERROR;
3949 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3950 discard_const_p(char, "O"),
3955 if (py_result == NULL) {
3956 return LDB_ERR_PYTHON_EXCEPTION;
3959 Py_DECREF(py_result);
3964 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3966 PyObject *py_ldb = (PyObject *)mod->private_data;
3967 PyObject *py_result, *py_msg;
3969 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3971 if (py_msg == NULL) {
3972 return LDB_ERR_OPERATIONS_ERROR;
3975 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3976 discard_const_p(char, "O"),
3981 if (py_result == NULL) {
3982 return LDB_ERR_PYTHON_EXCEPTION;
3985 Py_DECREF(py_result);
3990 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3992 PyObject *py_ldb = (PyObject *)mod->private_data;
3993 PyObject *py_result, *py_dn;
3995 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3998 return LDB_ERR_OPERATIONS_ERROR;
4000 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
4001 discard_const_p(char, "O"),
4004 if (py_result == NULL) {
4005 return LDB_ERR_PYTHON_EXCEPTION;
4008 Py_DECREF(py_result);
4013 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
4015 PyObject *py_ldb = (PyObject *)mod->private_data;
4016 PyObject *py_result, *py_olddn, *py_newdn;
4018 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
4020 if (py_olddn == NULL)
4021 return LDB_ERR_OPERATIONS_ERROR;
4023 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
4025 if (py_newdn == NULL)
4026 return LDB_ERR_OPERATIONS_ERROR;
4028 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
4029 discard_const_p(char, "OO"),
4030 py_olddn, py_newdn);
4032 Py_DECREF(py_olddn);
4033 Py_DECREF(py_newdn);
4035 if (py_result == NULL) {
4036 return LDB_ERR_PYTHON_EXCEPTION;
4039 Py_DECREF(py_result);
4044 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
4046 PyObject *py_ldb = (PyObject *)mod->private_data;
4047 PyObject *py_result;
4049 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
4050 discard_const_p(char, ""));
4052 Py_XDECREF(py_result);
4054 return LDB_ERR_OPERATIONS_ERROR;
4057 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
4059 PyObject *py_ldb = (PyObject *)mod->private_data;
4060 PyObject *py_result;
4062 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
4063 discard_const_p(char, ""));
4065 Py_XDECREF(py_result);
4067 return LDB_ERR_OPERATIONS_ERROR;
4070 static int py_module_start_transaction(struct ldb_module *mod)
4072 PyObject *py_ldb = (PyObject *)mod->private_data;
4073 PyObject *py_result;
4075 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
4076 discard_const_p(char, ""));
4078 if (py_result == NULL) {
4079 return LDB_ERR_PYTHON_EXCEPTION;
4082 Py_DECREF(py_result);
4087 static int py_module_end_transaction(struct ldb_module *mod)
4089 PyObject *py_ldb = (PyObject *)mod->private_data;
4090 PyObject *py_result;
4092 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
4093 discard_const_p(char, ""));
4095 if (py_result == NULL) {
4096 return LDB_ERR_PYTHON_EXCEPTION;
4099 Py_DECREF(py_result);
4104 static int py_module_del_transaction(struct ldb_module *mod)
4106 PyObject *py_ldb = (PyObject *)mod->private_data;
4107 PyObject *py_result;
4109 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
4110 discard_const_p(char, ""));
4112 if (py_result == NULL) {
4113 return LDB_ERR_PYTHON_EXCEPTION;
4116 Py_DECREF(py_result);
4121 static int py_module_destructor(struct ldb_module *mod)
4123 Py_DECREF((PyObject *)mod->private_data);
4127 static int py_module_init(struct ldb_module *mod)
4129 PyObject *py_class = (PyObject *)mod->ops->private_data;
4130 PyObject *py_result, *py_next, *py_ldb;
4132 py_ldb = PyLdb_FromLdbContext(mod->ldb);
4135 return LDB_ERR_OPERATIONS_ERROR;
4137 py_next = PyLdbModule_FromModule(mod->next);
4139 if (py_next == NULL)
4140 return LDB_ERR_OPERATIONS_ERROR;
4142 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
4145 if (py_result == NULL) {
4146 return LDB_ERR_PYTHON_EXCEPTION;
4149 mod->private_data = py_result;
4151 talloc_set_destructor(mod, py_module_destructor);
4153 return ldb_next_init(mod);
4156 static PyObject *py_register_module(PyObject *module, PyObject *args)
4159 struct ldb_module_ops *ops;
4163 if (!PyArg_ParseTuple(args, "O", &input))
4166 ops = talloc_zero(NULL, struct ldb_module_ops);
4172 tmp = PyObject_GetAttrString(input, discard_const_p(char, "name"));
4173 ops->name = talloc_strdup(ops, PyStr_AsUTF8(tmp));
4177 ops->private_data = input;
4178 ops->init_context = py_module_init;
4179 ops->search = py_module_search;
4180 ops->add = py_module_add;
4181 ops->modify = py_module_modify;
4182 ops->del = py_module_del;
4183 ops->rename = py_module_rename;
4184 ops->request = py_module_request;
4185 ops->extended = py_module_extended;
4186 ops->start_transaction = py_module_start_transaction;
4187 ops->end_transaction = py_module_end_transaction;
4188 ops->del_transaction = py_module_del_transaction;
4190 ret = ldb_register_module(ops);
4191 if (ret != LDB_SUCCESS) {
4195 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
4200 static PyObject *py_timestring(PyObject *module, PyObject *args)
4202 /* most times "time_t" is a signed integer type with 32 or 64 bit:
4203 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4207 if (!PyArg_ParseTuple(args, "l", &t_val))
4209 tresult = ldb_timestring(NULL, (time_t) t_val);
4210 ret = PyStr_FromString(tresult);
4211 talloc_free(tresult);
4215 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
4218 if (!PyArg_ParseTuple(args, "s", &str))
4221 return PyInt_FromLong(ldb_string_to_time(str));
4224 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4227 if (!PyArg_ParseTuple(args, "s", &name))
4229 return PyBool_FromLong(ldb_valid_attr_name(name));
4233 encode a string using RFC2254 rules
4235 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4237 char *str, *encoded;
4238 Py_ssize_t size = 0;
4242 if (!PyArg_ParseTuple(args, "s#", &str, &size))
4244 val.data = (uint8_t *)str;
4247 encoded = ldb_binary_encode(NULL, val);
4248 if (encoded == NULL) {
4249 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4252 ret = PyStr_FromString(encoded);
4253 talloc_free(encoded);
4258 decode a string using RFC2254 rules
4260 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4266 if (!PyArg_ParseTuple(args, "s", &str))
4269 val = ldb_binary_decode(NULL, str);
4270 if (val.data == NULL) {
4271 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4274 ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4275 talloc_free(val.data);
4279 static PyMethodDef py_ldb_global_methods[] = {
4280 { "register_module", py_register_module, METH_VARARGS,
4281 "S.register_module(module) -> None\n\n"
4282 "Register a LDB module."},
4283 { "timestring", py_timestring, METH_VARARGS,
4284 "S.timestring(int) -> string\n\n"
4285 "Generate a LDAP time string from a UNIX timestamp" },
4286 { "string_to_time", py_string_to_time, METH_VARARGS,
4287 "S.string_to_time(string) -> int\n\n"
4288 "Parse a LDAP time string into a UNIX timestamp." },
4289 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4290 "S.valid_attr_name(name) -> bool\n\nn"
4291 "Check whether the supplied name is a valid attribute name." },
4292 { "open", PY_DISCARD_FUNC_SIG(PyCFunction,py_ldb_new),
4293 METH_VARARGS|METH_KEYWORDS,
4294 "S.open() -> Ldb\n\n"
4295 "Open a new LDB context." },
4296 { "binary_encode", py_binary_encode, METH_VARARGS,
4297 "S.binary_encode(string) -> string\n\n"
4298 "Perform a RFC2254 binary encoding on a string" },
4299 { "binary_decode", py_binary_decode, METH_VARARGS,
4300 "S.binary_decode(string) -> string\n\n"
4301 "Perform a RFC2254 binary decode on a string" },
4305 #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."
4307 #if PY_MAJOR_VERSION >= 3
4308 static struct PyModuleDef moduledef = {
4309 PyModuleDef_HEAD_INIT,
4311 .m_doc = MODULE_DOC,
4313 .m_methods = py_ldb_global_methods,
4317 static PyObject* module_init(void)
4321 PyLdbBytesType.tp_base = &PyBytes_Type;
4322 if (PyType_Ready(&PyLdbBytesType) < 0) {
4326 if (PyType_Ready(&PyLdbDn) < 0)
4329 if (PyType_Ready(&PyLdbMessage) < 0)
4332 if (PyType_Ready(&PyLdbMessageElement) < 0)
4335 if (PyType_Ready(&PyLdb) < 0)
4338 if (PyType_Ready(&PyLdbModule) < 0)
4341 if (PyType_Ready(&PyLdbTree) < 0)
4344 if (PyType_Ready(&PyLdbResult) < 0)
4347 if (PyType_Ready(&PyLdbSearchIterator) < 0)
4350 if (PyType_Ready(&PyLdbControl) < 0)
4353 #if PY_MAJOR_VERSION >= 3
4354 m = PyModule_Create(&moduledef);
4356 m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC);
4361 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4363 ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4364 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4365 ADD_LDB_INT(SEQ_NEXT);
4366 ADD_LDB_INT(SCOPE_DEFAULT);
4367 ADD_LDB_INT(SCOPE_BASE);
4368 ADD_LDB_INT(SCOPE_ONELEVEL);
4369 ADD_LDB_INT(SCOPE_SUBTREE);
4371 ADD_LDB_INT(CHANGETYPE_NONE);
4372 ADD_LDB_INT(CHANGETYPE_ADD);
4373 ADD_LDB_INT(CHANGETYPE_DELETE);
4374 ADD_LDB_INT(CHANGETYPE_MODIFY);
4376 ADD_LDB_INT(FLAG_MOD_ADD);
4377 ADD_LDB_INT(FLAG_MOD_REPLACE);
4378 ADD_LDB_INT(FLAG_MOD_DELETE);
4380 ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4381 ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4382 ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4383 ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4385 ADD_LDB_INT(SUCCESS);
4386 ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4387 ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4388 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4389 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4390 ADD_LDB_INT(ERR_COMPARE_FALSE);
4391 ADD_LDB_INT(ERR_COMPARE_TRUE);
4392 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4393 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4394 ADD_LDB_INT(ERR_REFERRAL);
4395 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4396 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4397 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4398 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4399 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4400 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4401 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4402 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4403 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4404 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4405 ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4406 ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4407 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4408 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4409 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4410 ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4411 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4412 ADD_LDB_INT(ERR_BUSY);
4413 ADD_LDB_INT(ERR_UNAVAILABLE);
4414 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4415 ADD_LDB_INT(ERR_LOOP_DETECT);
4416 ADD_LDB_INT(ERR_NAMING_VIOLATION);
4417 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4418 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4419 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4420 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4421 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4422 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4423 ADD_LDB_INT(ERR_OTHER);
4425 ADD_LDB_INT(FLG_RDONLY);
4426 ADD_LDB_INT(FLG_NOSYNC);
4427 ADD_LDB_INT(FLG_RECONNECT);
4428 ADD_LDB_INT(FLG_NOMMAP);
4429 ADD_LDB_INT(FLG_SHOW_BINARY);
4430 ADD_LDB_INT(FLG_ENABLE_TRACING);
4431 ADD_LDB_INT(FLG_DONT_CREATE_DB);
4434 /* Historical misspelling */
4435 PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
4437 PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
4439 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
4440 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
4443 Py_INCREF(&PyLdbDn);
4444 Py_INCREF(&PyLdbModule);
4445 Py_INCREF(&PyLdbMessage);
4446 Py_INCREF(&PyLdbMessageElement);
4447 Py_INCREF(&PyLdbTree);
4448 Py_INCREF(&PyLdbResult);
4449 Py_INCREF(&PyLdbControl);
4451 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
4452 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
4453 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
4454 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
4455 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
4456 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
4457 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
4459 PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
4461 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
4463 ADD_LDB_STRING(SYNTAX_DN);
4464 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
4465 ADD_LDB_STRING(SYNTAX_INTEGER);
4466 ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER);
4467 ADD_LDB_STRING(SYNTAX_BOOLEAN);
4468 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
4469 ADD_LDB_STRING(SYNTAX_UTC_TIME);
4470 ADD_LDB_STRING(OID_COMPARATOR_AND);
4471 ADD_LDB_STRING(OID_COMPARATOR_OR);
4476 #if PY_MAJOR_VERSION >= 3
4477 PyMODINIT_FUNC PyInit_ldb(void);
4478 PyMODINIT_FUNC PyInit_ldb(void)
4480 return module_init();