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"
37 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
38 static PyObject *PyExc_LdbError;
40 static PyTypeObject PyLdbControl;
41 static PyTypeObject PyLdbResult;
42 static PyTypeObject PyLdbMessage;
43 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
44 static PyTypeObject PyLdbModule;
45 static PyTypeObject PyLdbDn;
46 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
47 static PyTypeObject PyLdb;
48 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
49 static PyTypeObject PyLdbMessageElement;
50 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
52 static PyTypeObject PyLdbTree;
53 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
54 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
55 static struct ldb_message_element *PyObject_AsMessageElement(
59 const char *attr_name);
61 #if PY_MAJOR_VERSION >= 3
62 #define PyStr_Check PyUnicode_Check
63 #define PyStr_FromString PyUnicode_FromString
64 #define PyStr_FromStringAndSize PyUnicode_FromStringAndSize
65 #define PyStr_FromFormat PyUnicode_FromFormat
66 #define PyStr_FromFormatV PyUnicode_FromFormatV
67 #define PyStr_AsUTF8 PyUnicode_AsUTF8
68 #define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize
69 #define PyInt_FromLong PyLong_FromLong
71 #define PyStr_Check PyString_Check
72 #define PyStr_FromString PyString_FromString
73 #define PyStr_FromStringAndSize PyString_FromStringAndSize
74 #define PyStr_FromFormat PyString_FromFormat
75 #define PyStr_FromFormatV PyString_FromFormatV
76 #define PyStr_AsUTF8 PyString_AsString
78 const char *PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr);
80 PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr)
82 const char * ret = PyString_AsString(pystr);
85 *sizeptr = PyString_Size(pystr);
90 static PyObject *richcmp(int cmp_val, int op)
94 case Py_LT: ret = cmp_val < 0; break;
95 case Py_LE: ret = cmp_val <= 0; break;
96 case Py_EQ: ret = cmp_val == 0; break;
97 case Py_NE: ret = cmp_val != 0; break;
98 case Py_GT: ret = cmp_val > 0; break;
99 case Py_GE: ret = cmp_val >= 0; break;
101 Py_INCREF(Py_NotImplemented);
102 return Py_NotImplemented;
104 return PyBool_FromLong(ret);
108 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
110 if (self->data != NULL) {
111 char* control = ldb_control_to_string(self->mem_ctx, self->data);
112 if (control == NULL) {
116 return PyStr_FromString(control);
118 return PyStr_FromString("ldb control");
122 static void py_ldb_control_dealloc(PyLdbControlObject *self)
124 if (self->mem_ctx != NULL) {
125 talloc_free(self->mem_ctx);
128 Py_TYPE(self)->tp_free(self);
131 /* Create a text (rather than bytes) interface for a LDB result object */
132 static PyObject *wrap_text(const char *type, PyObject *wrapped)
134 PyObject *mod, *cls, *constructor, *inst;
135 mod = PyImport_ImportModule("_ldb_text");
138 cls = PyObject_GetAttrString(mod, type);
144 constructor = PyObject_GetAttrString(cls, "_wrap");
146 if (constructor == NULL) {
149 inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped);
150 Py_DECREF(constructor);
154 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
156 return PyStr_FromString(self->data->oid);
159 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
161 return PyBool_FromLong(self->data->critical);
164 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
166 if (PyObject_IsTrue(value)) {
167 self->data->critical = true;
169 self->data->critical = false;
174 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
177 const char * const kwnames[] = { "ldb", "data", NULL };
178 struct ldb_control *parsed_controls;
179 PyLdbControlObject *ret;
182 struct ldb_context *ldb_ctx;
184 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
185 discard_const_p(char *, kwnames),
186 &PyLdb, &py_ldb, &data))
189 mem_ctx = talloc_new(NULL);
190 if (mem_ctx == NULL) {
195 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
196 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
198 if (!parsed_controls) {
199 talloc_free(mem_ctx);
200 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
204 ret = PyObject_New(PyLdbControlObject, type);
207 talloc_free(mem_ctx);
211 ret->mem_ctx = mem_ctx;
213 ret->data = talloc_move(mem_ctx, &parsed_controls);
214 if (ret->data == NULL) {
217 talloc_free(mem_ctx);
221 return (PyObject *)ret;
224 static PyGetSetDef py_ldb_control_getset[] = {
225 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
226 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
230 static PyTypeObject PyLdbControl = {
231 .tp_name = "ldb.control",
232 .tp_dealloc = (destructor)py_ldb_control_dealloc,
233 .tp_getattro = PyObject_GenericGetAttr,
234 .tp_basicsize = sizeof(PyLdbControlObject),
235 .tp_getset = py_ldb_control_getset,
236 .tp_doc = "LDB control.",
237 .tp_str = (reprfunc)py_ldb_control_str,
238 .tp_new = py_ldb_control_new,
239 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
242 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
244 if (ret == LDB_ERR_PYTHON_EXCEPTION)
245 return; /* Python exception should already be set, just keep that */
247 PyErr_SetObject(error,
248 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
249 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
252 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
254 return PyBytes_FromStringAndSize((const char *)val->data, val->length);
257 static PyObject *PyStr_FromLdbValue(const struct ldb_val *val)
259 return PyStr_FromStringAndSize((const char *)val->data, val->length);
263 * Create a Python object from a ldb_result.
265 * @param result LDB result to convert
266 * @return Python object with converted result (a list object)
268 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
270 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
271 PyLdbControlObject *ctrl;
272 if (ctl_ctx == NULL) {
277 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
279 talloc_free(ctl_ctx);
283 ctrl->mem_ctx = ctl_ctx;
284 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
285 if (ctrl->data == NULL) {
290 return (PyObject*) ctrl;
294 * Create a Python object from a ldb_result.
296 * @param result LDB result to convert
297 * @return Python object with converted result (a list object)
299 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
301 PyLdbResultObject *ret;
302 PyObject *list, *controls, *referals;
305 if (result == NULL) {
309 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
315 list = PyList_New(result->count);
322 for (i = 0; i < result->count; i++) {
323 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
326 ret->mem_ctx = talloc_new(NULL);
327 if (ret->mem_ctx == NULL) {
336 if (result->controls) {
338 while (result->controls[i]) {
341 controls = PyList_New(i);
342 if (controls == NULL) {
347 for (i=0; result->controls[i]; i++) {
348 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
355 PyList_SetItem(controls, i, ctrl);
359 * No controls so we keep an empty list
361 controls = PyList_New(0);
362 if (controls == NULL) {
369 ret->controls = controls;
373 while (result->refs && result->refs[i]) {
377 referals = PyList_New(i);
378 if (referals == NULL) {
384 for (i = 0;result->refs && result->refs[i]; i++) {
385 PyList_SetItem(referals, i, PyStr_FromString(result->refs[i]));
387 ret->referals = referals;
388 return (PyObject *)ret;
392 * Create a LDB Result from a Python object.
393 * If conversion fails, NULL will be returned and a Python exception set.
395 * Note: the result object only includes the messages at the moment; extended
396 * result, controls and referrals are ignored.
398 * @param mem_ctx Memory context in which to allocate the LDB Result
399 * @param obj Python object to convert
400 * @return a ldb_result, or NULL if the conversion failed
402 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
405 struct ldb_result *res;
411 res = talloc_zero(mem_ctx, struct ldb_result);
412 res->count = PyList_Size(obj);
413 res->msgs = talloc_array(res, struct ldb_message *, res->count);
414 for (i = 0; i < res->count; i++) {
415 PyObject *item = PyList_GetItem(obj, i);
416 res->msgs[i] = pyldb_Message_AsMessage(item);
421 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
423 return PyBool_FromLong(ldb_dn_validate(self->dn));
426 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
428 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
431 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
433 return PyBool_FromLong(ldb_dn_is_special(self->dn));
436 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
438 return PyBool_FromLong(ldb_dn_is_null(self->dn));
441 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
443 return PyStr_FromString(ldb_dn_get_casefold(self->dn));
446 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
448 return PyStr_FromString(ldb_dn_get_linearized(self->dn));
451 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
453 return PyStr_FromString(ldb_dn_canonical_string(self->dn, self->dn));
456 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
458 return PyStr_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
461 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
463 const char * const kwnames[] = { "mode", NULL };
465 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
466 discard_const_p(char *, kwnames),
469 return PyStr_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
472 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
475 const struct ldb_val *val;
477 if (!PyArg_ParseTuple(args, "s", &name))
479 val = ldb_dn_get_extended_component(self->dn, name);
484 return PyBytes_FromStringAndSize((const char *)val->data, val->length);
487 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
494 if (!PyArg_ParseTuple(args, "sz#", &name, (const char**)&value, &size))
498 err = ldb_dn_set_extended_component(self->dn, name, NULL);
501 val.data = (uint8_t *)value;
503 err = ldb_dn_set_extended_component(self->dn, name, &val);
506 if (err != LDB_SUCCESS) {
507 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
514 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
516 PyObject *str = PyStr_FromString(ldb_dn_get_linearized(self->dn));
517 PyObject *repr, *result;
520 repr = PyObject_Repr(str);
525 result = PyStr_FromFormat("Dn(%s)", PyStr_AsUTF8(repr));
531 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
535 if (!PyArg_ParseTuple(args, "s", &name))
538 return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
541 static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
544 if (!pyldb_Dn_Check(dn2)) {
545 Py_INCREF(Py_NotImplemented);
546 return Py_NotImplemented;
548 ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2));
549 return richcmp(ret, op);
552 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
554 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
555 struct ldb_dn *parent;
556 PyLdbDnObject *py_ret;
557 TALLOC_CTX *mem_ctx = talloc_new(NULL);
559 parent = ldb_dn_get_parent(mem_ctx, dn);
560 if (parent == NULL) {
561 talloc_free(mem_ctx);
565 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
566 if (py_ret == NULL) {
568 talloc_free(mem_ctx);
571 py_ret->mem_ctx = mem_ctx;
573 return (PyObject *)py_ret;
576 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
579 struct ldb_dn *dn, *other;
580 if (!PyArg_ParseTuple(args, "O", &py_other))
583 dn = pyldb_Dn_AsDn((PyObject *)self);
585 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
588 return PyBool_FromLong(ldb_dn_add_child(dn, other));
591 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
594 struct ldb_dn *other, *dn;
595 if (!PyArg_ParseTuple(args, "O", &py_other))
598 dn = pyldb_Dn_AsDn((PyObject *)self);
600 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
603 return PyBool_FromLong(ldb_dn_add_base(dn, other));
606 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
610 if (!PyArg_ParseTuple(args, "i", &i))
613 dn = pyldb_Dn_AsDn((PyObject *)self);
615 return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
618 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
621 struct ldb_dn *dn, *base;
622 if (!PyArg_ParseTuple(args, "O", &py_base))
625 dn = pyldb_Dn_AsDn((PyObject *)self);
627 if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
630 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
633 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
637 unsigned int num = 0;
639 if (!PyArg_ParseTuple(args, "I", &num))
642 dn = pyldb_Dn_AsDn((PyObject *)self);
644 name = ldb_dn_get_component_name(dn, num);
649 return PyStr_FromString(name);
652 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
655 const struct ldb_val *val;
656 unsigned int num = 0;
658 if (!PyArg_ParseTuple(args, "I", &num))
661 dn = pyldb_Dn_AsDn((PyObject *)self);
663 val = ldb_dn_get_component_val(dn, num);
668 return PyStr_FromLdbValue(val);
671 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
673 unsigned int num = 0;
674 char *name = NULL, *value = NULL;
675 struct ldb_val val = { NULL, };
679 if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size))
682 val.data = (unsigned char*) value;
685 err = ldb_dn_set_component(self->dn, num, name, val);
686 if (err != LDB_SUCCESS) {
687 PyErr_SetString(PyExc_TypeError, "Failed to set component");
694 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
699 dn = pyldb_Dn_AsDn((PyObject *)self);
701 name = ldb_dn_get_rdn_name(dn);
706 return PyStr_FromString(name);
709 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
712 const struct ldb_val *val;
714 dn = pyldb_Dn_AsDn((PyObject *)self);
716 val = ldb_dn_get_rdn_val(dn);
721 return PyStr_FromLdbValue(val);
724 static PyMethodDef py_ldb_dn_methods[] = {
725 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
726 "S.validate() -> bool\n"
727 "Validate DN is correct." },
728 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
729 "S.is_valid() -> bool\n" },
730 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
731 "S.is_special() -> bool\n"
732 "Check whether this is a special LDB DN." },
733 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
734 "Check whether this is a null DN." },
735 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
737 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
739 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
740 "S.canonical_str() -> string\n"
741 "Canonical version of this DN (like a posix path)." },
742 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
743 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
744 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
745 "S.canonical_ex_str() -> string\n"
746 "Canonical version of this DN (like a posix path, with terminating newline)." },
747 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
748 "S.extended_str(mode=1) -> string\n"
749 "Extended version of this DN" },
750 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
752 "Get the parent for this DN." },
753 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
754 "S.add_child(dn) -> None\n"
755 "Add a child DN to this DN." },
756 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
757 "S.add_base(dn) -> None\n"
758 "Add a base DN to this DN." },
759 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
760 "S.remove_base_components(int) -> bool\n"
761 "Remove a number of DN components from the base of this DN." },
762 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
763 "S.check_special(name) -> bool\n\n"
764 "Check if name is a special DN name"},
765 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
766 "S.get_extended_component(name) -> string\n\n"
767 "returns a DN extended component as a binary string"},
768 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
769 "S.set_extended_component(name, value) -> None\n\n"
770 "set a DN extended component as a binary string"},
771 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
772 "S.get_component_name(num) -> string\n"
773 "get the attribute name of the specified component" },
774 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
775 "S.get_component_value(num) -> string\n"
776 "get the attribute value of the specified component as a binary string" },
777 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
778 "S.get_component_value(num, name, value) -> None\n"
779 "set the attribute name and value of the specified component" },
780 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
781 "S.get_rdn_name() -> string\n"
782 "get the RDN attribute name" },
783 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
784 "S.get_rdn_value() -> string\n"
785 "get the RDN attribute value as a binary string" },
789 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
791 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
795 copy a DN as a python object
797 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
799 PyLdbDnObject *py_ret;
801 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
802 if (py_ret == NULL) {
806 py_ret->mem_ctx = talloc_new(NULL);
807 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
808 return (PyObject *)py_ret;
811 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
813 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
815 PyLdbDnObject *py_ret;
817 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
820 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
821 if (py_ret == NULL) {
825 py_ret->mem_ctx = talloc_new(NULL);
826 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
827 ldb_dn_add_base(py_ret->dn, other);
828 return (PyObject *)py_ret;
831 static PySequenceMethods py_ldb_dn_seq = {
832 .sq_length = (lenfunc)py_ldb_dn_len,
833 .sq_concat = (binaryfunc)py_ldb_dn_concat,
836 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
841 struct ldb_context *ldb_ctx;
843 PyLdbDnObject *py_ret;
844 const char * const kwnames[] = { "ldb", "dn", NULL };
846 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
847 discard_const_p(char *, kwnames),
851 if (!PyLdb_Check(py_ldb)) {
852 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
856 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
858 mem_ctx = talloc_new(NULL);
859 if (mem_ctx == NULL) {
864 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
865 if (!ldb_dn_validate(ret)) {
866 talloc_free(mem_ctx);
867 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
871 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
873 talloc_free(mem_ctx);
877 py_ret->mem_ctx = mem_ctx;
879 return (PyObject *)py_ret;
882 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
884 talloc_free(self->mem_ctx);
888 static PyTypeObject PyLdbDn = {
890 .tp_methods = py_ldb_dn_methods,
891 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
892 .tp_repr = (reprfunc)py_ldb_dn_repr,
893 .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp,
894 .tp_as_sequence = &py_ldb_dn_seq,
895 .tp_doc = "A LDB distinguished name.",
896 .tp_new = py_ldb_dn_new,
897 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
898 .tp_basicsize = sizeof(PyLdbDnObject),
899 .tp_flags = Py_TPFLAGS_DEFAULT,
903 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
904 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
906 PyObject *fn = (PyObject *)context;
907 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyStr_FromFormatV(fmt, ap));
910 static PyObject *py_ldb_debug_func;
912 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
915 struct ldb_context *ldb_ctx;
917 if (!PyArg_ParseTuple(args, "O", &cb))
920 if (py_ldb_debug_func != NULL) {
921 Py_DECREF(py_ldb_debug_func);
925 /* FIXME: DECREF cb when exiting program */
926 py_ldb_debug_func = cb;
927 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
928 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
929 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
935 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
938 if (!PyArg_ParseTuple(args, "I", &perms))
941 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
946 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
949 if (!PyArg_ParseTuple(args, "s", &modules_dir))
952 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
957 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
959 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
961 ldb_err = ldb_transaction_start(ldb_ctx);
962 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
966 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
968 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
970 ldb_err = ldb_transaction_commit(ldb_ctx);
971 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
975 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
977 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
979 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
980 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
984 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
986 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
988 ldb_err = ldb_transaction_cancel(ldb_ctx);
989 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
993 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
995 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
997 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
998 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1002 static PyObject *py_ldb_repr(PyLdbObject *self)
1004 return PyStr_FromString("<ldb connection>");
1007 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
1009 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
1012 return py_ldb_dn_copy(dn);
1016 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
1018 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
1021 return py_ldb_dn_copy(dn);
1024 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
1026 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
1029 return py_ldb_dn_copy(dn);
1032 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
1034 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
1037 return py_ldb_dn_copy(dn);
1040 static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
1041 const char *paramname)
1045 if (!PyList_Check(list)) {
1046 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
1049 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1055 for (i = 0; i < PyList_Size(list); i++) {
1056 const char *str = NULL;
1058 PyObject *item = PyList_GetItem(list, i);
1059 if (!PyStr_Check(item)) {
1060 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
1064 str = PyStr_AsUTF8AndSize(item, &size);
1069 ret[i] = talloc_strndup(ret, str, size);
1075 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1077 const char * const kwnames[] = { "url", "flags", "options", NULL };
1079 PyObject *py_options = Py_None;
1080 const char **options;
1081 unsigned int flags = 0;
1083 struct ldb_context *ldb;
1085 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1086 discard_const_p(char *, kwnames),
1087 &url, &flags, &py_options))
1090 ldb = pyldb_Ldb_AsLdbContext(self);
1092 if (py_options == Py_None) {
1095 options = PyList_AsStrList(ldb, py_options, "options");
1096 if (options == NULL)
1101 ret = ldb_connect(ldb, url, flags, options);
1102 if (ret != LDB_SUCCESS) {
1103 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1108 talloc_free(options);
1112 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1115 struct ldb_context *ldb;
1116 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1121 ret->mem_ctx = talloc_new(NULL);
1122 ldb = ldb_init(ret->mem_ctx, NULL);
1130 return (PyObject *)ret;
1133 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1136 unsigned int flags = 0;
1137 PyObject *py_options = Py_None;
1139 const char **options;
1140 const char * const kwnames[] = { "url", "flags", "options", NULL };
1141 struct ldb_context *ldb_ctx;
1143 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
1144 discard_const_p(char *, kwnames),
1145 &url, &flags, &py_options))
1148 if (py_options == Py_None) {
1151 options = PyList_AsStrList(NULL, py_options, "options");
1152 if (options == NULL)
1156 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1157 ret = ldb_connect(ldb_ctx, url, flags, options);
1158 talloc_free(options);
1160 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1165 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1168 PyObject *py_controls = Py_None;
1169 struct ldb_context *ldb_ctx;
1170 struct ldb_request *req;
1171 struct ldb_control **parsed_controls;
1172 struct ldb_message *msg;
1174 TALLOC_CTX *mem_ctx;
1176 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1178 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1179 discard_const_p(char *, kwnames),
1180 &py_msg, &py_controls, &validate))
1183 mem_ctx = talloc_new(NULL);
1184 if (mem_ctx == NULL) {
1188 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1190 if (py_controls == Py_None) {
1191 parsed_controls = NULL;
1193 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1194 if (controls == NULL) {
1195 talloc_free(mem_ctx);
1198 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1199 talloc_free(controls);
1202 if (!PyLdbMessage_Check(py_msg)) {
1203 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1204 talloc_free(mem_ctx);
1207 msg = pyldb_Message_AsMessage(py_msg);
1210 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1211 if (ret != LDB_SUCCESS) {
1212 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1213 talloc_free(mem_ctx);
1218 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1219 NULL, ldb_op_default_callback, NULL);
1220 if (ret != LDB_SUCCESS) {
1221 PyErr_SetString(PyExc_TypeError, "failed to build request");
1222 talloc_free(mem_ctx);
1226 /* do request and autostart a transaction */
1227 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1229 ret = ldb_transaction_start(ldb_ctx);
1230 if (ret != LDB_SUCCESS) {
1231 talloc_free(mem_ctx);
1232 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1236 ret = ldb_request(ldb_ctx, req);
1237 if (ret == LDB_SUCCESS) {
1238 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1241 if (ret == LDB_SUCCESS) {
1242 ret = ldb_transaction_commit(ldb_ctx);
1244 ldb_transaction_cancel(ldb_ctx);
1247 talloc_free(mem_ctx);
1248 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1255 * Obtain a ldb message from a Python Dictionary object.
1257 * @param mem_ctx Memory context
1258 * @param py_obj Python Dictionary object
1259 * @param ldb_ctx LDB context
1260 * @param mod_flags Flags to be set on every message element
1261 * @return ldb_message on success or NULL on failure
1263 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1265 struct ldb_context *ldb_ctx,
1266 unsigned int mod_flags)
1268 struct ldb_message *msg;
1269 unsigned int msg_pos = 0;
1270 Py_ssize_t dict_pos = 0;
1271 PyObject *key, *value;
1272 struct ldb_message_element *msg_el;
1273 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1275 msg = ldb_msg_new(mem_ctx);
1280 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1283 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1284 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1287 if (msg->dn == NULL) {
1288 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1292 PyErr_SetString(PyExc_TypeError, "no dn set");
1296 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1297 char *key_str = PyStr_AsUTF8(key);
1298 if (ldb_attr_cmp(key_str, "dn") != 0) {
1299 msg_el = PyObject_AsMessageElement(msg->elements, value,
1300 mod_flags, key_str);
1301 if (msg_el == NULL) {
1302 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1305 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1310 msg->num_elements = msg_pos;
1315 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1319 struct ldb_context *ldb_ctx;
1320 struct ldb_request *req;
1321 struct ldb_message *msg = NULL;
1322 PyObject *py_controls = Py_None;
1323 TALLOC_CTX *mem_ctx;
1324 struct ldb_control **parsed_controls;
1325 const char * const kwnames[] = { "message", "controls", NULL };
1327 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1328 discard_const_p(char *, kwnames),
1329 &py_obj, &py_controls))
1332 mem_ctx = talloc_new(NULL);
1333 if (mem_ctx == NULL) {
1337 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1339 if (py_controls == Py_None) {
1340 parsed_controls = NULL;
1342 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1343 if (controls == NULL) {
1344 talloc_free(mem_ctx);
1347 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1348 talloc_free(controls);
1351 if (PyLdbMessage_Check(py_obj)) {
1352 msg = pyldb_Message_AsMessage(py_obj);
1353 } else if (PyDict_Check(py_obj)) {
1354 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1356 PyErr_SetString(PyExc_TypeError,
1357 "Dictionary or LdbMessage object expected!");
1361 /* we should have a PyErr already set */
1362 talloc_free(mem_ctx);
1366 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1367 if (ret != LDB_SUCCESS) {
1368 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1369 talloc_free(mem_ctx);
1373 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1374 NULL, ldb_op_default_callback, NULL);
1375 if (ret != LDB_SUCCESS) {
1376 PyErr_SetString(PyExc_TypeError, "failed to build request");
1377 talloc_free(mem_ctx);
1381 /* do request and autostart a transaction */
1382 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1384 ret = ldb_transaction_start(ldb_ctx);
1385 if (ret != LDB_SUCCESS) {
1386 talloc_free(mem_ctx);
1387 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1391 ret = ldb_request(ldb_ctx, req);
1392 if (ret == LDB_SUCCESS) {
1393 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1396 if (ret == LDB_SUCCESS) {
1397 ret = ldb_transaction_commit(ldb_ctx);
1399 ldb_transaction_cancel(ldb_ctx);
1402 talloc_free(mem_ctx);
1403 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1408 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1413 struct ldb_context *ldb_ctx;
1414 struct ldb_request *req;
1415 PyObject *py_controls = Py_None;
1416 TALLOC_CTX *mem_ctx;
1417 struct ldb_control **parsed_controls;
1418 const char * const kwnames[] = { "dn", "controls", NULL };
1420 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1421 discard_const_p(char *, kwnames),
1422 &py_dn, &py_controls))
1425 mem_ctx = talloc_new(NULL);
1426 if (mem_ctx == NULL) {
1430 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1432 if (py_controls == Py_None) {
1433 parsed_controls = NULL;
1435 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1436 if (controls == NULL) {
1437 talloc_free(mem_ctx);
1440 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1441 talloc_free(controls);
1444 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1445 talloc_free(mem_ctx);
1449 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1450 NULL, ldb_op_default_callback, NULL);
1451 if (ret != LDB_SUCCESS) {
1452 PyErr_SetString(PyExc_TypeError, "failed to build request");
1453 talloc_free(mem_ctx);
1457 /* do request and autostart a transaction */
1458 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1460 ret = ldb_transaction_start(ldb_ctx);
1461 if (ret != LDB_SUCCESS) {
1462 talloc_free(mem_ctx);
1463 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1467 ret = ldb_request(ldb_ctx, req);
1468 if (ret == LDB_SUCCESS) {
1469 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1472 if (ret == LDB_SUCCESS) {
1473 ret = ldb_transaction_commit(ldb_ctx);
1475 ldb_transaction_cancel(ldb_ctx);
1478 talloc_free(mem_ctx);
1479 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1484 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1486 PyObject *py_dn1, *py_dn2;
1487 struct ldb_dn *dn1, *dn2;
1489 TALLOC_CTX *mem_ctx;
1490 PyObject *py_controls = Py_None;
1491 struct ldb_control **parsed_controls;
1492 struct ldb_context *ldb_ctx;
1493 struct ldb_request *req;
1494 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1496 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1498 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1499 discard_const_p(char *, kwnames),
1500 &py_dn1, &py_dn2, &py_controls))
1504 mem_ctx = talloc_new(NULL);
1505 if (mem_ctx == NULL) {
1510 if (py_controls == Py_None) {
1511 parsed_controls = NULL;
1513 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1514 if (controls == NULL) {
1515 talloc_free(mem_ctx);
1518 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1519 talloc_free(controls);
1523 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1524 talloc_free(mem_ctx);
1528 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1529 talloc_free(mem_ctx);
1533 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1534 NULL, ldb_op_default_callback, NULL);
1535 if (ret != LDB_SUCCESS) {
1536 PyErr_SetString(PyExc_TypeError, "failed to build request");
1537 talloc_free(mem_ctx);
1541 /* do request and autostart a transaction */
1542 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1544 ret = ldb_transaction_start(ldb_ctx);
1545 if (ret != LDB_SUCCESS) {
1546 talloc_free(mem_ctx);
1547 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1551 ret = ldb_request(ldb_ctx, req);
1552 if (ret == LDB_SUCCESS) {
1553 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1556 if (ret == LDB_SUCCESS) {
1557 ret = ldb_transaction_commit(ldb_ctx);
1559 ldb_transaction_cancel(ldb_ctx);
1562 talloc_free(mem_ctx);
1563 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1568 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1571 if (!PyArg_ParseTuple(args, "s", &name))
1574 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1579 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1581 char *attribute, *syntax;
1584 struct ldb_context *ldb_ctx;
1586 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1589 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1590 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1592 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1597 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1602 /* We don't want this attached to the 'ldb' any more */
1603 return Py_BuildValue(discard_const_p(char, "(iO)"),
1605 PyLdbMessage_FromMessage(ldif->msg));
1610 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1614 struct ldb_ldif ldif;
1617 TALLOC_CTX *mem_ctx;
1619 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1622 if (!PyLdbMessage_Check(py_msg)) {
1623 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1627 ldif.msg = pyldb_Message_AsMessage(py_msg);
1628 ldif.changetype = changetype;
1630 mem_ctx = talloc_new(NULL);
1632 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1634 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1638 ret = PyStr_FromString(string);
1640 talloc_free(mem_ctx);
1645 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1647 PyObject *list, *ret;
1648 struct ldb_ldif *ldif;
1651 TALLOC_CTX *mem_ctx;
1653 if (!PyArg_ParseTuple(args, "s", &s))
1656 mem_ctx = talloc_new(NULL);
1661 list = PyList_New(0);
1662 while (s && *s != '\0') {
1663 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1664 talloc_steal(mem_ctx, ldif);
1666 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1668 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1669 talloc_free(mem_ctx);
1673 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1674 ret = PyObject_GetIter(list);
1679 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1682 PyObject *py_msg_old;
1683 PyObject *py_msg_new;
1684 struct ldb_message *diff;
1685 struct ldb_context *ldb;
1688 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1691 if (!PyLdbMessage_Check(py_msg_old)) {
1692 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1696 if (!PyLdbMessage_Check(py_msg_new)) {
1697 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1701 ldb = pyldb_Ldb_AsLdbContext(self);
1702 ldb_ret = ldb_msg_difference(ldb, ldb,
1703 pyldb_Message_AsMessage(py_msg_old),
1704 pyldb_Message_AsMessage(py_msg_new),
1706 if (ldb_ret != LDB_SUCCESS) {
1707 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1711 py_ret = PyLdbMessage_FromMessage(diff);
1713 talloc_unlink(ldb, diff);
1718 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1720 const struct ldb_schema_attribute *a;
1721 struct ldb_val old_val;
1722 struct ldb_val new_val;
1723 TALLOC_CTX *mem_ctx;
1730 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1733 result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1734 old_val.length = size;
1737 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1741 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1747 mem_ctx = talloc_new(NULL);
1748 if (mem_ctx == NULL) {
1753 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1754 talloc_free(mem_ctx);
1758 ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1760 talloc_free(mem_ctx);
1765 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1767 PyObject *py_base = Py_None;
1768 int scope = LDB_SCOPE_DEFAULT;
1770 PyObject *py_attrs = Py_None;
1771 PyObject *py_controls = Py_None;
1772 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1774 struct ldb_result *res;
1775 struct ldb_request *req;
1777 struct ldb_context *ldb_ctx;
1778 struct ldb_control **parsed_controls;
1779 struct ldb_dn *base;
1781 TALLOC_CTX *mem_ctx;
1783 /* type "int" rather than "enum" for "scope" is intentional */
1784 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1785 discard_const_p(char *, kwnames),
1786 &py_base, &scope, &expr, &py_attrs, &py_controls))
1790 mem_ctx = talloc_new(NULL);
1791 if (mem_ctx == NULL) {
1795 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1797 if (py_attrs == Py_None) {
1800 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1801 if (attrs == NULL) {
1802 talloc_free(mem_ctx);
1807 if (py_base == Py_None) {
1808 base = ldb_get_default_basedn(ldb_ctx);
1810 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1811 talloc_free(mem_ctx);
1816 if (py_controls == Py_None) {
1817 parsed_controls = NULL;
1819 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1820 if (controls == NULL) {
1821 talloc_free(mem_ctx);
1824 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1825 talloc_free(controls);
1828 res = talloc_zero(mem_ctx, struct ldb_result);
1831 talloc_free(mem_ctx);
1835 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1842 ldb_search_default_callback,
1845 if (ret != LDB_SUCCESS) {
1846 talloc_free(mem_ctx);
1847 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1851 talloc_steal(req, attrs);
1853 ret = ldb_request(ldb_ctx, req);
1855 if (ret == LDB_SUCCESS) {
1856 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1859 if (ret != LDB_SUCCESS) {
1860 talloc_free(mem_ctx);
1861 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1865 py_ret = PyLdbResult_FromResult(res);
1867 talloc_free(mem_ctx);
1872 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1877 if (!PyArg_ParseTuple(args, "s", &name))
1880 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1885 /* FIXME: More interpretation */
1890 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1895 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1898 /* FIXME: More interpretation */
1900 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1905 static PyObject *py_ldb_modules(PyLdbObject *self)
1907 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1908 PyObject *ret = PyList_New(0);
1909 struct ldb_module *mod;
1911 for (mod = ldb->modules; mod; mod = mod->next) {
1912 PyList_Append(ret, PyLdbModule_FromModule(mod));
1918 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1920 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1924 if (!PyArg_ParseTuple(args, "i", &type))
1927 /* FIXME: More interpretation */
1929 ret = ldb_sequence_number(ldb, type, &value);
1931 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1933 return PyLong_FromLongLong(value);
1937 static const struct ldb_dn_extended_syntax test_dn_syntax = {
1939 .read_fn = ldb_handler_copy,
1940 .write_clear_fn = ldb_handler_copy,
1941 .write_hex_fn = ldb_handler_copy,
1944 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self)
1946 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1949 ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
1951 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1957 static PyMethodDef py_ldb_methods[] = {
1958 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1959 "S.set_debug(callback) -> None\n"
1960 "Set callback for LDB debug messages.\n"
1961 "The callback should accept a debug level and debug text." },
1962 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1963 "S.set_create_perms(mode) -> None\n"
1964 "Set mode to use when creating new LDB files." },
1965 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1966 "S.set_modules_dir(path) -> None\n"
1967 "Set path LDB should search for modules" },
1968 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1969 "S.transaction_start() -> None\n"
1970 "Start a new transaction." },
1971 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1972 "S.transaction_prepare_commit() -> None\n"
1973 "prepare to commit a new transaction (2-stage commit)." },
1974 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1975 "S.transaction_commit() -> None\n"
1976 "commit a new transaction." },
1977 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1978 "S.transaction_cancel() -> None\n"
1979 "cancel a new transaction." },
1980 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1982 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1984 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1986 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1988 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1990 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1991 "S.connect(url, flags=0, options=None) -> None\n"
1992 "Connect to a LDB URL." },
1993 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1994 "S.modify(message, controls=None, validate=False) -> None\n"
1995 "Modify an entry." },
1996 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1997 "S.add(message, controls=None) -> None\n"
1999 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
2000 "S.delete(dn, controls=None) -> None\n"
2001 "Remove an entry." },
2002 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
2003 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2004 "Rename an entry." },
2005 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
2006 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
2007 "Search in a database.\n"
2009 ":param base: Optional base DN to search\n"
2010 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2011 ":param expression: Optional search expression\n"
2012 ":param attrs: Attributes to return (defaults to all)\n"
2013 ":param controls: Optional list of controls\n"
2014 ":return: Iterator over Message objects\n"
2016 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2018 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2020 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2022 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2023 "S.parse_ldif(ldif) -> iter(messages)\n"
2024 "Parse a string formatted using LDIF." },
2025 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2026 "S.write_ldif(message, changetype) -> ldif\n"
2027 "Print the message as a string formatted using LDIF." },
2028 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2029 "S.msg_diff(Message) -> Message\n"
2030 "Return an LDB Message of the difference between two Message objects." },
2031 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2032 "S.get_opaque(name) -> value\n"
2033 "Get an opaque value set on this LDB connection. \n"
2034 ":note: The returned value may not be useful in Python."
2036 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2037 "S.set_opaque(name, value) -> None\n"
2038 "Set an opaque value on this LDB connection. \n"
2039 ":note: Passing incorrect values may cause crashes." },
2040 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2041 "S.modules() -> list\n"
2042 "Return the list of modules on this LDB connection " },
2043 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2044 "S.sequence_number(type) -> value\n"
2045 "Return the value of the sequence according to the requested type" },
2046 { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2047 "S._register_test_extensions() -> None\n"
2048 "Register internal extensions used in testing" },
2052 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2054 PyLdbModuleObject *ret;
2056 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2061 ret->mem_ctx = talloc_new(NULL);
2062 ret->mod = talloc_reference(ret->mem_ctx, mod);
2063 return (PyObject *)ret;
2066 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2068 struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2072 return PyLdbModule_FromModule(mod);
2075 static PyGetSetDef py_ldb_getset[] = {
2076 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
2080 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2082 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2084 struct ldb_result *result;
2088 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2092 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2094 if (ret != LDB_SUCCESS) {
2095 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2099 count = result->count;
2101 talloc_free(result);
2104 PyErr_Format(PyExc_RuntimeError,
2105 "Searching for [%s] dn gave %u results!",
2106 ldb_dn_get_linearized(dn),
2114 static PySequenceMethods py_ldb_seq = {
2115 .sq_contains = (objobjproc)py_ldb_contains,
2118 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2122 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2127 ret->mem_ctx = talloc_new(NULL);
2128 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2129 return (PyObject *)ret;
2132 static void py_ldb_dealloc(PyLdbObject *self)
2134 talloc_free(self->mem_ctx);
2135 Py_TYPE(self)->tp_free(self);
2138 static PyTypeObject PyLdb = {
2139 .tp_name = "ldb.Ldb",
2140 .tp_methods = py_ldb_methods,
2141 .tp_repr = (reprfunc)py_ldb_repr,
2142 .tp_new = py_ldb_new,
2143 .tp_init = (initproc)py_ldb_init,
2144 .tp_dealloc = (destructor)py_ldb_dealloc,
2145 .tp_getset = py_ldb_getset,
2146 .tp_getattro = PyObject_GenericGetAttr,
2147 .tp_basicsize = sizeof(PyLdbObject),
2148 .tp_doc = "Connection to a LDB database.",
2149 .tp_as_sequence = &py_ldb_seq,
2150 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2153 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2155 talloc_free(self->mem_ctx);
2156 Py_DECREF(self->msgs);
2157 Py_DECREF(self->referals);
2158 Py_DECREF(self->controls);
2159 Py_TYPE(self)->tp_free(self);
2162 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2164 Py_INCREF(self->msgs);
2168 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2170 Py_INCREF(self->controls);
2171 return self->controls;
2174 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2176 Py_INCREF(self->referals);
2177 return self->referals;
2180 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2183 if (self->msgs == NULL) {
2184 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2187 size = PyList_Size(self->msgs);
2188 return PyInt_FromLong(size);
2191 static PyGetSetDef py_ldb_result_getset[] = {
2192 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2193 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2194 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2195 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2199 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2201 return PyObject_GetIter(self->msgs);
2204 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2206 return PySequence_Size(self->msgs);
2209 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2211 return PySequence_GetItem(self->msgs, idx);
2214 static PySequenceMethods py_ldb_result_seq = {
2215 .sq_length = (lenfunc)py_ldb_result_len,
2216 .sq_item = (ssizeargfunc)py_ldb_result_find,
2219 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2221 return PyStr_FromString("<ldb result>");
2225 static PyTypeObject PyLdbResult = {
2226 .tp_name = "ldb.Result",
2227 .tp_repr = (reprfunc)py_ldb_result_repr,
2228 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2229 .tp_iter = (getiterfunc)py_ldb_result_iter,
2230 .tp_getset = py_ldb_result_getset,
2231 .tp_getattro = PyObject_GenericGetAttr,
2232 .tp_basicsize = sizeof(PyLdbResultObject),
2233 .tp_as_sequence = &py_ldb_result_seq,
2234 .tp_doc = "LDB result.",
2235 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2238 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2240 return PyStr_FromFormat("<ldb module '%s'>",
2241 pyldb_Module_AsModule(self)->ops->name);
2244 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2246 return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
2249 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2251 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2255 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2257 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2261 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2263 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2267 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2269 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2271 struct ldb_request *req;
2272 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2273 struct ldb_module *mod;
2274 const char * const*attrs;
2276 /* type "int" rather than "enum" for "scope" is intentional */
2277 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2278 discard_const_p(char *, kwnames),
2279 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2284 if (py_attrs == Py_None) {
2287 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2292 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2293 scope, NULL /* expr */, attrs,
2294 NULL /* controls */, NULL, NULL, NULL);
2296 talloc_steal(req, attrs);
2298 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2300 req->op.search.res = NULL;
2302 ret = mod->ops->search(mod, req);
2304 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2306 py_ret = PyLdbResult_FromResult(req->op.search.res);
2314 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2316 struct ldb_request *req;
2317 PyObject *py_message;
2319 struct ldb_module *mod;
2321 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2324 req = talloc_zero(NULL, struct ldb_request);
2325 req->operation = LDB_ADD;
2326 req->op.add.message = pyldb_Message_AsMessage(py_message);
2328 mod = pyldb_Module_AsModule(self);
2329 ret = mod->ops->add(mod, req);
2331 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2336 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2339 struct ldb_request *req;
2340 PyObject *py_message;
2341 struct ldb_module *mod;
2343 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2346 req = talloc_zero(NULL, struct ldb_request);
2347 req->operation = LDB_MODIFY;
2348 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2350 mod = pyldb_Module_AsModule(self);
2351 ret = mod->ops->modify(mod, req);
2353 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2358 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2361 struct ldb_request *req;
2364 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2367 req = talloc_zero(NULL, struct ldb_request);
2368 req->operation = LDB_DELETE;
2369 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2371 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2373 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2378 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2381 struct ldb_request *req;
2382 PyObject *py_dn1, *py_dn2;
2384 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2387 req = talloc_zero(NULL, struct ldb_request);
2389 req->operation = LDB_RENAME;
2390 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2391 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2393 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2395 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2400 static PyMethodDef py_ldb_module_methods[] = {
2401 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2402 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2403 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2404 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2405 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2406 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2407 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2408 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2412 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2414 talloc_free(self->mem_ctx);
2418 static PyTypeObject PyLdbModule = {
2419 .tp_name = "ldb.LdbModule",
2420 .tp_methods = py_ldb_module_methods,
2421 .tp_repr = (reprfunc)py_ldb_module_repr,
2422 .tp_str = (reprfunc)py_ldb_module_str,
2423 .tp_basicsize = sizeof(PyLdbModuleObject),
2424 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2425 .tp_flags = Py_TPFLAGS_DEFAULT,
2426 .tp_doc = "LDB module (extension)",
2431 * Create a ldb_message_element from a Python object.
2433 * This will accept any sequence objects that contains strings, or
2436 * A reference to set_obj will be borrowed.
2438 * @param mem_ctx Memory context
2439 * @param set_obj Python object to convert
2440 * @param flags ldb_message_element flags to set
2441 * @param attr_name Name of the attribute
2442 * @return New ldb_message_element, allocated as child of mem_ctx
2444 static struct ldb_message_element *PyObject_AsMessageElement(
2445 TALLOC_CTX *mem_ctx,
2448 const char *attr_name)
2450 struct ldb_message_element *me;
2451 const char *msg = NULL;
2455 if (pyldb_MessageElement_Check(set_obj)) {
2456 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2457 /* We have to talloc_reference() the memory context, not the pointer
2458 * which may not actually be it's own context */
2459 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2460 return pyldb_MessageElement_AsMessageElement(set_obj);
2465 me = talloc(mem_ctx, struct ldb_message_element);
2471 me->name = talloc_strdup(me, attr_name);
2473 if (PyBytes_Check(set_obj) || PyStr_Check(set_obj)) {
2475 me->values = talloc_array(me, struct ldb_val, me->num_values);
2476 if (PyBytes_Check(set_obj)) {
2478 result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
2485 msg = PyStr_AsUTF8AndSize(set_obj, &size);
2491 me->values[0].data = talloc_memdup(me,
2492 (const uint8_t *)msg,
2494 me->values[0].length = size;
2495 } else if (PySequence_Check(set_obj)) {
2497 me->num_values = PySequence_Size(set_obj);
2498 me->values = talloc_array(me, struct ldb_val, me->num_values);
2499 for (i = 0; i < me->num_values; i++) {
2500 PyObject *obj = PySequence_GetItem(set_obj, i);
2501 if (PyBytes_Check(obj)) {
2503 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
2509 } else if (PyStr_Check(obj)) {
2510 msg = PyStr_AsUTF8AndSize(obj, &size);
2516 PyErr_Format(PyExc_TypeError,
2517 "Expected string as element %zd in list", i);
2521 me->values[i].data = talloc_memdup(me,
2522 (const uint8_t *)msg,
2524 me->values[i].length = size;
2527 PyErr_Format(PyExc_TypeError,
2528 "String or List type expected for '%s' attribute", attr_name);
2537 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2538 struct ldb_message_element *me)
2543 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2544 result = PyList_New(me->num_values);
2546 for (i = 0; i < me->num_values; i++) {
2547 PyList_SetItem(result, i,
2548 PyObject_FromLdbValue(&me->values[i]));
2554 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2557 if (!PyArg_ParseTuple(args, "I", &i))
2559 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2562 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2565 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2567 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2568 return PyInt_FromLong(el->flags);
2571 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2574 struct ldb_message_element *el;
2575 if (!PyArg_ParseTuple(args, "I", &flags))
2578 el = pyldb_MessageElement_AsMessageElement(self);
2583 static PyMethodDef py_ldb_msg_element_methods[] = {
2584 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2585 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2586 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2590 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2592 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2595 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2597 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2598 if (idx < 0 || idx >= el->num_values) {
2599 PyErr_SetString(PyExc_IndexError, "Out of range");
2602 return PyBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2605 static PySequenceMethods py_ldb_msg_element_seq = {
2606 .sq_length = (lenfunc)py_ldb_msg_element_len,
2607 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2610 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
2613 if (!pyldb_MessageElement_Check(other)) {
2614 Py_INCREF(Py_NotImplemented);
2615 return Py_NotImplemented;
2617 ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2618 pyldb_MessageElement_AsMessageElement(other));
2619 return richcmp(ret, op);
2622 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2624 PyObject *el = ldb_msg_element_to_set(NULL,
2625 pyldb_MessageElement_AsMessageElement(self));
2626 PyObject *ret = PyObject_GetIter(el);
2631 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2633 PyLdbMessageElementObject *ret;
2634 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2639 ret->mem_ctx = talloc_new(NULL);
2640 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2645 return (PyObject *)ret;
2648 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2650 PyObject *py_elements = NULL;
2651 struct ldb_message_element *el;
2652 unsigned int flags = 0;
2654 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2655 PyLdbMessageElementObject *ret;
2656 TALLOC_CTX *mem_ctx;
2657 const char *msg = NULL;
2661 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2662 discard_const_p(char *, kwnames),
2663 &py_elements, &flags, &name))
2666 mem_ctx = talloc_new(NULL);
2667 if (mem_ctx == NULL) {
2672 el = talloc_zero(mem_ctx, struct ldb_message_element);
2675 talloc_free(mem_ctx);
2679 if (py_elements != NULL) {
2681 if (PyBytes_Check(py_elements)) {
2684 el->values = talloc_array(el, struct ldb_val, 1);
2685 if (el->values == NULL) {
2686 talloc_free(mem_ctx);
2690 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
2692 talloc_free(mem_ctx);
2696 el->values[0].data = talloc_memdup(el->values,
2697 (const uint8_t *)msg, size + 1);
2698 el->values[0].length = size;
2699 } else if (PySequence_Check(py_elements)) {
2700 el->num_values = PySequence_Size(py_elements);
2701 el->values = talloc_array(el, struct ldb_val, el->num_values);
2702 if (el->values == NULL) {
2703 talloc_free(mem_ctx);
2707 for (i = 0; i < el->num_values; i++) {
2708 PyObject *item = PySequence_GetItem(py_elements, i);
2710 talloc_free(mem_ctx);
2713 if (PyBytes_Check(item)) {
2715 result = PyBytes_AsStringAndSize(item, &_msg, &size);
2717 } else if (PyStr_Check(item)) {
2718 msg = PyStr_AsUTF8AndSize(item, &size);
2719 result = (msg == NULL) ? -1 : 0;
2721 PyErr_Format(PyExc_TypeError,
2722 "Expected string as element %zd in list", i);
2726 talloc_free(mem_ctx);
2729 el->values[i].data = talloc_memdup(el,
2730 (const uint8_t *)msg, size+1);
2731 el->values[i].length = size;
2734 PyErr_SetString(PyExc_TypeError,
2735 "Expected string or list");
2736 talloc_free(mem_ctx);
2742 el->name = talloc_strdup(el, name);
2744 ret = PyObject_New(PyLdbMessageElementObject, type);
2746 talloc_free(mem_ctx);
2750 ret->mem_ctx = mem_ctx;
2752 return (PyObject *)ret;
2755 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2757 char *element_str = NULL;
2759 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2760 PyObject *ret, *repr;
2762 for (i = 0; i < el->num_values; i++) {
2763 PyObject *o = py_ldb_msg_element_find(self, i);
2764 repr = PyObject_Repr(o);
2765 if (element_str == NULL)
2766 element_str = talloc_strdup(NULL, PyStr_AsUTF8(repr));
2768 element_str = talloc_asprintf_append(element_str, ",%s", PyStr_AsUTF8(repr));
2772 if (element_str != NULL) {
2773 ret = PyStr_FromFormat("MessageElement([%s])", element_str);
2774 talloc_free(element_str);
2776 ret = PyStr_FromString("MessageElement([])");
2782 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2784 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2786 if (el->num_values == 1)
2787 return PyStr_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2792 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2794 talloc_free(self->mem_ctx);
2798 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
2800 return wrap_text("MessageElementTextWrapper", self);
2803 static PyGetSetDef py_ldb_msg_element_getset[] = {
2804 { discard_const_p(char, "text"), (getter)py_ldb_msg_element_get_text, NULL, NULL },
2808 static PyTypeObject PyLdbMessageElement = {
2809 .tp_name = "ldb.MessageElement",
2810 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2811 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2812 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2813 .tp_str = (reprfunc)py_ldb_msg_element_str,
2814 .tp_methods = py_ldb_msg_element_methods,
2815 .tp_getset = py_ldb_msg_element_getset,
2816 .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
2817 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2818 .tp_as_sequence = &py_ldb_msg_element_seq,
2819 .tp_new = py_ldb_msg_element_new,
2820 .tp_flags = Py_TPFLAGS_DEFAULT,
2821 .tp_doc = "An element of a Message",
2825 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2830 struct ldb_message *msg;
2831 struct ldb_context *ldb_ctx;
2832 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2834 if (!PyArg_ParseTuple(args, "O!O!|I",
2835 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2840 if (!PyLdb_Check(py_ldb)) {
2841 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
2845 /* mask only flags we are going to use */
2846 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2848 PyErr_SetString(PyExc_ValueError,
2849 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2850 " expected as mod_flag value");
2854 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2856 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2861 py_ret = PyLdbMessage_FromMessage(msg);
2863 talloc_unlink(ldb_ctx, msg);
2868 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2871 if (!PyArg_ParseTuple(args, "s", &name))
2874 ldb_msg_remove_attr(self->msg, name);
2879 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2881 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2882 Py_ssize_t i, j = 0;
2883 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2884 if (msg->dn != NULL) {
2885 PyList_SetItem(obj, j, PyStr_FromString("dn"));
2888 for (i = 0; i < msg->num_elements; i++) {
2889 PyList_SetItem(obj, j, PyStr_FromString(msg->elements[i].name));
2895 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2897 struct ldb_message_element *el;
2899 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2900 name = PyStr_AsUTF8(py_name);
2902 PyErr_SetNone(PyExc_TypeError);
2905 if (!ldb_attr_cmp(name, "dn"))
2906 return pyldb_Dn_FromDn(msg->dn);
2907 el = ldb_msg_find_element(msg, name);
2911 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2914 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2916 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2918 PyErr_SetString(PyExc_KeyError, "No such element");
2924 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2926 PyObject *def = NULL;
2927 const char *kwnames[] = { "name", "default", "idx", NULL };
2928 const char *name = NULL;
2930 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2931 struct ldb_message_element *el;
2933 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2934 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2938 if (strcasecmp(name, "dn") == 0) {
2939 return pyldb_Dn_FromDn(msg->dn);
2942 el = ldb_msg_find_element(msg, name);
2944 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2953 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2956 return PyObject_FromLdbValue(&el->values[idx]);
2959 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2961 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2962 Py_ssize_t i, j = 0;
2963 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2964 if (msg->dn != NULL) {
2965 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2968 for (i = 0; i < msg->num_elements; i++, j++) {
2969 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2970 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2971 PyList_SetItem(l, j, value);
2976 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2978 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2980 PyObject *l = PyList_New(msg->num_elements);
2981 for (i = 0; i < msg->num_elements; i++) {
2982 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2987 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2989 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2990 PyLdbMessageElementObject *py_element;
2992 struct ldb_message_element *el;
2993 struct ldb_message_element *el_new;
2995 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2998 el = py_element->el;
3000 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3004 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3005 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3007 /* now deep copy all attribute values */
3008 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3009 if (el_new->values == NULL) {
3013 el_new->num_values = el->num_values;
3015 for (i = 0; i < el->num_values; i++) {
3016 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
3017 if (el_new->values[i].data == NULL
3018 && el->values[i].length != 0) {
3027 static PyMethodDef py_ldb_msg_methods[] = {
3028 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
3029 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3030 "Class method to create ldb.Message object from Dictionary.\n"
3031 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3032 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
3033 "S.keys() -> list\n\n"
3034 "Return sequence of all attribute names." },
3035 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
3036 "S.remove(name)\n\n"
3037 "Remove all entries for attributes with the specified name."},
3038 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
3039 "msg.get(name,default=None,idx=None) -> string\n"
3040 "idx is the index into the values array\n"
3041 "if idx is None, then a list is returned\n"
3042 "if idx is not None, then the element with that index is returned\n"
3043 "if you pass the special name 'dn' then the DN object is returned\n"},
3044 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
3045 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
3046 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
3047 "S.add(element)\n\n"
3048 "Add an element to this message." },
3052 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
3054 PyObject *list, *iter;
3056 list = py_ldb_msg_keys(self);
3057 iter = PyObject_GetIter(list);
3062 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
3066 attr_name = PyStr_AsUTF8(name);
3067 if (attr_name == NULL) {
3068 PyErr_SetNone(PyExc_TypeError);
3072 if (value == NULL) {
3074 ldb_msg_remove_attr(self->msg, attr_name);
3077 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
3078 value, 0, attr_name);
3082 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
3083 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
3084 if (ret != LDB_SUCCESS) {
3085 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
3092 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
3094 return pyldb_Message_AsMessage(self)->num_elements;
3097 static PyMappingMethods py_ldb_msg_mapping = {
3098 .mp_length = (lenfunc)py_ldb_msg_length,
3099 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
3100 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
3103 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3105 const char * const kwnames[] = { "dn", NULL };
3106 struct ldb_message *ret;
3107 TALLOC_CTX *mem_ctx;
3108 PyObject *pydn = NULL;
3109 PyLdbMessageObject *py_ret;
3111 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
3112 discard_const_p(char *, kwnames),
3116 mem_ctx = talloc_new(NULL);
3117 if (mem_ctx == NULL) {
3122 ret = ldb_msg_new(mem_ctx);
3124 talloc_free(mem_ctx);
3131 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
3132 talloc_free(mem_ctx);
3135 ret->dn = talloc_reference(ret, dn);
3138 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
3139 if (py_ret == NULL) {
3141 talloc_free(mem_ctx);
3145 py_ret->mem_ctx = mem_ctx;
3147 return (PyObject *)py_ret;
3150 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
3152 PyLdbMessageObject *ret;
3154 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3159 ret->mem_ctx = talloc_new(NULL);
3160 ret->msg = talloc_reference(ret->mem_ctx, msg);
3161 return (PyObject *)ret;
3164 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3166 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3167 return pyldb_Dn_FromDn(msg->dn);
3170 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3172 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3173 if (!pyldb_Dn_Check(value)) {
3174 PyErr_SetString(PyExc_TypeError, "expected dn");
3178 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3182 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
3184 return wrap_text("MessageTextWrapper", self);
3187 static PyGetSetDef py_ldb_msg_getset[] = {
3188 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
3189 { discard_const_p(char, "text"), (getter)py_ldb_msg_get_text, NULL, NULL },
3193 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3195 PyObject *dict = PyDict_New(), *ret, *repr;
3196 if (PyDict_Update(dict, (PyObject *)self) != 0)
3198 repr = PyObject_Repr(dict);
3203 ret = PyStr_FromFormat("Message(%s)", PyStr_AsUTF8(repr));
3209 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3211 talloc_free(self->mem_ctx);
3215 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3216 PyLdbMessageObject *py_msg2, int op)
3218 struct ldb_message *msg1, *msg2;
3222 if (!PyLdbMessage_Check(py_msg2)) {
3223 Py_INCREF(Py_NotImplemented);
3224 return Py_NotImplemented;
3227 msg1 = pyldb_Message_AsMessage(py_msg1),
3228 msg2 = pyldb_Message_AsMessage(py_msg2);
3230 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3231 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3233 return richcmp(ret, op);
3237 ret = msg1->num_elements - msg2->num_elements;
3239 return richcmp(ret, op);
3242 for (i = 0; i < msg1->num_elements; i++) {
3243 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3244 &msg2->elements[i]);
3246 return richcmp(ret, op);
3249 ret = ldb_msg_element_compare(&msg1->elements[i],
3250 &msg2->elements[i]);
3252 return richcmp(ret, op);
3256 return richcmp(0, op);
3259 static PyTypeObject PyLdbMessage = {
3260 .tp_name = "ldb.Message",
3261 .tp_methods = py_ldb_msg_methods,
3262 .tp_getset = py_ldb_msg_getset,
3263 .tp_as_mapping = &py_ldb_msg_mapping,
3264 .tp_basicsize = sizeof(PyLdbMessageObject),
3265 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3266 .tp_new = py_ldb_msg_new,
3267 .tp_repr = (reprfunc)py_ldb_msg_repr,
3268 .tp_flags = Py_TPFLAGS_DEFAULT,
3269 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3270 .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3271 .tp_doc = "A LDB Message",
3274 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3276 PyLdbTreeObject *ret;
3278 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3284 ret->mem_ctx = talloc_new(NULL);
3285 ret->tree = talloc_reference(ret->mem_ctx, tree);
3286 return (PyObject *)ret;
3289 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3291 talloc_free(self->mem_ctx);
3295 static PyTypeObject PyLdbTree = {
3296 .tp_name = "ldb.Tree",
3297 .tp_basicsize = sizeof(PyLdbTreeObject),
3298 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3299 .tp_flags = Py_TPFLAGS_DEFAULT,
3300 .tp_doc = "A search tree",
3304 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3306 PyObject *py_ldb = (PyObject *)mod->private_data;
3307 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3309 py_base = pyldb_Dn_FromDn(req->op.search.base);
3311 if (py_base == NULL)
3312 return LDB_ERR_OPERATIONS_ERROR;
3314 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3316 if (py_tree == NULL)
3317 return LDB_ERR_OPERATIONS_ERROR;
3319 if (req->op.search.attrs == NULL) {
3323 for (len = 0; req->op.search.attrs[len]; len++);
3324 py_attrs = PyList_New(len);
3325 for (i = 0; i < len; i++)
3326 PyList_SetItem(py_attrs, i, PyStr_FromString(req->op.search.attrs[i]));
3329 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3330 discard_const_p(char, "OiOO"),
3331 py_base, req->op.search.scope, py_tree, py_attrs);
3333 Py_DECREF(py_attrs);
3337 if (py_result == NULL) {
3338 return LDB_ERR_PYTHON_EXCEPTION;
3341 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3342 if (req->op.search.res == NULL) {
3343 return LDB_ERR_PYTHON_EXCEPTION;
3346 Py_DECREF(py_result);
3351 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3353 PyObject *py_ldb = (PyObject *)mod->private_data;
3354 PyObject *py_result, *py_msg;
3356 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3358 if (py_msg == NULL) {
3359 return LDB_ERR_OPERATIONS_ERROR;
3362 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3363 discard_const_p(char, "O"),
3368 if (py_result == NULL) {
3369 return LDB_ERR_PYTHON_EXCEPTION;
3372 Py_DECREF(py_result);
3377 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3379 PyObject *py_ldb = (PyObject *)mod->private_data;
3380 PyObject *py_result, *py_msg;
3382 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3384 if (py_msg == NULL) {
3385 return LDB_ERR_OPERATIONS_ERROR;
3388 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3389 discard_const_p(char, "O"),
3394 if (py_result == NULL) {
3395 return LDB_ERR_PYTHON_EXCEPTION;
3398 Py_DECREF(py_result);
3403 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3405 PyObject *py_ldb = (PyObject *)mod->private_data;
3406 PyObject *py_result, *py_dn;
3408 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3411 return LDB_ERR_OPERATIONS_ERROR;
3413 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3414 discard_const_p(char, "O"),
3417 if (py_result == NULL) {
3418 return LDB_ERR_PYTHON_EXCEPTION;
3421 Py_DECREF(py_result);
3426 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3428 PyObject *py_ldb = (PyObject *)mod->private_data;
3429 PyObject *py_result, *py_olddn, *py_newdn;
3431 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3433 if (py_olddn == NULL)
3434 return LDB_ERR_OPERATIONS_ERROR;
3436 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3438 if (py_newdn == NULL)
3439 return LDB_ERR_OPERATIONS_ERROR;
3441 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3442 discard_const_p(char, "OO"),
3443 py_olddn, py_newdn);
3445 Py_DECREF(py_olddn);
3446 Py_DECREF(py_newdn);
3448 if (py_result == NULL) {
3449 return LDB_ERR_PYTHON_EXCEPTION;
3452 Py_DECREF(py_result);
3457 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3459 PyObject *py_ldb = (PyObject *)mod->private_data;
3460 PyObject *py_result;
3462 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3463 discard_const_p(char, ""));
3465 Py_XDECREF(py_result);
3467 return LDB_ERR_OPERATIONS_ERROR;
3470 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3472 PyObject *py_ldb = (PyObject *)mod->private_data;
3473 PyObject *py_result;
3475 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3476 discard_const_p(char, ""));
3478 Py_XDECREF(py_result);
3480 return LDB_ERR_OPERATIONS_ERROR;
3483 static int py_module_start_transaction(struct ldb_module *mod)
3485 PyObject *py_ldb = (PyObject *)mod->private_data;
3486 PyObject *py_result;
3488 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3489 discard_const_p(char, ""));
3491 if (py_result == NULL) {
3492 return LDB_ERR_PYTHON_EXCEPTION;
3495 Py_DECREF(py_result);
3500 static int py_module_end_transaction(struct ldb_module *mod)
3502 PyObject *py_ldb = (PyObject *)mod->private_data;
3503 PyObject *py_result;
3505 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3506 discard_const_p(char, ""));
3508 if (py_result == NULL) {
3509 return LDB_ERR_PYTHON_EXCEPTION;
3512 Py_DECREF(py_result);
3517 static int py_module_del_transaction(struct ldb_module *mod)
3519 PyObject *py_ldb = (PyObject *)mod->private_data;
3520 PyObject *py_result;
3522 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3523 discard_const_p(char, ""));
3525 if (py_result == NULL) {
3526 return LDB_ERR_PYTHON_EXCEPTION;
3529 Py_DECREF(py_result);
3534 static int py_module_destructor(struct ldb_module *mod)
3536 Py_DECREF((PyObject *)mod->private_data);
3540 static int py_module_init(struct ldb_module *mod)
3542 PyObject *py_class = (PyObject *)mod->ops->private_data;
3543 PyObject *py_result, *py_next, *py_ldb;
3545 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3548 return LDB_ERR_OPERATIONS_ERROR;
3550 py_next = PyLdbModule_FromModule(mod->next);
3552 if (py_next == NULL)
3553 return LDB_ERR_OPERATIONS_ERROR;
3555 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3558 if (py_result == NULL) {
3559 return LDB_ERR_PYTHON_EXCEPTION;
3562 mod->private_data = py_result;
3564 talloc_set_destructor(mod, py_module_destructor);
3566 return ldb_next_init(mod);
3569 static PyObject *py_register_module(PyObject *module, PyObject *args)
3572 struct ldb_module_ops *ops;
3575 if (!PyArg_ParseTuple(args, "O", &input))
3578 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3584 ops->name = talloc_strdup(ops, PyStr_AsUTF8(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3587 ops->private_data = input;
3588 ops->init_context = py_module_init;
3589 ops->search = py_module_search;
3590 ops->add = py_module_add;
3591 ops->modify = py_module_modify;
3592 ops->del = py_module_del;
3593 ops->rename = py_module_rename;
3594 ops->request = py_module_request;
3595 ops->extended = py_module_extended;
3596 ops->start_transaction = py_module_start_transaction;
3597 ops->end_transaction = py_module_end_transaction;
3598 ops->del_transaction = py_module_del_transaction;
3600 ret = ldb_register_module(ops);
3602 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3607 static PyObject *py_timestring(PyObject *module, PyObject *args)
3609 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3610 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3614 if (!PyArg_ParseTuple(args, "l", &t_val))
3616 tresult = ldb_timestring(NULL, (time_t) t_val);
3617 ret = PyStr_FromString(tresult);
3618 talloc_free(tresult);
3622 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3625 if (!PyArg_ParseTuple(args, "s", &str))
3628 return PyInt_FromLong(ldb_string_to_time(str));
3631 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3634 if (!PyArg_ParseTuple(args, "s", &name))
3636 return PyBool_FromLong(ldb_valid_attr_name(name));
3640 encode a string using RFC2254 rules
3642 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3644 char *str, *encoded;
3645 Py_ssize_t size = 0;
3649 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3651 val.data = (uint8_t *)str;
3654 encoded = ldb_binary_encode(NULL, val);
3655 if (encoded == NULL) {
3656 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3659 ret = PyStr_FromString(encoded);
3660 talloc_free(encoded);
3665 decode a string using RFC2254 rules
3667 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3673 if (!PyArg_ParseTuple(args, "s", &str))
3676 val = ldb_binary_decode(NULL, str);
3677 if (val.data == NULL) {
3678 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3681 ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
3682 talloc_free(val.data);
3686 static PyMethodDef py_ldb_global_methods[] = {
3687 { "register_module", py_register_module, METH_VARARGS,
3688 "S.register_module(module) -> None\n\n"
3689 "Register a LDB module."},
3690 { "timestring", py_timestring, METH_VARARGS,
3691 "S.timestring(int) -> string\n\n"
3692 "Generate a LDAP time string from a UNIX timestamp" },
3693 { "string_to_time", py_string_to_time, METH_VARARGS,
3694 "S.string_to_time(string) -> int\n\n"
3695 "Parse a LDAP time string into a UNIX timestamp." },
3696 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3697 "S.valid_attr_name(name) -> bool\n\nn"
3698 "Check whether the supplied name is a valid attribute name." },
3699 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3700 "S.open() -> Ldb\n\n"
3701 "Open a new LDB context." },
3702 { "binary_encode", py_binary_encode, METH_VARARGS,
3703 "S.binary_encode(string) -> string\n\n"
3704 "Perform a RFC2254 binary encoding on a string" },
3705 { "binary_decode", py_binary_decode, METH_VARARGS,
3706 "S.binary_decode(string) -> string\n\n"
3707 "Perform a RFC2254 binary decode on a string" },
3711 #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."
3713 #if PY_MAJOR_VERSION >= 3
3714 static struct PyModuleDef moduledef = {
3715 PyModuleDef_HEAD_INIT,
3717 .m_doc = MODULE_DOC,
3719 .m_methods = py_ldb_global_methods,
3723 static PyObject* module_init(void)
3727 if (PyType_Ready(&PyLdbDn) < 0)
3730 if (PyType_Ready(&PyLdbMessage) < 0)
3733 if (PyType_Ready(&PyLdbMessageElement) < 0)
3736 if (PyType_Ready(&PyLdb) < 0)
3739 if (PyType_Ready(&PyLdbModule) < 0)
3742 if (PyType_Ready(&PyLdbTree) < 0)
3745 if (PyType_Ready(&PyLdbResult) < 0)
3748 if (PyType_Ready(&PyLdbControl) < 0)
3751 #if PY_MAJOR_VERSION >= 3
3752 m = PyModule_Create(&moduledef);
3754 m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC);
3759 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
3761 ADD_LDB_INT(SEQ_HIGHEST_SEQ);
3762 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
3763 ADD_LDB_INT(SEQ_NEXT);
3764 ADD_LDB_INT(SCOPE_DEFAULT);
3765 ADD_LDB_INT(SCOPE_BASE);
3766 ADD_LDB_INT(SCOPE_ONELEVEL);
3767 ADD_LDB_INT(SCOPE_SUBTREE);
3769 ADD_LDB_INT(CHANGETYPE_NONE);
3770 ADD_LDB_INT(CHANGETYPE_ADD);
3771 ADD_LDB_INT(CHANGETYPE_DELETE);
3772 ADD_LDB_INT(CHANGETYPE_MODIFY);
3774 ADD_LDB_INT(FLAG_MOD_ADD);
3775 ADD_LDB_INT(FLAG_MOD_REPLACE);
3776 ADD_LDB_INT(FLAG_MOD_DELETE);
3778 ADD_LDB_INT(SUCCESS);
3779 ADD_LDB_INT(ERR_OPERATIONS_ERROR);
3780 ADD_LDB_INT(ERR_PROTOCOL_ERROR);
3781 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
3782 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
3783 ADD_LDB_INT(ERR_COMPARE_FALSE);
3784 ADD_LDB_INT(ERR_COMPARE_TRUE);
3785 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
3786 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
3787 ADD_LDB_INT(ERR_REFERRAL);
3788 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
3789 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
3790 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
3791 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
3792 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
3793 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
3794 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
3795 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
3796 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
3797 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
3798 ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
3799 ADD_LDB_INT(ERR_ALIAS_PROBLEM);
3800 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
3801 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
3802 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
3803 ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
3804 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
3805 ADD_LDB_INT(ERR_BUSY);
3806 ADD_LDB_INT(ERR_UNAVAILABLE);
3807 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
3808 ADD_LDB_INT(ERR_LOOP_DETECT);
3809 ADD_LDB_INT(ERR_NAMING_VIOLATION);
3810 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
3811 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
3812 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
3813 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
3814 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
3815 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
3816 ADD_LDB_INT(ERR_OTHER);
3818 ADD_LDB_INT(FLG_RDONLY);
3819 ADD_LDB_INT(FLG_NOSYNC);
3820 ADD_LDB_INT(FLG_RECONNECT);
3821 ADD_LDB_INT(FLG_NOMMAP);
3823 /* Historical misspelling */
3824 PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
3826 PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
3828 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3829 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3832 Py_INCREF(&PyLdbDn);
3833 Py_INCREF(&PyLdbModule);
3834 Py_INCREF(&PyLdbMessage);
3835 Py_INCREF(&PyLdbMessageElement);
3836 Py_INCREF(&PyLdbTree);
3837 Py_INCREF(&PyLdbResult);
3838 Py_INCREF(&PyLdbControl);
3840 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3841 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3842 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3843 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3844 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3845 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3846 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3848 PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
3850 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
3852 ADD_LDB_STRING(SYNTAX_DN);
3853 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3854 ADD_LDB_STRING(SYNTAX_INTEGER);
3855 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3856 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3857 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3858 ADD_LDB_STRING(OID_COMPARATOR_AND);
3859 ADD_LDB_STRING(OID_COMPARATOR_OR);
3864 #if PY_MAJOR_VERSION >= 3
3865 PyMODINIT_FUNC PyInit_ldb(void);
3866 PyMODINIT_FUNC PyInit_ldb(void)
3868 return module_init();