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"
36 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
37 static PyObject *PyExc_LdbError;
39 static PyTypeObject PyLdbControl;
40 static PyTypeObject PyLdbResult;
41 static PyTypeObject PyLdbMessage;
42 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
43 static PyTypeObject PyLdbModule;
44 static PyTypeObject PyLdbDn;
45 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
46 static PyTypeObject PyLdb;
47 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
48 static PyTypeObject PyLdbMessageElement;
49 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
51 static PyTypeObject PyLdbTree;
52 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
53 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
54 static struct ldb_message_element *PyObject_AsMessageElement(
58 const char *attr_name);
60 /* There's no Py_ssize_t in 2.4, apparently */
61 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
62 typedef int Py_ssize_t;
63 typedef inquiry lenfunc;
64 typedef intargfunc ssizeargfunc;
67 #define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
71 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
73 if (self->data != NULL) {
74 char* control = ldb_control_to_string(self->mem_ctx, self->data);
75 if (control == NULL) {
79 return PyString_FromString(control);
81 return PyString_FromFormat("ldb control");
85 static void py_ldb_control_dealloc(PyLdbControlObject *self)
87 if (self->mem_ctx != NULL) {
88 talloc_free(self->mem_ctx);
91 Py_TYPE(self)->tp_free(self);
94 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
96 return PyString_FromString(self->data->oid);
99 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
101 return PyBool_FromLong(self->data->critical);
104 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
106 if (PyObject_IsTrue(value)) {
107 self->data->critical = true;
109 self->data->critical = false;
114 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
117 const char * const kwnames[] = { "ldb", "data", NULL };
118 struct ldb_control *parsed_controls;
119 PyLdbControlObject *ret;
122 struct ldb_context *ldb_ctx;
124 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
125 discard_const_p(char *, kwnames),
126 &PyLdb, &py_ldb, &data))
129 mem_ctx = talloc_new(NULL);
130 if (mem_ctx == NULL) {
135 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
136 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
138 if (!parsed_controls) {
139 talloc_free(mem_ctx);
140 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
144 ret = PyObject_New(PyLdbControlObject, type);
147 talloc_free(mem_ctx);
151 ret->mem_ctx = mem_ctx;
153 ret->data = talloc_move(mem_ctx, &parsed_controls);
154 if (ret->data == NULL) {
157 talloc_free(mem_ctx);
161 return (PyObject *)ret;
164 static PyGetSetDef py_ldb_control_getset[] = {
165 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
166 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
170 static PyTypeObject PyLdbControl = {
171 .tp_name = "ldb.control",
172 .tp_dealloc = (destructor)py_ldb_control_dealloc,
173 .tp_getattro = PyObject_GenericGetAttr,
174 .tp_basicsize = sizeof(PyLdbControlObject),
175 .tp_getset = py_ldb_control_getset,
176 .tp_doc = "LDB control.",
177 .tp_str = (reprfunc)py_ldb_control_str,
178 .tp_new = py_ldb_control_new,
179 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
182 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
184 if (ret == LDB_ERR_PYTHON_EXCEPTION)
185 return; /* Python exception should already be set, just keep that */
187 PyErr_SetObject(error,
188 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
189 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
192 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
194 return PyString_FromStringAndSize((const char *)val->data, val->length);
198 * Create a Python object from a ldb_result.
200 * @param result LDB result to convert
201 * @return Python object with converted result (a list object)
203 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
205 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
206 PyLdbControlObject *ctrl;
207 if (ctl_ctx == NULL) {
212 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
214 talloc_free(ctl_ctx);
218 ctrl->mem_ctx = ctl_ctx;
219 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
220 if (ctrl->data == NULL) {
225 return (PyObject*) ctrl;
229 * Create a Python object from a ldb_result.
231 * @param result LDB result to convert
232 * @return Python object with converted result (a list object)
234 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
236 PyLdbResultObject *ret;
237 PyObject *list, *controls, *referals;
240 if (result == NULL) {
244 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
250 list = PyList_New(result->count);
257 for (i = 0; i < result->count; i++) {
258 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
261 ret->mem_ctx = talloc_new(NULL);
262 if (ret->mem_ctx == NULL) {
271 if (result->controls) {
273 while (result->controls[i]) {
276 controls = PyList_New(i);
277 if (controls == NULL) {
282 for (i=0; result->controls[i]; i++) {
283 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
290 PyList_SetItem(controls, i, ctrl);
294 * No controls so we keep an empty list
296 controls = PyList_New(0);
297 if (controls == NULL) {
304 ret->controls = controls;
308 while (result->refs && result->refs[i]) {
312 referals = PyList_New(i);
313 if (referals == NULL) {
319 for (i = 0;result->refs && result->refs[i]; i++) {
320 PyList_SetItem(referals, i, PyString_FromString(result->refs[i]));
322 ret->referals = referals;
323 return (PyObject *)ret;
327 * Create a LDB Result from a Python object.
328 * If conversion fails, NULL will be returned and a Python exception set.
330 * Note: the result object only includes the messages at the moment; extended
331 * result, controls and referrals are ignored.
333 * @param mem_ctx Memory context in which to allocate the LDB Result
334 * @param obj Python object to convert
335 * @return a ldb_result, or NULL if the conversion failed
337 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
340 struct ldb_result *res;
346 res = talloc_zero(mem_ctx, struct ldb_result);
347 res->count = PyList_Size(obj);
348 res->msgs = talloc_array(res, struct ldb_message *, res->count);
349 for (i = 0; i < res->count; i++) {
350 PyObject *item = PyList_GetItem(obj, i);
351 res->msgs[i] = pyldb_Message_AsMessage(item);
356 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
358 return PyBool_FromLong(ldb_dn_validate(self->dn));
361 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
363 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
366 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
368 return PyBool_FromLong(ldb_dn_is_special(self->dn));
371 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
373 return PyBool_FromLong(ldb_dn_is_null(self->dn));
376 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
378 return PyString_FromString(ldb_dn_get_casefold(self->dn));
381 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
383 return PyString_FromString(ldb_dn_get_linearized(self->dn));
386 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
388 return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
391 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
393 return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
396 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
398 const char * const kwnames[] = { "mode", NULL };
400 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
401 discard_const_p(char *, kwnames),
404 return PyString_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
407 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
410 const struct ldb_val *val;
412 if (!PyArg_ParseTuple(args, "s", &name))
414 val = ldb_dn_get_extended_component(self->dn, name);
419 return PyString_FromStringAndSize((const char *)val->data, val->length);
422 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
428 if (!PyArg_ParseTuple(args, "sO", &name, &value))
431 if (value == Py_None) {
432 err = ldb_dn_set_extended_component(self->dn, name, NULL);
435 if (!PyString_Check(value)) {
436 PyErr_SetString(PyExc_TypeError, "Expected a string argument");
439 val.data = (uint8_t *)PyString_AsString(value);
440 val.length = PyString_Size(value);
441 err = ldb_dn_set_extended_component(self->dn, name, &val);
444 if (err != LDB_SUCCESS) {
445 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
452 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
454 return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
457 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
461 if (!PyArg_ParseTuple(args, "s", &name))
464 return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
467 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
470 ret = ldb_dn_compare(dn1->dn, dn2->dn);
471 if (ret < 0) ret = -1;
472 if (ret > 0) ret = 1;
476 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
478 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
479 struct ldb_dn *parent;
480 PyLdbDnObject *py_ret;
481 TALLOC_CTX *mem_ctx = talloc_new(NULL);
483 parent = ldb_dn_get_parent(mem_ctx, dn);
484 if (parent == NULL) {
485 talloc_free(mem_ctx);
489 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
490 if (py_ret == NULL) {
492 talloc_free(mem_ctx);
495 py_ret->mem_ctx = mem_ctx;
497 return (PyObject *)py_ret;
500 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
502 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
505 struct ldb_dn *dn, *other;
506 if (!PyArg_ParseTuple(args, "O", &py_other))
509 dn = pyldb_Dn_AsDn((PyObject *)self);
511 if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
514 return PyBool_FromLong(ldb_dn_add_child(dn, other));
517 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
520 struct ldb_dn *other, *dn;
521 if (!PyArg_ParseTuple(args, "O", &py_other))
524 dn = pyldb_Dn_AsDn((PyObject *)self);
526 if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
529 return PyBool_FromLong(ldb_dn_add_base(dn, other));
532 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
536 if (!PyArg_ParseTuple(args, "i", &i))
539 dn = pyldb_Dn_AsDn((PyObject *)self);
541 return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
544 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
547 struct ldb_dn *dn, *base;
548 if (!PyArg_ParseTuple(args, "O", &py_base))
551 dn = pyldb_Dn_AsDn((PyObject *)self);
553 if (!pyldb_Object_AsDn(NULL, py_base, dn_ldb_ctx(dn), &base))
556 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
559 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
563 unsigned int num = 0;
565 if (!PyArg_ParseTuple(args, "I", &num))
568 dn = pyldb_Dn_AsDn((PyObject *)self);
570 name = ldb_dn_get_component_name(dn, num);
575 return PyString_FromString(name);
578 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
581 const struct ldb_val *val;
582 unsigned int num = 0;
584 if (!PyArg_ParseTuple(args, "I", &num))
587 dn = pyldb_Dn_AsDn((PyObject *)self);
589 val = ldb_dn_get_component_val(dn, num);
594 return PyObject_FromLdbValue(val);
597 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
599 unsigned int num = 0;
601 PyObject *value = Py_None;
602 struct ldb_val val = { NULL, };
605 if (!PyArg_ParseTuple(args, "IsO", &num, &name, &value))
608 if (value != Py_None) {
609 if (!PyString_Check(value)) {
610 PyErr_SetString(PyExc_TypeError, "Expected a string argument");
613 val.data = (uint8_t *)PyString_AsString(value);
614 val.length = PyString_Size(value);
617 err = ldb_dn_set_component(self->dn, num, name, val);
618 if (err != LDB_SUCCESS) {
619 PyErr_SetString(PyExc_TypeError, "Failed to set component");
626 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
631 dn = pyldb_Dn_AsDn((PyObject *)self);
633 name = ldb_dn_get_rdn_name(dn);
638 return PyString_FromString(name);
641 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
644 const struct ldb_val *val;
646 dn = pyldb_Dn_AsDn((PyObject *)self);
648 val = ldb_dn_get_rdn_val(dn);
653 return PyObject_FromLdbValue(val);
656 static PyMethodDef py_ldb_dn_methods[] = {
657 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
658 "S.validate() -> bool\n"
659 "Validate DN is correct." },
660 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
661 "S.is_valid() -> bool\n" },
662 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
663 "S.is_special() -> bool\n"
664 "Check whether this is a special LDB DN." },
665 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
666 "Check whether this is a null DN." },
667 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
669 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
671 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
672 "S.canonical_str() -> string\n"
673 "Canonical version of this DN (like a posix path)." },
674 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
675 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
676 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
677 "S.canonical_ex_str() -> string\n"
678 "Canonical version of this DN (like a posix path, with terminating newline)." },
679 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
680 "S.extended_str(mode=1) -> string\n"
681 "Extended version of this DN" },
682 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
684 "Get the parent for this DN." },
685 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
686 "S.add_child(dn) -> None\n"
687 "Add a child DN to this DN." },
688 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
689 "S.add_base(dn) -> None\n"
690 "Add a base DN to this DN." },
691 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
692 "S.remove_base_components(int) -> bool\n"
693 "Remove a number of DN components from the base of this DN." },
694 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
695 "S.check_special(name) -> bool\n\n"
696 "Check if name is a special DN name"},
697 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
698 "S.get_extended_component(name) -> string\n\n"
699 "returns a DN extended component as a binary string"},
700 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
701 "S.set_extended_component(name, value) -> None\n\n"
702 "set a DN extended component as a binary string"},
703 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
704 "S.get_component_name(num) -> string\n"
705 "get the attribute name of the specified component" },
706 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
707 "S.get_component_value(num) -> string\n"
708 "get the attribute value of the specified component as a binary string" },
709 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
710 "S.get_component_value(num, name, value) -> None\n"
711 "set the attribute name and value of the specified component" },
712 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
713 "S.get_rdn_name() -> string\n"
714 "get the RDN attribute name" },
715 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
716 "S.get_rdn_value() -> string\n"
717 "get the RDN attribute value as a binary string" },
721 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
723 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
727 copy a DN as a python object
729 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
731 PyLdbDnObject *py_ret;
733 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
734 if (py_ret == NULL) {
738 py_ret->mem_ctx = talloc_new(NULL);
739 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
740 return (PyObject *)py_ret;
743 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
745 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
747 PyLdbDnObject *py_ret;
749 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
752 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
753 if (py_ret == NULL) {
757 py_ret->mem_ctx = talloc_new(NULL);
758 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
759 ldb_dn_add_base(py_ret->dn, other);
760 return (PyObject *)py_ret;
763 static PySequenceMethods py_ldb_dn_seq = {
764 .sq_length = (lenfunc)py_ldb_dn_len,
765 .sq_concat = (binaryfunc)py_ldb_dn_concat,
768 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
773 struct ldb_context *ldb_ctx;
775 PyLdbDnObject *py_ret;
776 const char * const kwnames[] = { "ldb", "dn", NULL };
778 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
779 discard_const_p(char *, kwnames),
783 if (!PyLdb_Check(py_ldb)) {
784 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
788 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
790 mem_ctx = talloc_new(NULL);
791 if (mem_ctx == NULL) {
796 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
797 if (!ldb_dn_validate(ret)) {
798 talloc_free(mem_ctx);
799 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
803 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
805 talloc_free(mem_ctx);
809 py_ret->mem_ctx = mem_ctx;
811 return (PyObject *)py_ret;
814 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
816 talloc_free(self->mem_ctx);
820 static PyTypeObject PyLdbDn = {
822 .tp_methods = py_ldb_dn_methods,
823 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
824 .tp_repr = (reprfunc)py_ldb_dn_repr,
825 .tp_compare = (cmpfunc)py_ldb_dn_compare,
826 .tp_as_sequence = &py_ldb_dn_seq,
827 .tp_doc = "A LDB distinguished name.",
828 .tp_new = py_ldb_dn_new,
829 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
830 .tp_basicsize = sizeof(PyLdbDnObject),
831 .tp_flags = Py_TPFLAGS_DEFAULT,
835 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
836 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
838 PyObject *fn = (PyObject *)context;
839 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
842 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
845 struct ldb_context *ldb_ctx;
847 if (!PyArg_ParseTuple(args, "O", &cb))
851 /* FIXME: Where do we DECREF cb ? */
852 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
853 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
854 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
860 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
863 if (!PyArg_ParseTuple(args, "I", &perms))
866 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
871 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
874 if (!PyArg_ParseTuple(args, "s", &modules_dir))
877 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
882 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
884 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
886 ldb_err = ldb_transaction_start(ldb_ctx);
887 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
891 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
893 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
895 ldb_err = ldb_transaction_commit(ldb_ctx);
896 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
900 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
902 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
904 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
905 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
909 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
911 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
913 ldb_err = ldb_transaction_cancel(ldb_ctx);
914 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
918 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
920 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
922 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
923 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
927 static PyObject *py_ldb_repr(PyLdbObject *self)
929 return PyString_FromFormat("<ldb connection>");
932 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
934 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
937 return py_ldb_dn_copy(dn);
941 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
943 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
946 return py_ldb_dn_copy(dn);
949 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
951 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
954 return py_ldb_dn_copy(dn);
957 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
959 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
962 return py_ldb_dn_copy(dn);
965 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
966 const char *paramname)
970 if (!PyList_Check(list)) {
971 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
974 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
980 for (i = 0; i < PyList_Size(list); i++) {
981 PyObject *item = PyList_GetItem(list, i);
982 if (!PyString_Check(item)) {
983 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
986 ret[i] = talloc_strndup(ret, PyString_AsString(item),
987 PyString_Size(item));
993 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
995 const char * const kwnames[] = { "url", "flags", "options", NULL };
997 PyObject *py_options = Py_None;
998 const char **options;
999 unsigned int flags = 0;
1001 struct ldb_context *ldb;
1003 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1004 discard_const_p(char *, kwnames),
1005 &url, &flags, &py_options))
1008 ldb = pyldb_Ldb_AsLdbContext(self);
1010 if (py_options == Py_None) {
1013 options = PyList_AsStringList(ldb, py_options, "options");
1014 if (options == NULL)
1019 ret = ldb_connect(ldb, url, flags, options);
1020 if (ret != LDB_SUCCESS) {
1021 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1026 talloc_free(options);
1030 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1033 struct ldb_context *ldb;
1034 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1039 ret->mem_ctx = talloc_new(NULL);
1040 ldb = ldb_init(ret->mem_ctx, NULL);
1048 return (PyObject *)ret;
1051 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1054 unsigned int flags = 0;
1055 PyObject *py_options = Py_None;
1057 const char **options;
1058 const char * const kwnames[] = { "url", "flags", "options", NULL };
1059 struct ldb_context *ldb_ctx;
1061 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
1062 discard_const_p(char *, kwnames),
1063 &url, &flags, &py_options))
1066 if (py_options == Py_None) {
1069 options = PyList_AsStringList(NULL, py_options, "options");
1070 if (options == NULL)
1074 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1075 ret = ldb_connect(ldb_ctx, url, flags, options);
1076 talloc_free(options);
1078 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1083 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1086 PyObject *py_controls = Py_None;
1087 struct ldb_context *ldb_ctx;
1088 struct ldb_request *req;
1089 struct ldb_control **parsed_controls;
1090 struct ldb_message *msg;
1092 TALLOC_CTX *mem_ctx;
1094 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1096 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1097 discard_const_p(char *, kwnames),
1098 &py_msg, &py_controls, &validate))
1101 mem_ctx = talloc_new(NULL);
1102 if (mem_ctx == NULL) {
1106 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1108 if (py_controls == Py_None) {
1109 parsed_controls = NULL;
1111 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1112 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1113 talloc_free(controls);
1116 if (!PyLdbMessage_Check(py_msg)) {
1117 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1118 talloc_free(mem_ctx);
1121 msg = pyldb_Message_AsMessage(py_msg);
1124 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1125 if (ret != LDB_SUCCESS) {
1126 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1127 talloc_free(mem_ctx);
1132 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1133 NULL, ldb_op_default_callback, NULL);
1134 if (ret != LDB_SUCCESS) {
1135 PyErr_SetString(PyExc_TypeError, "failed to build request");
1136 talloc_free(mem_ctx);
1140 /* do request and autostart a transaction */
1141 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1143 ret = ldb_transaction_start(ldb_ctx);
1144 if (ret != LDB_SUCCESS) {
1145 talloc_free(mem_ctx);
1146 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1150 ret = ldb_request(ldb_ctx, req);
1151 if (ret == LDB_SUCCESS) {
1152 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1155 if (ret == LDB_SUCCESS) {
1156 ret = ldb_transaction_commit(ldb_ctx);
1158 ldb_transaction_cancel(ldb_ctx);
1161 talloc_free(mem_ctx);
1162 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1169 * Obtain a ldb message from a Python Dictionary object.
1171 * @param mem_ctx Memory context
1172 * @param py_obj Python Dictionary object
1173 * @param ldb_ctx LDB context
1174 * @param mod_flags Flags to be set on every message element
1175 * @return ldb_message on success or NULL on failure
1177 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1179 struct ldb_context *ldb_ctx,
1180 unsigned int mod_flags)
1182 struct ldb_message *msg;
1183 unsigned int msg_pos = 0;
1184 Py_ssize_t dict_pos = 0;
1185 PyObject *key, *value;
1186 struct ldb_message_element *msg_el;
1187 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1189 msg = ldb_msg_new(mem_ctx);
1194 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1197 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1198 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1201 if (msg->dn == NULL) {
1202 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1206 PyErr_SetString(PyExc_TypeError, "no dn set");
1210 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1211 char *key_str = PyString_AsString(key);
1212 if (ldb_attr_cmp(key_str, "dn") != 0) {
1213 msg_el = PyObject_AsMessageElement(msg->elements, value,
1214 mod_flags, key_str);
1215 if (msg_el == NULL) {
1216 PyErr_SetString(PyExc_TypeError, "unable to import element");
1219 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1224 msg->num_elements = msg_pos;
1229 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1233 struct ldb_context *ldb_ctx;
1234 struct ldb_request *req;
1235 struct ldb_message *msg = NULL;
1236 PyObject *py_controls = Py_None;
1237 TALLOC_CTX *mem_ctx;
1238 struct ldb_control **parsed_controls;
1239 const char * const kwnames[] = { "message", "controls", NULL };
1241 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1242 discard_const_p(char *, kwnames),
1243 &py_obj, &py_controls))
1246 mem_ctx = talloc_new(NULL);
1247 if (mem_ctx == NULL) {
1251 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1253 if (py_controls == Py_None) {
1254 parsed_controls = NULL;
1256 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1257 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1258 talloc_free(controls);
1261 if (PyLdbMessage_Check(py_obj)) {
1262 msg = pyldb_Message_AsMessage(py_obj);
1263 } else if (PyDict_Check(py_obj)) {
1264 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1266 PyErr_SetString(PyExc_TypeError,
1267 "Dictionary or LdbMessage object expected!");
1271 /* we should have a PyErr already set */
1272 talloc_free(mem_ctx);
1276 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1277 if (ret != LDB_SUCCESS) {
1278 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1279 talloc_free(mem_ctx);
1283 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1284 NULL, ldb_op_default_callback, NULL);
1285 if (ret != LDB_SUCCESS) {
1286 PyErr_SetString(PyExc_TypeError, "failed to build request");
1287 talloc_free(mem_ctx);
1291 /* do request and autostart a transaction */
1292 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1294 ret = ldb_transaction_start(ldb_ctx);
1295 if (ret != LDB_SUCCESS) {
1296 talloc_free(mem_ctx);
1297 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1301 ret = ldb_request(ldb_ctx, req);
1302 if (ret == LDB_SUCCESS) {
1303 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1306 if (ret == LDB_SUCCESS) {
1307 ret = ldb_transaction_commit(ldb_ctx);
1309 ldb_transaction_cancel(ldb_ctx);
1312 talloc_free(mem_ctx);
1313 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1318 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1323 struct ldb_context *ldb_ctx;
1324 struct ldb_request *req;
1325 PyObject *py_controls = Py_None;
1326 TALLOC_CTX *mem_ctx;
1327 struct ldb_control **parsed_controls;
1328 const char * const kwnames[] = { "dn", "controls", NULL };
1330 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1331 discard_const_p(char *, kwnames),
1332 &py_dn, &py_controls))
1335 mem_ctx = talloc_new(NULL);
1336 if (mem_ctx == NULL) {
1340 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1342 if (py_controls == Py_None) {
1343 parsed_controls = NULL;
1345 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1346 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1347 talloc_free(controls);
1350 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1351 talloc_free(mem_ctx);
1355 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1356 NULL, ldb_op_default_callback, NULL);
1357 if (ret != LDB_SUCCESS) {
1358 PyErr_SetString(PyExc_TypeError, "failed to build request");
1359 talloc_free(mem_ctx);
1363 /* do request and autostart a transaction */
1364 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1366 ret = ldb_transaction_start(ldb_ctx);
1367 if (ret != LDB_SUCCESS) {
1368 talloc_free(mem_ctx);
1369 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1373 ret = ldb_request(ldb_ctx, req);
1374 if (ret == LDB_SUCCESS) {
1375 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1378 if (ret == LDB_SUCCESS) {
1379 ret = ldb_transaction_commit(ldb_ctx);
1381 ldb_transaction_cancel(ldb_ctx);
1384 talloc_free(mem_ctx);
1385 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1390 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1392 PyObject *py_dn1, *py_dn2;
1393 struct ldb_dn *dn1, *dn2;
1395 TALLOC_CTX *mem_ctx;
1396 PyObject *py_controls = Py_None;
1397 struct ldb_control **parsed_controls;
1398 struct ldb_context *ldb_ctx;
1399 struct ldb_request *req;
1400 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1402 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1404 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1405 discard_const_p(char *, kwnames),
1406 &py_dn1, &py_dn2, &py_controls))
1410 mem_ctx = talloc_new(NULL);
1411 if (mem_ctx == NULL) {
1416 if (py_controls == Py_None) {
1417 parsed_controls = NULL;
1419 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1420 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1421 talloc_free(controls);
1425 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1426 talloc_free(mem_ctx);
1430 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1431 talloc_free(mem_ctx);
1435 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1436 NULL, ldb_op_default_callback, NULL);
1437 if (ret != LDB_SUCCESS) {
1438 PyErr_SetString(PyExc_TypeError, "failed to build request");
1439 talloc_free(mem_ctx);
1443 /* do request and autostart a transaction */
1444 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1446 ret = ldb_transaction_start(ldb_ctx);
1447 if (ret != LDB_SUCCESS) {
1448 talloc_free(mem_ctx);
1449 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1453 ret = ldb_request(ldb_ctx, req);
1454 if (ret == LDB_SUCCESS) {
1455 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1458 if (ret == LDB_SUCCESS) {
1459 ret = ldb_transaction_commit(ldb_ctx);
1461 ldb_transaction_cancel(ldb_ctx);
1464 talloc_free(mem_ctx);
1465 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1470 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1473 if (!PyArg_ParseTuple(args, "s", &name))
1476 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1481 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1483 char *attribute, *syntax;
1486 struct ldb_context *ldb_ctx;
1488 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1491 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1492 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1494 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1499 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1504 /* We don't want this attached to the 'ldb' any more */
1505 return Py_BuildValue(discard_const_p(char, "(iO)"),
1507 PyLdbMessage_FromMessage(ldif->msg));
1512 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1516 struct ldb_ldif ldif;
1519 TALLOC_CTX *mem_ctx;
1521 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1524 if (!PyLdbMessage_Check(py_msg)) {
1525 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1529 ldif.msg = pyldb_Message_AsMessage(py_msg);
1530 ldif.changetype = changetype;
1532 mem_ctx = talloc_new(NULL);
1534 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1536 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1540 ret = PyString_FromString(string);
1542 talloc_free(mem_ctx);
1547 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1549 PyObject *list, *ret;
1550 struct ldb_ldif *ldif;
1553 TALLOC_CTX *mem_ctx;
1555 if (!PyArg_ParseTuple(args, "s", &s))
1558 mem_ctx = talloc_new(NULL);
1563 list = PyList_New(0);
1564 while (s && *s != '\0') {
1565 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1566 talloc_steal(mem_ctx, ldif);
1568 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1570 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1571 talloc_free(mem_ctx);
1575 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1576 ret = PyObject_GetIter(list);
1581 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1584 PyObject *py_msg_old;
1585 PyObject *py_msg_new;
1586 struct ldb_message *diff;
1587 struct ldb_context *ldb;
1590 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1593 if (!PyLdbMessage_Check(py_msg_old)) {
1594 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1598 if (!PyLdbMessage_Check(py_msg_new)) {
1599 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1603 ldb = pyldb_Ldb_AsLdbContext(self);
1604 ldb_ret = ldb_msg_difference(ldb, ldb,
1605 pyldb_Message_AsMessage(py_msg_old),
1606 pyldb_Message_AsMessage(py_msg_new),
1608 if (ldb_ret != LDB_SUCCESS) {
1609 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1613 py_ret = PyLdbMessage_FromMessage(diff);
1615 talloc_unlink(ldb, diff);
1620 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1622 const struct ldb_schema_attribute *a;
1623 struct ldb_val old_val;
1624 struct ldb_val new_val;
1625 TALLOC_CTX *mem_ctx;
1630 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1633 old_val.data = (uint8_t *)PyString_AsString(val);
1634 old_val.length = PyString_Size(val);
1636 if (old_val.data == NULL) {
1637 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1641 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1647 mem_ctx = talloc_new(NULL);
1648 if (mem_ctx == NULL) {
1653 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1654 talloc_free(mem_ctx);
1658 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1660 talloc_free(mem_ctx);
1665 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1667 PyObject *py_base = Py_None;
1668 int scope = LDB_SCOPE_DEFAULT;
1670 PyObject *py_attrs = Py_None;
1671 PyObject *py_controls = Py_None;
1672 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1674 struct ldb_result *res;
1675 struct ldb_request *req;
1677 struct ldb_context *ldb_ctx;
1678 struct ldb_control **parsed_controls;
1679 struct ldb_dn *base;
1681 TALLOC_CTX *mem_ctx;
1683 /* type "int" rather than "enum" for "scope" is intentional */
1684 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1685 discard_const_p(char *, kwnames),
1686 &py_base, &scope, &expr, &py_attrs, &py_controls))
1690 mem_ctx = talloc_new(NULL);
1691 if (mem_ctx == NULL) {
1695 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1697 if (py_attrs == Py_None) {
1700 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1701 if (attrs == NULL) {
1702 talloc_free(mem_ctx);
1707 if (py_base == Py_None) {
1708 base = ldb_get_default_basedn(ldb_ctx);
1710 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1716 if (py_controls == Py_None) {
1717 parsed_controls = NULL;
1719 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1720 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1721 talloc_free(controls);
1724 res = talloc_zero(mem_ctx, struct ldb_result);
1727 talloc_free(mem_ctx);
1731 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1738 ldb_search_default_callback,
1741 if (ret != LDB_SUCCESS) {
1742 talloc_free(mem_ctx);
1743 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1747 talloc_steal(req, attrs);
1749 ret = ldb_request(ldb_ctx, req);
1751 if (ret == LDB_SUCCESS) {
1752 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1755 if (ret != LDB_SUCCESS) {
1756 talloc_free(mem_ctx);
1757 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1761 py_ret = PyLdbResult_FromResult(res);
1763 talloc_free(mem_ctx);
1768 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1773 if (!PyArg_ParseTuple(args, "s", &name))
1776 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1781 /* FIXME: More interpretation */
1786 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1791 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1794 /* FIXME: More interpretation */
1796 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1801 static PyObject *py_ldb_modules(PyLdbObject *self)
1803 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1804 PyObject *ret = PyList_New(0);
1805 struct ldb_module *mod;
1807 for (mod = ldb->modules; mod; mod = mod->next) {
1808 PyList_Append(ret, PyLdbModule_FromModule(mod));
1814 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1816 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1820 if (!PyArg_ParseTuple(args, "i", &type))
1823 /* FIXME: More interpretation */
1825 ret = ldb_sequence_number(ldb, type, &value);
1827 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1829 return PyLong_FromLongLong(value);
1831 static PyMethodDef py_ldb_methods[] = {
1832 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1833 "S.set_debug(callback) -> None\n"
1834 "Set callback for LDB debug messages.\n"
1835 "The callback should accept a debug level and debug text." },
1836 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1837 "S.set_create_perms(mode) -> None\n"
1838 "Set mode to use when creating new LDB files." },
1839 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1840 "S.set_modules_dir(path) -> None\n"
1841 "Set path LDB should search for modules" },
1842 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1843 "S.transaction_start() -> None\n"
1844 "Start a new transaction." },
1845 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1846 "S.transaction_prepare_commit() -> None\n"
1847 "prepare to commit a new transaction (2-stage commit)." },
1848 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1849 "S.transaction_commit() -> None\n"
1850 "commit a new transaction." },
1851 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1852 "S.transaction_cancel() -> None\n"
1853 "cancel a new transaction." },
1854 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1856 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1858 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1860 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1862 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1864 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1865 "S.connect(url, flags=0, options=None) -> None\n"
1866 "Connect to a LDB URL." },
1867 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1868 "S.modify(message, controls=None, validate=False) -> None\n"
1869 "Modify an entry." },
1870 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1871 "S.add(message, controls=None) -> None\n"
1873 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1874 "S.delete(dn, controls=None) -> None\n"
1875 "Remove an entry." },
1876 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1877 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1878 "Rename an entry." },
1879 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1880 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1881 "Search in a database.\n"
1883 ":param base: Optional base DN to search\n"
1884 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1885 ":param expression: Optional search expression\n"
1886 ":param attrs: Attributes to return (defaults to all)\n"
1887 ":param controls: Optional list of controls\n"
1888 ":return: Iterator over Message objects\n"
1890 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1892 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1894 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1896 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1897 "S.parse_ldif(ldif) -> iter(messages)\n"
1898 "Parse a string formatted using LDIF." },
1899 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1900 "S.write_ldif(message, changetype) -> ldif\n"
1901 "Print the message as a string formatted using LDIF." },
1902 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1903 "S.msg_diff(Message) -> Message\n"
1904 "Return an LDB Message of the difference between two Message objects." },
1905 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1906 "S.get_opaque(name) -> value\n"
1907 "Get an opaque value set on this LDB connection. \n"
1908 ":note: The returned value may not be useful in Python."
1910 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1911 "S.set_opaque(name, value) -> None\n"
1912 "Set an opaque value on this LDB connection. \n"
1913 ":note: Passing incorrect values may cause crashes." },
1914 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1915 "S.modules() -> list\n"
1916 "Return the list of modules on this LDB connection " },
1917 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1918 "S.sequence_number(type) -> value\n"
1919 "Return the value of the sequence according to the requested type" },
1923 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1925 PyLdbModuleObject *ret;
1927 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1932 ret->mem_ctx = talloc_new(NULL);
1933 ret->mod = talloc_reference(ret->mem_ctx, mod);
1934 return (PyObject *)ret;
1937 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1939 return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1942 static PyGetSetDef py_ldb_getset[] = {
1943 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1947 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1949 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1951 struct ldb_result *result;
1955 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1959 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1961 if (ret != LDB_SUCCESS) {
1962 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1966 count = result->count;
1968 talloc_free(result);
1971 PyErr_Format(PyExc_RuntimeError,
1972 "Searching for [%s] dn gave %u results!",
1973 ldb_dn_get_linearized(dn),
1981 static PySequenceMethods py_ldb_seq = {
1982 .sq_contains = (objobjproc)py_ldb_contains,
1985 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1989 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1994 ret->mem_ctx = talloc_new(NULL);
1995 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1996 return (PyObject *)ret;
1999 static void py_ldb_dealloc(PyLdbObject *self)
2001 talloc_free(self->mem_ctx);
2002 Py_TYPE(self)->tp_free(self);
2005 static PyTypeObject PyLdb = {
2006 .tp_name = "ldb.Ldb",
2007 .tp_methods = py_ldb_methods,
2008 .tp_repr = (reprfunc)py_ldb_repr,
2009 .tp_new = py_ldb_new,
2010 .tp_init = (initproc)py_ldb_init,
2011 .tp_dealloc = (destructor)py_ldb_dealloc,
2012 .tp_getset = py_ldb_getset,
2013 .tp_getattro = PyObject_GenericGetAttr,
2014 .tp_basicsize = sizeof(PyLdbObject),
2015 .tp_doc = "Connection to a LDB database.",
2016 .tp_as_sequence = &py_ldb_seq,
2017 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2020 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2022 talloc_free(self->mem_ctx);
2023 Py_DECREF(self->msgs);
2024 Py_DECREF(self->referals);
2025 Py_DECREF(self->controls);
2026 Py_TYPE(self)->tp_free(self);
2029 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2031 Py_INCREF(self->msgs);
2035 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2037 Py_INCREF(self->controls);
2038 return self->controls;
2041 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2043 Py_INCREF(self->referals);
2044 return self->referals;
2047 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2050 if (self->msgs == NULL) {
2051 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2054 size = PyList_Size(self->msgs);
2055 return PyInt_FromLong(size);
2058 static PyGetSetDef py_ldb_result_getset[] = {
2059 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2060 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2061 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2062 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2066 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2068 return PyObject_GetIter(self->msgs);
2071 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2073 return PySequence_Size(self->msgs);
2076 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2078 return PySequence_GetItem(self->msgs, idx);
2081 static PySequenceMethods py_ldb_result_seq = {
2082 .sq_length = (lenfunc)py_ldb_result_len,
2083 .sq_item = (ssizeargfunc)py_ldb_result_find,
2086 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2088 return PyString_FromFormat("<ldb result>");
2092 static PyTypeObject PyLdbResult = {
2093 .tp_name = "ldb.Result",
2094 .tp_repr = (reprfunc)py_ldb_result_repr,
2095 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2096 .tp_iter = (getiterfunc)py_ldb_result_iter,
2097 .tp_getset = py_ldb_result_getset,
2098 .tp_getattro = PyObject_GenericGetAttr,
2099 .tp_basicsize = sizeof(PyLdbResultObject),
2100 .tp_as_sequence = &py_ldb_result_seq,
2101 .tp_doc = "LDB result.",
2102 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2105 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2107 return PyString_FromFormat("<ldb module '%s'>",
2108 pyldb_Module_AsModule(self)->ops->name);
2111 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2113 return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
2116 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2118 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2122 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2124 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2128 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2130 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2134 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2136 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2138 struct ldb_request *req;
2139 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2140 struct ldb_module *mod;
2141 const char * const*attrs;
2143 /* type "int" rather than "enum" for "scope" is intentional */
2144 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2145 discard_const_p(char *, kwnames),
2146 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2151 if (py_attrs == Py_None) {
2154 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
2159 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2160 scope, NULL /* expr */, attrs,
2161 NULL /* controls */, NULL, NULL, NULL);
2163 talloc_steal(req, attrs);
2165 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2167 req->op.search.res = NULL;
2169 ret = mod->ops->search(mod, req);
2171 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2173 py_ret = PyLdbResult_FromResult(req->op.search.res);
2181 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2183 struct ldb_request *req;
2184 PyObject *py_message;
2186 struct ldb_module *mod;
2188 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2191 req = talloc_zero(NULL, struct ldb_request);
2192 req->operation = LDB_ADD;
2193 req->op.add.message = pyldb_Message_AsMessage(py_message);
2195 mod = pyldb_Module_AsModule(self);
2196 ret = mod->ops->add(mod, req);
2198 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2203 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2206 struct ldb_request *req;
2207 PyObject *py_message;
2208 struct ldb_module *mod;
2210 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2213 req = talloc_zero(NULL, struct ldb_request);
2214 req->operation = LDB_MODIFY;
2215 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2217 mod = pyldb_Module_AsModule(self);
2218 ret = mod->ops->modify(mod, req);
2220 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2225 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2228 struct ldb_request *req;
2231 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2234 req = talloc_zero(NULL, struct ldb_request);
2235 req->operation = LDB_DELETE;
2236 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2238 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2240 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2245 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2248 struct ldb_request *req;
2249 PyObject *py_dn1, *py_dn2;
2251 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2254 req = talloc_zero(NULL, struct ldb_request);
2256 req->operation = LDB_RENAME;
2257 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2258 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2260 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2262 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2267 static PyMethodDef py_ldb_module_methods[] = {
2268 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2269 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2270 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2271 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2272 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2273 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2274 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2275 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2279 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2281 talloc_free(self->mem_ctx);
2285 static PyTypeObject PyLdbModule = {
2286 .tp_name = "ldb.LdbModule",
2287 .tp_methods = py_ldb_module_methods,
2288 .tp_repr = (reprfunc)py_ldb_module_repr,
2289 .tp_str = (reprfunc)py_ldb_module_str,
2290 .tp_basicsize = sizeof(PyLdbModuleObject),
2291 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2292 .tp_flags = Py_TPFLAGS_DEFAULT,
2293 .tp_doc = "LDB module (extension)",
2298 * Create a ldb_message_element from a Python object.
2300 * This will accept any sequence objects that contains strings, or
2303 * A reference to set_obj will be borrowed.
2305 * @param mem_ctx Memory context
2306 * @param set_obj Python object to convert
2307 * @param flags ldb_message_element flags to set
2308 * @param attr_name Name of the attribute
2309 * @return New ldb_message_element, allocated as child of mem_ctx
2311 static struct ldb_message_element *PyObject_AsMessageElement(
2312 TALLOC_CTX *mem_ctx,
2315 const char *attr_name)
2317 struct ldb_message_element *me;
2319 if (pyldb_MessageElement_Check(set_obj)) {
2320 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2321 /* We have to talloc_reference() the memory context, not the pointer
2322 * which may not actually be it's own context */
2323 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2324 return pyldb_MessageElement_AsMessageElement(set_obj);
2329 me = talloc(mem_ctx, struct ldb_message_element);
2335 me->name = talloc_strdup(me, attr_name);
2337 if (PyString_Check(set_obj)) {
2339 me->values = talloc_array(me, struct ldb_val, me->num_values);
2340 me->values[0].length = PyString_Size(set_obj);
2341 me->values[0].data = talloc_memdup(me,
2342 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2343 } else if (PySequence_Check(set_obj)) {
2345 me->num_values = PySequence_Size(set_obj);
2346 me->values = talloc_array(me, struct ldb_val, me->num_values);
2347 for (i = 0; i < me->num_values; i++) {
2348 PyObject *obj = PySequence_GetItem(set_obj, i);
2349 if (!PyString_Check(obj)) {
2350 PyErr_Format(PyExc_TypeError,
2351 "Expected string as element %zd in list", i);
2356 me->values[i].length = PyString_Size(obj);
2357 me->values[i].data = talloc_memdup(me,
2358 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2361 PyErr_Format(PyExc_TypeError,
2362 "String or List type expected for '%s' attribute", attr_name);
2371 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2372 struct ldb_message_element *me)
2377 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2378 result = PyList_New(me->num_values);
2380 for (i = 0; i < me->num_values; i++) {
2381 PyList_SetItem(result, i,
2382 PyObject_FromLdbValue(&me->values[i]));
2388 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2391 if (!PyArg_ParseTuple(args, "I", &i))
2393 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2396 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2399 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2401 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2402 return PyInt_FromLong(el->flags);
2405 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2408 struct ldb_message_element *el;
2409 if (!PyArg_ParseTuple(args, "I", &flags))
2412 el = pyldb_MessageElement_AsMessageElement(self);
2417 static PyMethodDef py_ldb_msg_element_methods[] = {
2418 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2419 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2420 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2424 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2426 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2429 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2431 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2432 if (idx < 0 || idx >= el->num_values) {
2433 PyErr_SetString(PyExc_IndexError, "Out of range");
2436 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2439 static PySequenceMethods py_ldb_msg_element_seq = {
2440 .sq_length = (lenfunc)py_ldb_msg_element_len,
2441 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2444 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2446 int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2447 pyldb_MessageElement_AsMessageElement(other));
2451 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2453 PyObject *el = ldb_msg_element_to_set(NULL,
2454 pyldb_MessageElement_AsMessageElement(self));
2455 PyObject *ret = PyObject_GetIter(el);
2460 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2462 PyLdbMessageElementObject *ret;
2463 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2468 ret->mem_ctx = talloc_new(NULL);
2469 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2474 return (PyObject *)ret;
2477 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2479 PyObject *py_elements = NULL;
2480 struct ldb_message_element *el;
2481 unsigned int flags = 0;
2483 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2484 PyLdbMessageElementObject *ret;
2485 TALLOC_CTX *mem_ctx;
2487 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2488 discard_const_p(char *, kwnames),
2489 &py_elements, &flags, &name))
2492 mem_ctx = talloc_new(NULL);
2493 if (mem_ctx == NULL) {
2498 el = talloc_zero(mem_ctx, struct ldb_message_element);
2501 talloc_free(mem_ctx);
2505 if (py_elements != NULL) {
2507 if (PyString_Check(py_elements)) {
2509 el->values = talloc_array(el, struct ldb_val, 1);
2510 if (el->values == NULL) {
2511 talloc_free(mem_ctx);
2515 el->values[0].length = PyString_Size(py_elements);
2516 el->values[0].data = talloc_memdup(el->values,
2517 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2518 } else if (PySequence_Check(py_elements)) {
2519 el->num_values = PySequence_Size(py_elements);
2520 el->values = talloc_array(el, struct ldb_val, el->num_values);
2521 if (el->values == NULL) {
2522 talloc_free(mem_ctx);
2526 for (i = 0; i < el->num_values; i++) {
2527 PyObject *item = PySequence_GetItem(py_elements, i);
2529 talloc_free(mem_ctx);
2532 if (!PyString_Check(item)) {
2533 PyErr_Format(PyExc_TypeError,
2534 "Expected string as element %zd in list", i);
2535 talloc_free(mem_ctx);
2538 el->values[i].length = PyString_Size(item);
2539 el->values[i].data = talloc_memdup(el,
2540 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2543 PyErr_SetString(PyExc_TypeError,
2544 "Expected string or list");
2545 talloc_free(mem_ctx);
2551 el->name = talloc_strdup(el, name);
2553 ret = PyObject_New(PyLdbMessageElementObject, type);
2555 talloc_free(mem_ctx);
2559 ret->mem_ctx = mem_ctx;
2561 return (PyObject *)ret;
2564 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2566 char *element_str = NULL;
2568 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2569 PyObject *ret, *repr;
2571 for (i = 0; i < el->num_values; i++) {
2572 PyObject *o = py_ldb_msg_element_find(self, i);
2573 repr = PyObject_Repr(o);
2574 if (element_str == NULL)
2575 element_str = talloc_strdup(NULL, PyString_AsString(repr));
2577 element_str = talloc_asprintf_append(element_str, ",%s", PyString_AsString(repr));
2581 if (element_str != NULL) {
2582 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2583 talloc_free(element_str);
2585 ret = PyString_FromString("MessageElement([])");
2591 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2593 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2595 if (el->num_values == 1)
2596 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2601 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2603 talloc_free(self->mem_ctx);
2607 static PyTypeObject PyLdbMessageElement = {
2608 .tp_name = "ldb.MessageElement",
2609 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2610 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2611 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2612 .tp_str = (reprfunc)py_ldb_msg_element_str,
2613 .tp_methods = py_ldb_msg_element_methods,
2614 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2615 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2616 .tp_as_sequence = &py_ldb_msg_element_seq,
2617 .tp_new = py_ldb_msg_element_new,
2618 .tp_flags = Py_TPFLAGS_DEFAULT,
2619 .tp_doc = "An element of a Message",
2623 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2628 struct ldb_message *msg;
2629 struct ldb_context *ldb_ctx;
2630 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2632 if (!PyArg_ParseTuple(args, "O!O!|I",
2633 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2638 if (!PyLdb_Check(py_ldb)) {
2639 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
2643 /* mask only flags we are going to use */
2644 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2646 PyErr_SetString(PyExc_ValueError,
2647 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2648 " expected as mod_flag value");
2652 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2654 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2659 py_ret = PyLdbMessage_FromMessage(msg);
2661 talloc_unlink(ldb_ctx, msg);
2666 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2669 if (!PyArg_ParseTuple(args, "s", &name))
2672 ldb_msg_remove_attr(self->msg, name);
2677 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2679 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2680 Py_ssize_t i, j = 0;
2681 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2682 if (msg->dn != NULL) {
2683 PyList_SetItem(obj, j, PyString_FromString("dn"));
2686 for (i = 0; i < msg->num_elements; i++) {
2687 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2693 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2695 struct ldb_message_element *el;
2697 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2698 if (!PyString_Check(py_name)) {
2699 PyErr_SetNone(PyExc_TypeError);
2702 name = PyString_AsString(py_name);
2703 if (!ldb_attr_cmp(name, "dn"))
2704 return pyldb_Dn_FromDn(msg->dn);
2705 el = ldb_msg_find_element(msg, name);
2709 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2712 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2714 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2716 PyErr_SetString(PyExc_KeyError, "No such element");
2722 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2724 PyObject *def = NULL;
2725 const char *kwnames[] = { "name", "default", "idx", NULL };
2726 const char *name = NULL;
2728 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2729 struct ldb_message_element *el;
2731 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2732 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2736 if (strcasecmp(name, "dn") == 0) {
2737 return pyldb_Dn_FromDn(msg->dn);
2740 el = ldb_msg_find_element(msg, name);
2742 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2750 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2753 return PyObject_FromLdbValue(&el->values[idx]);
2756 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2758 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2759 Py_ssize_t i, j = 0;
2760 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2761 if (msg->dn != NULL) {
2762 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2765 for (i = 0; i < msg->num_elements; i++, j++) {
2766 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2767 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2768 PyList_SetItem(l, j, value);
2773 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2775 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2777 PyObject *l = PyList_New(msg->num_elements);
2778 for (i = 0; i < msg->num_elements; i++) {
2779 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2784 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2786 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2787 PyLdbMessageElementObject *py_element;
2789 struct ldb_message_element *el;
2790 struct ldb_message_element *el_new;
2792 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2795 el = py_element->el;
2797 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
2801 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
2802 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2804 /* now deep copy all attribute values */
2805 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
2806 if (el_new->values == NULL) {
2810 el_new->num_values = el->num_values;
2812 for (i = 0; i < el->num_values; i++) {
2813 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
2814 if (el_new->values[i].data == NULL
2815 && el->values[i].length != 0) {
2824 static PyMethodDef py_ldb_msg_methods[] = {
2825 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2826 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2827 "Class method to create ldb.Message object from Dictionary.\n"
2828 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2829 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2830 "S.keys() -> list\n\n"
2831 "Return sequence of all attribute names." },
2832 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2833 "S.remove(name)\n\n"
2834 "Remove all entries for attributes with the specified name."},
2835 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2836 "msg.get(name,default=None,idx=None) -> string\n"
2837 "idx is the index into the values array\n"
2838 "if idx is None, then a list is returned\n"
2839 "if idx is not None, then the element with that index is returned\n"
2840 "if you pass the special name 'dn' then the DN object is returned\n"},
2841 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2842 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2843 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2844 "S.add(element)\n\n"
2845 "Add an element to this message." },
2849 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2851 PyObject *list, *iter;
2853 list = py_ldb_msg_keys(self);
2854 iter = PyObject_GetIter(list);
2859 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2863 if (!PyString_Check(name)) {
2864 PyErr_SetNone(PyExc_TypeError);
2868 attr_name = PyString_AsString(name);
2869 if (value == NULL) {
2871 ldb_msg_remove_attr(self->msg, attr_name);
2874 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2875 value, 0, attr_name);
2879 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2880 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2881 if (ret != LDB_SUCCESS) {
2882 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
2889 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2891 return pyldb_Message_AsMessage(self)->num_elements;
2894 static PyMappingMethods py_ldb_msg_mapping = {
2895 .mp_length = (lenfunc)py_ldb_msg_length,
2896 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2897 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2900 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2902 const char * const kwnames[] = { "dn", NULL };
2903 struct ldb_message *ret;
2904 TALLOC_CTX *mem_ctx;
2905 PyObject *pydn = NULL;
2906 PyLdbMessageObject *py_ret;
2908 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2909 discard_const_p(char *, kwnames),
2913 mem_ctx = talloc_new(NULL);
2914 if (mem_ctx == NULL) {
2919 ret = ldb_msg_new(mem_ctx);
2921 talloc_free(mem_ctx);
2928 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2929 talloc_free(mem_ctx);
2932 ret->dn = talloc_reference(ret, dn);
2935 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2936 if (py_ret == NULL) {
2938 talloc_free(mem_ctx);
2942 py_ret->mem_ctx = mem_ctx;
2944 return (PyObject *)py_ret;
2947 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2949 PyLdbMessageObject *ret;
2951 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2956 ret->mem_ctx = talloc_new(NULL);
2957 ret->msg = talloc_reference(ret->mem_ctx, msg);
2958 return (PyObject *)ret;
2961 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2963 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2964 return pyldb_Dn_FromDn(msg->dn);
2967 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2969 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2970 if (!pyldb_Dn_Check(value)) {
2971 PyErr_SetNone(PyExc_TypeError);
2975 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2979 static PyGetSetDef py_ldb_msg_getset[] = {
2980 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2984 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2986 PyObject *dict = PyDict_New(), *ret;
2987 if (PyDict_Update(dict, (PyObject *)self) != 0)
2989 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2994 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2996 talloc_free(self->mem_ctx);
3000 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
3001 PyLdbMessageObject *py_msg2)
3003 struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
3004 *msg2 = pyldb_Message_AsMessage(py_msg2);
3008 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3009 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3015 ret = msg1->num_elements - msg2->num_elements;
3020 for (i = 0; i < msg1->num_elements; i++) {
3021 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3022 &msg2->elements[i]);
3027 ret = ldb_msg_element_compare(&msg1->elements[i],
3028 &msg2->elements[i]);
3037 static PyTypeObject PyLdbMessage = {
3038 .tp_name = "ldb.Message",
3039 .tp_methods = py_ldb_msg_methods,
3040 .tp_getset = py_ldb_msg_getset,
3041 .tp_as_mapping = &py_ldb_msg_mapping,
3042 .tp_basicsize = sizeof(PyLdbMessageObject),
3043 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3044 .tp_new = py_ldb_msg_new,
3045 .tp_repr = (reprfunc)py_ldb_msg_repr,
3046 .tp_flags = Py_TPFLAGS_DEFAULT,
3047 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3048 .tp_compare = (cmpfunc)py_ldb_msg_compare,
3049 .tp_doc = "A LDB Message",
3052 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3054 PyLdbTreeObject *ret;
3056 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3062 ret->mem_ctx = talloc_new(NULL);
3063 ret->tree = talloc_reference(ret->mem_ctx, tree);
3064 return (PyObject *)ret;
3067 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3069 talloc_free(self->mem_ctx);
3073 static PyTypeObject PyLdbTree = {
3074 .tp_name = "ldb.Tree",
3075 .tp_basicsize = sizeof(PyLdbTreeObject),
3076 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3077 .tp_flags = Py_TPFLAGS_DEFAULT,
3078 .tp_doc = "A search tree",
3082 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3084 PyObject *py_ldb = (PyObject *)mod->private_data;
3085 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3087 py_base = pyldb_Dn_FromDn(req->op.search.base);
3089 if (py_base == NULL)
3090 return LDB_ERR_OPERATIONS_ERROR;
3092 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3094 if (py_tree == NULL)
3095 return LDB_ERR_OPERATIONS_ERROR;
3097 if (req->op.search.attrs == NULL) {
3101 for (len = 0; req->op.search.attrs[len]; len++);
3102 py_attrs = PyList_New(len);
3103 for (i = 0; i < len; i++)
3104 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
3107 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3108 discard_const_p(char, "OiOO"),
3109 py_base, req->op.search.scope, py_tree, py_attrs);
3111 Py_DECREF(py_attrs);
3115 if (py_result == NULL) {
3116 return LDB_ERR_PYTHON_EXCEPTION;
3119 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3120 if (req->op.search.res == NULL) {
3121 return LDB_ERR_PYTHON_EXCEPTION;
3124 Py_DECREF(py_result);
3129 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3131 PyObject *py_ldb = (PyObject *)mod->private_data;
3132 PyObject *py_result, *py_msg;
3134 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3136 if (py_msg == NULL) {
3137 return LDB_ERR_OPERATIONS_ERROR;
3140 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3141 discard_const_p(char, "O"),
3146 if (py_result == NULL) {
3147 return LDB_ERR_PYTHON_EXCEPTION;
3150 Py_DECREF(py_result);
3155 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3157 PyObject *py_ldb = (PyObject *)mod->private_data;
3158 PyObject *py_result, *py_msg;
3160 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3162 if (py_msg == NULL) {
3163 return LDB_ERR_OPERATIONS_ERROR;
3166 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3167 discard_const_p(char, "O"),
3172 if (py_result == NULL) {
3173 return LDB_ERR_PYTHON_EXCEPTION;
3176 Py_DECREF(py_result);
3181 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3183 PyObject *py_ldb = (PyObject *)mod->private_data;
3184 PyObject *py_result, *py_dn;
3186 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3189 return LDB_ERR_OPERATIONS_ERROR;
3191 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3192 discard_const_p(char, "O"),
3195 if (py_result == NULL) {
3196 return LDB_ERR_PYTHON_EXCEPTION;
3199 Py_DECREF(py_result);
3204 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3206 PyObject *py_ldb = (PyObject *)mod->private_data;
3207 PyObject *py_result, *py_olddn, *py_newdn;
3209 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3211 if (py_olddn == NULL)
3212 return LDB_ERR_OPERATIONS_ERROR;
3214 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3216 if (py_newdn == NULL)
3217 return LDB_ERR_OPERATIONS_ERROR;
3219 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3220 discard_const_p(char, "OO"),
3221 py_olddn, py_newdn);
3223 Py_DECREF(py_olddn);
3224 Py_DECREF(py_newdn);
3226 if (py_result == NULL) {
3227 return LDB_ERR_PYTHON_EXCEPTION;
3230 Py_DECREF(py_result);
3235 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3237 PyObject *py_ldb = (PyObject *)mod->private_data;
3238 PyObject *py_result;
3240 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3241 discard_const_p(char, ""));
3243 Py_XDECREF(py_result);
3245 return LDB_ERR_OPERATIONS_ERROR;
3248 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3250 PyObject *py_ldb = (PyObject *)mod->private_data;
3251 PyObject *py_result;
3253 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3254 discard_const_p(char, ""));
3256 Py_XDECREF(py_result);
3258 return LDB_ERR_OPERATIONS_ERROR;
3261 static int py_module_start_transaction(struct ldb_module *mod)
3263 PyObject *py_ldb = (PyObject *)mod->private_data;
3264 PyObject *py_result;
3266 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3267 discard_const_p(char, ""));
3269 if (py_result == NULL) {
3270 return LDB_ERR_PYTHON_EXCEPTION;
3273 Py_DECREF(py_result);
3278 static int py_module_end_transaction(struct ldb_module *mod)
3280 PyObject *py_ldb = (PyObject *)mod->private_data;
3281 PyObject *py_result;
3283 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3284 discard_const_p(char, ""));
3286 if (py_result == NULL) {
3287 return LDB_ERR_PYTHON_EXCEPTION;
3290 Py_DECREF(py_result);
3295 static int py_module_del_transaction(struct ldb_module *mod)
3297 PyObject *py_ldb = (PyObject *)mod->private_data;
3298 PyObject *py_result;
3300 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3301 discard_const_p(char, ""));
3303 if (py_result == NULL) {
3304 return LDB_ERR_PYTHON_EXCEPTION;
3307 Py_DECREF(py_result);
3312 static int py_module_destructor(struct ldb_module *mod)
3314 Py_DECREF((PyObject *)mod->private_data);
3318 static int py_module_init(struct ldb_module *mod)
3320 PyObject *py_class = (PyObject *)mod->ops->private_data;
3321 PyObject *py_result, *py_next, *py_ldb;
3323 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3326 return LDB_ERR_OPERATIONS_ERROR;
3328 py_next = PyLdbModule_FromModule(mod->next);
3330 if (py_next == NULL)
3331 return LDB_ERR_OPERATIONS_ERROR;
3333 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3336 if (py_result == NULL) {
3337 return LDB_ERR_PYTHON_EXCEPTION;
3340 mod->private_data = py_result;
3342 talloc_set_destructor(mod, py_module_destructor);
3344 return ldb_next_init(mod);
3347 static PyObject *py_register_module(PyObject *module, PyObject *args)
3350 struct ldb_module_ops *ops;
3353 if (!PyArg_ParseTuple(args, "O", &input))
3356 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3362 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3365 ops->private_data = input;
3366 ops->init_context = py_module_init;
3367 ops->search = py_module_search;
3368 ops->add = py_module_add;
3369 ops->modify = py_module_modify;
3370 ops->del = py_module_del;
3371 ops->rename = py_module_rename;
3372 ops->request = py_module_request;
3373 ops->extended = py_module_extended;
3374 ops->start_transaction = py_module_start_transaction;
3375 ops->end_transaction = py_module_end_transaction;
3376 ops->del_transaction = py_module_del_transaction;
3378 ret = ldb_register_module(ops);
3380 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3385 static PyObject *py_timestring(PyObject *module, PyObject *args)
3387 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3388 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3392 if (!PyArg_ParseTuple(args, "l", &t_val))
3394 tresult = ldb_timestring(NULL, (time_t) t_val);
3395 ret = PyString_FromString(tresult);
3396 talloc_free(tresult);
3400 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3403 if (!PyArg_ParseTuple(args, "s", &str))
3406 return PyInt_FromLong(ldb_string_to_time(str));
3409 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3412 if (!PyArg_ParseTuple(args, "s", &name))
3414 return PyBool_FromLong(ldb_valid_attr_name(name));
3418 encode a string using RFC2254 rules
3420 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3422 char *str, *encoded;
3427 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3429 val.data = (uint8_t *)str;
3432 encoded = ldb_binary_encode(NULL, val);
3433 if (encoded == NULL) {
3434 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3437 ret = PyString_FromString(encoded);
3438 talloc_free(encoded);
3443 decode a string using RFC2254 rules
3445 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3451 if (!PyArg_ParseTuple(args, "s", &str))
3454 val = ldb_binary_decode(NULL, str);
3455 if (val.data == NULL) {
3456 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3459 ret = Py_BuildValue("s#", val.data, val.length);
3460 talloc_free(val.data);
3464 static PyMethodDef py_ldb_global_methods[] = {
3465 { "register_module", py_register_module, METH_VARARGS,
3466 "S.register_module(module) -> None\n\n"
3467 "Register a LDB module."},
3468 { "timestring", py_timestring, METH_VARARGS,
3469 "S.timestring(int) -> string\n\n"
3470 "Generate a LDAP time string from a UNIX timestamp" },
3471 { "string_to_time", py_string_to_time, METH_VARARGS,
3472 "S.string_to_time(string) -> int\n\n"
3473 "Parse a LDAP time string into a UNIX timestamp." },
3474 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3475 "S.valid_attr_name(name) -> bool\n\nn"
3476 "Check whether the supplied name is a valid attribute name." },
3477 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3478 "S.open() -> Ldb\n\n"
3479 "Open a new LDB context." },
3480 { "binary_encode", py_binary_encode, METH_VARARGS,
3481 "S.binary_encode(string) -> string\n\n"
3482 "Perform a RFC2254 binary encoding on a string" },
3483 { "binary_decode", py_binary_decode, METH_VARARGS,
3484 "S.binary_decode(string) -> string\n\n"
3485 "Perform a RFC2254 binary decode on a string" },
3493 if (PyType_Ready(&PyLdbDn) < 0)
3496 if (PyType_Ready(&PyLdbMessage) < 0)
3499 if (PyType_Ready(&PyLdbMessageElement) < 0)
3502 if (PyType_Ready(&PyLdb) < 0)
3505 if (PyType_Ready(&PyLdbModule) < 0)
3508 if (PyType_Ready(&PyLdbTree) < 0)
3511 if (PyType_Ready(&PyLdbResult) < 0)
3514 if (PyType_Ready(&PyLdbControl) < 0)
3517 m = Py_InitModule3("ldb", py_ldb_global_methods,
3518 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3522 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3523 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3524 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3525 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3526 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3527 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3528 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3530 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3531 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3532 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3533 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3535 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3536 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3537 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3539 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3540 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3541 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3542 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3543 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3544 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3545 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3546 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3547 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3548 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3549 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3550 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3551 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3552 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3553 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3554 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3555 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3556 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3557 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3558 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3559 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3560 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3561 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3562 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3563 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3564 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3565 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3566 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3567 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3568 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3569 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3570 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3571 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3572 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3573 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3574 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3575 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3576 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3577 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3579 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3580 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3581 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3582 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3584 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3586 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3587 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3590 Py_INCREF(&PyLdbDn);
3591 Py_INCREF(&PyLdbModule);
3592 Py_INCREF(&PyLdbMessage);
3593 Py_INCREF(&PyLdbMessageElement);
3594 Py_INCREF(&PyLdbTree);
3595 Py_INCREF(&PyLdbResult);
3596 Py_INCREF(&PyLdbControl);
3598 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3599 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3600 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3601 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3602 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3603 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3604 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3606 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3608 #define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3610 ADD_LDB_STRING(SYNTAX_DN);
3611 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3612 ADD_LDB_STRING(SYNTAX_INTEGER);
3613 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3614 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3615 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3616 ADD_LDB_STRING(OID_COMPARATOR_AND);
3617 ADD_LDB_STRING(OID_COMPARATOR_OR);