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;
70 static PyObject *richcmp(int cmp_val, int op)
74 case Py_LT: ret = cmp_val < 0; break;
75 case Py_LE: ret = cmp_val <= 0; break;
76 case Py_EQ: ret = cmp_val == 0; break;
77 case Py_NE: ret = cmp_val != 0; break;
78 case Py_GT: ret = cmp_val > 0; break;
79 case Py_GE: ret = cmp_val >= 0; break;
81 Py_INCREF(Py_NotImplemented);
82 return Py_NotImplemented;
84 return PyBool_FromLong(ret);
88 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
90 if (self->data != NULL) {
91 char* control = ldb_control_to_string(self->mem_ctx, self->data);
92 if (control == NULL) {
96 return PyString_FromString(control);
98 return PyString_FromFormat("ldb control");
102 static void py_ldb_control_dealloc(PyLdbControlObject *self)
104 if (self->mem_ctx != NULL) {
105 talloc_free(self->mem_ctx);
108 Py_TYPE(self)->tp_free(self);
111 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
113 return PyString_FromString(self->data->oid);
116 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
118 return PyBool_FromLong(self->data->critical);
121 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
123 if (PyObject_IsTrue(value)) {
124 self->data->critical = true;
126 self->data->critical = false;
131 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
134 const char * const kwnames[] = { "ldb", "data", NULL };
135 struct ldb_control *parsed_controls;
136 PyLdbControlObject *ret;
139 struct ldb_context *ldb_ctx;
141 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
142 discard_const_p(char *, kwnames),
143 &PyLdb, &py_ldb, &data))
146 mem_ctx = talloc_new(NULL);
147 if (mem_ctx == NULL) {
152 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
153 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
155 if (!parsed_controls) {
156 talloc_free(mem_ctx);
157 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
161 ret = PyObject_New(PyLdbControlObject, type);
164 talloc_free(mem_ctx);
168 ret->mem_ctx = mem_ctx;
170 ret->data = talloc_move(mem_ctx, &parsed_controls);
171 if (ret->data == NULL) {
174 talloc_free(mem_ctx);
178 return (PyObject *)ret;
181 static PyGetSetDef py_ldb_control_getset[] = {
182 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
183 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
187 static PyTypeObject PyLdbControl = {
188 .tp_name = "ldb.control",
189 .tp_dealloc = (destructor)py_ldb_control_dealloc,
190 .tp_getattro = PyObject_GenericGetAttr,
191 .tp_basicsize = sizeof(PyLdbControlObject),
192 .tp_getset = py_ldb_control_getset,
193 .tp_doc = "LDB control.",
194 .tp_str = (reprfunc)py_ldb_control_str,
195 .tp_new = py_ldb_control_new,
196 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
199 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
201 if (ret == LDB_ERR_PYTHON_EXCEPTION)
202 return; /* Python exception should already be set, just keep that */
204 PyErr_SetObject(error,
205 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
206 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
209 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
211 return PyString_FromStringAndSize((const char *)val->data, val->length);
215 * Create a Python object from a ldb_result.
217 * @param result LDB result to convert
218 * @return Python object with converted result (a list object)
220 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
222 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
223 PyLdbControlObject *ctrl;
224 if (ctl_ctx == NULL) {
229 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
231 talloc_free(ctl_ctx);
235 ctrl->mem_ctx = ctl_ctx;
236 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
237 if (ctrl->data == NULL) {
242 return (PyObject*) ctrl;
246 * Create a Python object from a ldb_result.
248 * @param result LDB result to convert
249 * @return Python object with converted result (a list object)
251 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
253 PyLdbResultObject *ret;
254 PyObject *list, *controls, *referals;
257 if (result == NULL) {
261 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
267 list = PyList_New(result->count);
274 for (i = 0; i < result->count; i++) {
275 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
278 ret->mem_ctx = talloc_new(NULL);
279 if (ret->mem_ctx == NULL) {
288 if (result->controls) {
290 while (result->controls[i]) {
293 controls = PyList_New(i);
294 if (controls == NULL) {
299 for (i=0; result->controls[i]; i++) {
300 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
307 PyList_SetItem(controls, i, ctrl);
311 * No controls so we keep an empty list
313 controls = PyList_New(0);
314 if (controls == NULL) {
321 ret->controls = controls;
325 while (result->refs && result->refs[i]) {
329 referals = PyList_New(i);
330 if (referals == NULL) {
336 for (i = 0;result->refs && result->refs[i]; i++) {
337 PyList_SetItem(referals, i, PyString_FromString(result->refs[i]));
339 ret->referals = referals;
340 return (PyObject *)ret;
344 * Create a LDB Result from a Python object.
345 * If conversion fails, NULL will be returned and a Python exception set.
347 * Note: the result object only includes the messages at the moment; extended
348 * result, controls and referrals are ignored.
350 * @param mem_ctx Memory context in which to allocate the LDB Result
351 * @param obj Python object to convert
352 * @return a ldb_result, or NULL if the conversion failed
354 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
357 struct ldb_result *res;
363 res = talloc_zero(mem_ctx, struct ldb_result);
364 res->count = PyList_Size(obj);
365 res->msgs = talloc_array(res, struct ldb_message *, res->count);
366 for (i = 0; i < res->count; i++) {
367 PyObject *item = PyList_GetItem(obj, i);
368 res->msgs[i] = pyldb_Message_AsMessage(item);
373 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
375 return PyBool_FromLong(ldb_dn_validate(self->dn));
378 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
380 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
383 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
385 return PyBool_FromLong(ldb_dn_is_special(self->dn));
388 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
390 return PyBool_FromLong(ldb_dn_is_null(self->dn));
393 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
395 return PyString_FromString(ldb_dn_get_casefold(self->dn));
398 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
400 return PyString_FromString(ldb_dn_get_linearized(self->dn));
403 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
405 return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
408 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
410 return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
413 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
415 const char * const kwnames[] = { "mode", NULL };
417 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
418 discard_const_p(char *, kwnames),
421 return PyString_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
424 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
427 const struct ldb_val *val;
429 if (!PyArg_ParseTuple(args, "s", &name))
431 val = ldb_dn_get_extended_component(self->dn, name);
436 return PyString_FromStringAndSize((const char *)val->data, val->length);
439 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
445 if (!PyArg_ParseTuple(args, "sO", &name, &value))
448 if (value == Py_None) {
449 err = ldb_dn_set_extended_component(self->dn, name, NULL);
452 if (!PyString_Check(value)) {
453 PyErr_SetString(PyExc_TypeError, "Expected a string argument");
456 val.data = (uint8_t *)PyString_AsString(value);
457 val.length = PyString_Size(value);
458 err = ldb_dn_set_extended_component(self->dn, name, &val);
461 if (err != LDB_SUCCESS) {
462 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
469 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
471 return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
474 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
478 if (!PyArg_ParseTuple(args, "s", &name))
481 return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
484 static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
487 if (!pyldb_Dn_Check(dn2)) {
488 Py_INCREF(Py_NotImplemented);
489 return Py_NotImplemented;
491 ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2));
492 return richcmp(ret, op);
495 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
497 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
498 struct ldb_dn *parent;
499 PyLdbDnObject *py_ret;
500 TALLOC_CTX *mem_ctx = talloc_new(NULL);
502 parent = ldb_dn_get_parent(mem_ctx, dn);
503 if (parent == NULL) {
504 talloc_free(mem_ctx);
508 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
509 if (py_ret == NULL) {
511 talloc_free(mem_ctx);
514 py_ret->mem_ctx = mem_ctx;
516 return (PyObject *)py_ret;
519 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
522 struct ldb_dn *dn, *other;
523 if (!PyArg_ParseTuple(args, "O", &py_other))
526 dn = pyldb_Dn_AsDn((PyObject *)self);
528 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
531 return PyBool_FromLong(ldb_dn_add_child(dn, other));
534 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
537 struct ldb_dn *other, *dn;
538 if (!PyArg_ParseTuple(args, "O", &py_other))
541 dn = pyldb_Dn_AsDn((PyObject *)self);
543 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
546 return PyBool_FromLong(ldb_dn_add_base(dn, other));
549 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
553 if (!PyArg_ParseTuple(args, "i", &i))
556 dn = pyldb_Dn_AsDn((PyObject *)self);
558 return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
561 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
564 struct ldb_dn *dn, *base;
565 if (!PyArg_ParseTuple(args, "O", &py_base))
568 dn = pyldb_Dn_AsDn((PyObject *)self);
570 if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
573 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
576 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
580 unsigned int num = 0;
582 if (!PyArg_ParseTuple(args, "I", &num))
585 dn = pyldb_Dn_AsDn((PyObject *)self);
587 name = ldb_dn_get_component_name(dn, num);
592 return PyString_FromString(name);
595 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
598 const struct ldb_val *val;
599 unsigned int num = 0;
601 if (!PyArg_ParseTuple(args, "I", &num))
604 dn = pyldb_Dn_AsDn((PyObject *)self);
606 val = ldb_dn_get_component_val(dn, num);
611 return PyObject_FromLdbValue(val);
614 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
616 unsigned int num = 0;
618 PyObject *value = Py_None;
619 struct ldb_val val = { NULL, };
622 if (!PyArg_ParseTuple(args, "IsO", &num, &name, &value))
625 if (value != Py_None) {
626 if (!PyString_Check(value)) {
627 PyErr_SetString(PyExc_TypeError, "Expected a string argument");
630 val.data = (uint8_t *)PyString_AsString(value);
631 val.length = PyString_Size(value);
634 err = ldb_dn_set_component(self->dn, num, name, val);
635 if (err != LDB_SUCCESS) {
636 PyErr_SetString(PyExc_TypeError, "Failed to set component");
643 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
648 dn = pyldb_Dn_AsDn((PyObject *)self);
650 name = ldb_dn_get_rdn_name(dn);
655 return PyString_FromString(name);
658 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
661 const struct ldb_val *val;
663 dn = pyldb_Dn_AsDn((PyObject *)self);
665 val = ldb_dn_get_rdn_val(dn);
670 return PyObject_FromLdbValue(val);
673 static PyMethodDef py_ldb_dn_methods[] = {
674 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
675 "S.validate() -> bool\n"
676 "Validate DN is correct." },
677 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
678 "S.is_valid() -> bool\n" },
679 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
680 "S.is_special() -> bool\n"
681 "Check whether this is a special LDB DN." },
682 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
683 "Check whether this is a null DN." },
684 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
686 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
688 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
689 "S.canonical_str() -> string\n"
690 "Canonical version of this DN (like a posix path)." },
691 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
692 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
693 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
694 "S.canonical_ex_str() -> string\n"
695 "Canonical version of this DN (like a posix path, with terminating newline)." },
696 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
697 "S.extended_str(mode=1) -> string\n"
698 "Extended version of this DN" },
699 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
701 "Get the parent for this DN." },
702 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
703 "S.add_child(dn) -> None\n"
704 "Add a child DN to this DN." },
705 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
706 "S.add_base(dn) -> None\n"
707 "Add a base DN to this DN." },
708 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
709 "S.remove_base_components(int) -> bool\n"
710 "Remove a number of DN components from the base of this DN." },
711 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
712 "S.check_special(name) -> bool\n\n"
713 "Check if name is a special DN name"},
714 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
715 "S.get_extended_component(name) -> string\n\n"
716 "returns a DN extended component as a binary string"},
717 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
718 "S.set_extended_component(name, value) -> None\n\n"
719 "set a DN extended component as a binary string"},
720 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
721 "S.get_component_name(num) -> string\n"
722 "get the attribute name of the specified component" },
723 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
724 "S.get_component_value(num) -> string\n"
725 "get the attribute value of the specified component as a binary string" },
726 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
727 "S.get_component_value(num, name, value) -> None\n"
728 "set the attribute name and value of the specified component" },
729 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
730 "S.get_rdn_name() -> string\n"
731 "get the RDN attribute name" },
732 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
733 "S.get_rdn_value() -> string\n"
734 "get the RDN attribute value as a binary string" },
738 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
740 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
744 copy a DN as a python object
746 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
748 PyLdbDnObject *py_ret;
750 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
751 if (py_ret == NULL) {
755 py_ret->mem_ctx = talloc_new(NULL);
756 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
757 return (PyObject *)py_ret;
760 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
762 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
764 PyLdbDnObject *py_ret;
766 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
769 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
770 if (py_ret == NULL) {
774 py_ret->mem_ctx = talloc_new(NULL);
775 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
776 ldb_dn_add_base(py_ret->dn, other);
777 return (PyObject *)py_ret;
780 static PySequenceMethods py_ldb_dn_seq = {
781 .sq_length = (lenfunc)py_ldb_dn_len,
782 .sq_concat = (binaryfunc)py_ldb_dn_concat,
785 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
790 struct ldb_context *ldb_ctx;
792 PyLdbDnObject *py_ret;
793 const char * const kwnames[] = { "ldb", "dn", NULL };
795 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
796 discard_const_p(char *, kwnames),
800 if (!PyLdb_Check(py_ldb)) {
801 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
805 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
807 mem_ctx = talloc_new(NULL);
808 if (mem_ctx == NULL) {
813 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
814 if (!ldb_dn_validate(ret)) {
815 talloc_free(mem_ctx);
816 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
820 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
822 talloc_free(mem_ctx);
826 py_ret->mem_ctx = mem_ctx;
828 return (PyObject *)py_ret;
831 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
833 talloc_free(self->mem_ctx);
837 static PyTypeObject PyLdbDn = {
839 .tp_methods = py_ldb_dn_methods,
840 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
841 .tp_repr = (reprfunc)py_ldb_dn_repr,
842 .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp,
843 .tp_as_sequence = &py_ldb_dn_seq,
844 .tp_doc = "A LDB distinguished name.",
845 .tp_new = py_ldb_dn_new,
846 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
847 .tp_basicsize = sizeof(PyLdbDnObject),
848 .tp_flags = Py_TPFLAGS_DEFAULT,
852 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
853 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
855 PyObject *fn = (PyObject *)context;
856 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
859 static PyObject *py_ldb_debug_func;
861 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
864 struct ldb_context *ldb_ctx;
866 if (!PyArg_ParseTuple(args, "O", &cb))
869 if (py_ldb_debug_func != NULL) {
870 Py_DECREF(py_ldb_debug_func);
874 /* FIXME: DECREF cb when exiting program */
875 py_ldb_debug_func = cb;
876 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
877 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
878 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
884 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
887 if (!PyArg_ParseTuple(args, "I", &perms))
890 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
895 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
898 if (!PyArg_ParseTuple(args, "s", &modules_dir))
901 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
906 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
908 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
910 ldb_err = ldb_transaction_start(ldb_ctx);
911 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
915 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
917 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
919 ldb_err = ldb_transaction_commit(ldb_ctx);
920 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
924 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
926 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
928 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
929 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
933 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
935 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
937 ldb_err = ldb_transaction_cancel(ldb_ctx);
938 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
942 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
944 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
946 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
947 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
951 static PyObject *py_ldb_repr(PyLdbObject *self)
953 return PyString_FromFormat("<ldb connection>");
956 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
958 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
961 return py_ldb_dn_copy(dn);
965 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
967 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
970 return py_ldb_dn_copy(dn);
973 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
975 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
978 return py_ldb_dn_copy(dn);
981 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
983 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
986 return py_ldb_dn_copy(dn);
989 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
990 const char *paramname)
994 if (!PyList_Check(list)) {
995 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
998 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1004 for (i = 0; i < PyList_Size(list); i++) {
1005 PyObject *item = PyList_GetItem(list, i);
1006 if (!PyString_Check(item)) {
1007 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
1010 ret[i] = talloc_strndup(ret, PyString_AsString(item),
1011 PyString_Size(item));
1017 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1019 const char * const kwnames[] = { "url", "flags", "options", NULL };
1021 PyObject *py_options = Py_None;
1022 const char **options;
1023 unsigned int flags = 0;
1025 struct ldb_context *ldb;
1027 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1028 discard_const_p(char *, kwnames),
1029 &url, &flags, &py_options))
1032 ldb = pyldb_Ldb_AsLdbContext(self);
1034 if (py_options == Py_None) {
1037 options = PyList_AsStringList(ldb, py_options, "options");
1038 if (options == NULL)
1043 ret = ldb_connect(ldb, url, flags, options);
1044 if (ret != LDB_SUCCESS) {
1045 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1050 talloc_free(options);
1054 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1057 struct ldb_context *ldb;
1058 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1063 ret->mem_ctx = talloc_new(NULL);
1064 ldb = ldb_init(ret->mem_ctx, NULL);
1072 return (PyObject *)ret;
1075 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1078 unsigned int flags = 0;
1079 PyObject *py_options = Py_None;
1081 const char **options;
1082 const char * const kwnames[] = { "url", "flags", "options", NULL };
1083 struct ldb_context *ldb_ctx;
1085 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
1086 discard_const_p(char *, kwnames),
1087 &url, &flags, &py_options))
1090 if (py_options == Py_None) {
1093 options = PyList_AsStringList(NULL, py_options, "options");
1094 if (options == NULL)
1098 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1099 ret = ldb_connect(ldb_ctx, url, flags, options);
1100 talloc_free(options);
1102 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1107 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1110 PyObject *py_controls = Py_None;
1111 struct ldb_context *ldb_ctx;
1112 struct ldb_request *req;
1113 struct ldb_control **parsed_controls;
1114 struct ldb_message *msg;
1116 TALLOC_CTX *mem_ctx;
1118 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1120 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1121 discard_const_p(char *, kwnames),
1122 &py_msg, &py_controls, &validate))
1125 mem_ctx = talloc_new(NULL);
1126 if (mem_ctx == NULL) {
1130 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1132 if (py_controls == Py_None) {
1133 parsed_controls = NULL;
1135 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1136 if (controls == NULL) {
1137 talloc_free(mem_ctx);
1140 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1141 talloc_free(controls);
1144 if (!PyLdbMessage_Check(py_msg)) {
1145 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1146 talloc_free(mem_ctx);
1149 msg = pyldb_Message_AsMessage(py_msg);
1152 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1153 if (ret != LDB_SUCCESS) {
1154 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1155 talloc_free(mem_ctx);
1160 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1161 NULL, ldb_op_default_callback, NULL);
1162 if (ret != LDB_SUCCESS) {
1163 PyErr_SetString(PyExc_TypeError, "failed to build request");
1164 talloc_free(mem_ctx);
1168 /* do request and autostart a transaction */
1169 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1171 ret = ldb_transaction_start(ldb_ctx);
1172 if (ret != LDB_SUCCESS) {
1173 talloc_free(mem_ctx);
1174 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1178 ret = ldb_request(ldb_ctx, req);
1179 if (ret == LDB_SUCCESS) {
1180 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1183 if (ret == LDB_SUCCESS) {
1184 ret = ldb_transaction_commit(ldb_ctx);
1186 ldb_transaction_cancel(ldb_ctx);
1189 talloc_free(mem_ctx);
1190 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1197 * Obtain a ldb message from a Python Dictionary object.
1199 * @param mem_ctx Memory context
1200 * @param py_obj Python Dictionary object
1201 * @param ldb_ctx LDB context
1202 * @param mod_flags Flags to be set on every message element
1203 * @return ldb_message on success or NULL on failure
1205 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1207 struct ldb_context *ldb_ctx,
1208 unsigned int mod_flags)
1210 struct ldb_message *msg;
1211 unsigned int msg_pos = 0;
1212 Py_ssize_t dict_pos = 0;
1213 PyObject *key, *value;
1214 struct ldb_message_element *msg_el;
1215 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1217 msg = ldb_msg_new(mem_ctx);
1222 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1225 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1226 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1229 if (msg->dn == NULL) {
1230 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1234 PyErr_SetString(PyExc_TypeError, "no dn set");
1238 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1239 char *key_str = PyString_AsString(key);
1240 if (ldb_attr_cmp(key_str, "dn") != 0) {
1241 msg_el = PyObject_AsMessageElement(msg->elements, value,
1242 mod_flags, key_str);
1243 if (msg_el == NULL) {
1244 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1247 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1252 msg->num_elements = msg_pos;
1257 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1261 struct ldb_context *ldb_ctx;
1262 struct ldb_request *req;
1263 struct ldb_message *msg = NULL;
1264 PyObject *py_controls = Py_None;
1265 TALLOC_CTX *mem_ctx;
1266 struct ldb_control **parsed_controls;
1267 const char * const kwnames[] = { "message", "controls", NULL };
1269 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1270 discard_const_p(char *, kwnames),
1271 &py_obj, &py_controls))
1274 mem_ctx = talloc_new(NULL);
1275 if (mem_ctx == NULL) {
1279 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1281 if (py_controls == Py_None) {
1282 parsed_controls = NULL;
1284 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1285 if (controls == NULL) {
1286 talloc_free(mem_ctx);
1289 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1290 talloc_free(controls);
1293 if (PyLdbMessage_Check(py_obj)) {
1294 msg = pyldb_Message_AsMessage(py_obj);
1295 } else if (PyDict_Check(py_obj)) {
1296 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1298 PyErr_SetString(PyExc_TypeError,
1299 "Dictionary or LdbMessage object expected!");
1303 /* we should have a PyErr already set */
1304 talloc_free(mem_ctx);
1308 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1309 if (ret != LDB_SUCCESS) {
1310 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1311 talloc_free(mem_ctx);
1315 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1316 NULL, ldb_op_default_callback, NULL);
1317 if (ret != LDB_SUCCESS) {
1318 PyErr_SetString(PyExc_TypeError, "failed to build request");
1319 talloc_free(mem_ctx);
1323 /* do request and autostart a transaction */
1324 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1326 ret = ldb_transaction_start(ldb_ctx);
1327 if (ret != LDB_SUCCESS) {
1328 talloc_free(mem_ctx);
1329 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1333 ret = ldb_request(ldb_ctx, req);
1334 if (ret == LDB_SUCCESS) {
1335 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1338 if (ret == LDB_SUCCESS) {
1339 ret = ldb_transaction_commit(ldb_ctx);
1341 ldb_transaction_cancel(ldb_ctx);
1344 talloc_free(mem_ctx);
1345 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1350 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1355 struct ldb_context *ldb_ctx;
1356 struct ldb_request *req;
1357 PyObject *py_controls = Py_None;
1358 TALLOC_CTX *mem_ctx;
1359 struct ldb_control **parsed_controls;
1360 const char * const kwnames[] = { "dn", "controls", NULL };
1362 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1363 discard_const_p(char *, kwnames),
1364 &py_dn, &py_controls))
1367 mem_ctx = talloc_new(NULL);
1368 if (mem_ctx == NULL) {
1372 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1374 if (py_controls == Py_None) {
1375 parsed_controls = NULL;
1377 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1378 if (controls == NULL) {
1379 talloc_free(mem_ctx);
1382 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1383 talloc_free(controls);
1386 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1387 talloc_free(mem_ctx);
1391 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1392 NULL, ldb_op_default_callback, NULL);
1393 if (ret != LDB_SUCCESS) {
1394 PyErr_SetString(PyExc_TypeError, "failed to build request");
1395 talloc_free(mem_ctx);
1399 /* do request and autostart a transaction */
1400 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1402 ret = ldb_transaction_start(ldb_ctx);
1403 if (ret != LDB_SUCCESS) {
1404 talloc_free(mem_ctx);
1405 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1409 ret = ldb_request(ldb_ctx, req);
1410 if (ret == LDB_SUCCESS) {
1411 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1414 if (ret == LDB_SUCCESS) {
1415 ret = ldb_transaction_commit(ldb_ctx);
1417 ldb_transaction_cancel(ldb_ctx);
1420 talloc_free(mem_ctx);
1421 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1426 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1428 PyObject *py_dn1, *py_dn2;
1429 struct ldb_dn *dn1, *dn2;
1431 TALLOC_CTX *mem_ctx;
1432 PyObject *py_controls = Py_None;
1433 struct ldb_control **parsed_controls;
1434 struct ldb_context *ldb_ctx;
1435 struct ldb_request *req;
1436 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1438 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1440 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1441 discard_const_p(char *, kwnames),
1442 &py_dn1, &py_dn2, &py_controls))
1446 mem_ctx = talloc_new(NULL);
1447 if (mem_ctx == NULL) {
1452 if (py_controls == Py_None) {
1453 parsed_controls = NULL;
1455 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1456 if (controls == NULL) {
1457 talloc_free(mem_ctx);
1460 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1461 talloc_free(controls);
1465 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1466 talloc_free(mem_ctx);
1470 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1471 talloc_free(mem_ctx);
1475 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1476 NULL, ldb_op_default_callback, NULL);
1477 if (ret != LDB_SUCCESS) {
1478 PyErr_SetString(PyExc_TypeError, "failed to build request");
1479 talloc_free(mem_ctx);
1483 /* do request and autostart a transaction */
1484 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1486 ret = ldb_transaction_start(ldb_ctx);
1487 if (ret != LDB_SUCCESS) {
1488 talloc_free(mem_ctx);
1489 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1493 ret = ldb_request(ldb_ctx, req);
1494 if (ret == LDB_SUCCESS) {
1495 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1498 if (ret == LDB_SUCCESS) {
1499 ret = ldb_transaction_commit(ldb_ctx);
1501 ldb_transaction_cancel(ldb_ctx);
1504 talloc_free(mem_ctx);
1505 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1510 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1513 if (!PyArg_ParseTuple(args, "s", &name))
1516 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1521 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1523 char *attribute, *syntax;
1526 struct ldb_context *ldb_ctx;
1528 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1531 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1532 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1534 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1539 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1544 /* We don't want this attached to the 'ldb' any more */
1545 return Py_BuildValue(discard_const_p(char, "(iO)"),
1547 PyLdbMessage_FromMessage(ldif->msg));
1552 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1556 struct ldb_ldif ldif;
1559 TALLOC_CTX *mem_ctx;
1561 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1564 if (!PyLdbMessage_Check(py_msg)) {
1565 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1569 ldif.msg = pyldb_Message_AsMessage(py_msg);
1570 ldif.changetype = changetype;
1572 mem_ctx = talloc_new(NULL);
1574 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1576 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1580 ret = PyString_FromString(string);
1582 talloc_free(mem_ctx);
1587 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1589 PyObject *list, *ret;
1590 struct ldb_ldif *ldif;
1593 TALLOC_CTX *mem_ctx;
1595 if (!PyArg_ParseTuple(args, "s", &s))
1598 mem_ctx = talloc_new(NULL);
1603 list = PyList_New(0);
1604 while (s && *s != '\0') {
1605 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1606 talloc_steal(mem_ctx, ldif);
1608 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1610 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1611 talloc_free(mem_ctx);
1615 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1616 ret = PyObject_GetIter(list);
1621 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1624 PyObject *py_msg_old;
1625 PyObject *py_msg_new;
1626 struct ldb_message *diff;
1627 struct ldb_context *ldb;
1630 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1633 if (!PyLdbMessage_Check(py_msg_old)) {
1634 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1638 if (!PyLdbMessage_Check(py_msg_new)) {
1639 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1643 ldb = pyldb_Ldb_AsLdbContext(self);
1644 ldb_ret = ldb_msg_difference(ldb, ldb,
1645 pyldb_Message_AsMessage(py_msg_old),
1646 pyldb_Message_AsMessage(py_msg_new),
1648 if (ldb_ret != LDB_SUCCESS) {
1649 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1653 py_ret = PyLdbMessage_FromMessage(diff);
1655 talloc_unlink(ldb, diff);
1660 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1662 const struct ldb_schema_attribute *a;
1663 struct ldb_val old_val;
1664 struct ldb_val new_val;
1665 TALLOC_CTX *mem_ctx;
1670 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1673 old_val.data = (uint8_t *)PyString_AsString(val);
1674 old_val.length = PyString_Size(val);
1676 if (old_val.data == NULL) {
1677 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1681 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1687 mem_ctx = talloc_new(NULL);
1688 if (mem_ctx == NULL) {
1693 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1694 talloc_free(mem_ctx);
1698 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1700 talloc_free(mem_ctx);
1705 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1707 PyObject *py_base = Py_None;
1708 int scope = LDB_SCOPE_DEFAULT;
1710 PyObject *py_attrs = Py_None;
1711 PyObject *py_controls = Py_None;
1712 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1714 struct ldb_result *res;
1715 struct ldb_request *req;
1717 struct ldb_context *ldb_ctx;
1718 struct ldb_control **parsed_controls;
1719 struct ldb_dn *base;
1721 TALLOC_CTX *mem_ctx;
1723 /* type "int" rather than "enum" for "scope" is intentional */
1724 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1725 discard_const_p(char *, kwnames),
1726 &py_base, &scope, &expr, &py_attrs, &py_controls))
1730 mem_ctx = talloc_new(NULL);
1731 if (mem_ctx == NULL) {
1735 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1737 if (py_attrs == Py_None) {
1740 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1741 if (attrs == NULL) {
1742 talloc_free(mem_ctx);
1747 if (py_base == Py_None) {
1748 base = ldb_get_default_basedn(ldb_ctx);
1750 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1756 if (py_controls == Py_None) {
1757 parsed_controls = NULL;
1759 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1760 if (controls == NULL) {
1761 talloc_free(mem_ctx);
1764 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1765 talloc_free(controls);
1768 res = talloc_zero(mem_ctx, struct ldb_result);
1771 talloc_free(mem_ctx);
1775 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1782 ldb_search_default_callback,
1785 if (ret != LDB_SUCCESS) {
1786 talloc_free(mem_ctx);
1787 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1791 talloc_steal(req, attrs);
1793 ret = ldb_request(ldb_ctx, req);
1795 if (ret == LDB_SUCCESS) {
1796 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1799 if (ret != LDB_SUCCESS) {
1800 talloc_free(mem_ctx);
1801 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1805 py_ret = PyLdbResult_FromResult(res);
1807 talloc_free(mem_ctx);
1812 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1817 if (!PyArg_ParseTuple(args, "s", &name))
1820 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1825 /* FIXME: More interpretation */
1830 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1835 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1838 /* FIXME: More interpretation */
1840 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1845 static PyObject *py_ldb_modules(PyLdbObject *self)
1847 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1848 PyObject *ret = PyList_New(0);
1849 struct ldb_module *mod;
1851 for (mod = ldb->modules; mod; mod = mod->next) {
1852 PyList_Append(ret, PyLdbModule_FromModule(mod));
1858 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1860 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1864 if (!PyArg_ParseTuple(args, "i", &type))
1867 /* FIXME: More interpretation */
1869 ret = ldb_sequence_number(ldb, type, &value);
1871 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1873 return PyLong_FromLongLong(value);
1875 static PyMethodDef py_ldb_methods[] = {
1876 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1877 "S.set_debug(callback) -> None\n"
1878 "Set callback for LDB debug messages.\n"
1879 "The callback should accept a debug level and debug text." },
1880 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1881 "S.set_create_perms(mode) -> None\n"
1882 "Set mode to use when creating new LDB files." },
1883 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1884 "S.set_modules_dir(path) -> None\n"
1885 "Set path LDB should search for modules" },
1886 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1887 "S.transaction_start() -> None\n"
1888 "Start a new transaction." },
1889 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1890 "S.transaction_prepare_commit() -> None\n"
1891 "prepare to commit a new transaction (2-stage commit)." },
1892 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1893 "S.transaction_commit() -> None\n"
1894 "commit a new transaction." },
1895 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1896 "S.transaction_cancel() -> None\n"
1897 "cancel a new transaction." },
1898 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1900 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1902 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1904 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1906 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1908 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1909 "S.connect(url, flags=0, options=None) -> None\n"
1910 "Connect to a LDB URL." },
1911 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1912 "S.modify(message, controls=None, validate=False) -> None\n"
1913 "Modify an entry." },
1914 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1915 "S.add(message, controls=None) -> None\n"
1917 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1918 "S.delete(dn, controls=None) -> None\n"
1919 "Remove an entry." },
1920 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1921 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1922 "Rename an entry." },
1923 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1924 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1925 "Search in a database.\n"
1927 ":param base: Optional base DN to search\n"
1928 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1929 ":param expression: Optional search expression\n"
1930 ":param attrs: Attributes to return (defaults to all)\n"
1931 ":param controls: Optional list of controls\n"
1932 ":return: Iterator over Message objects\n"
1934 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1936 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1938 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1940 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1941 "S.parse_ldif(ldif) -> iter(messages)\n"
1942 "Parse a string formatted using LDIF." },
1943 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1944 "S.write_ldif(message, changetype) -> ldif\n"
1945 "Print the message as a string formatted using LDIF." },
1946 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1947 "S.msg_diff(Message) -> Message\n"
1948 "Return an LDB Message of the difference between two Message objects." },
1949 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1950 "S.get_opaque(name) -> value\n"
1951 "Get an opaque value set on this LDB connection. \n"
1952 ":note: The returned value may not be useful in Python."
1954 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1955 "S.set_opaque(name, value) -> None\n"
1956 "Set an opaque value on this LDB connection. \n"
1957 ":note: Passing incorrect values may cause crashes." },
1958 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1959 "S.modules() -> list\n"
1960 "Return the list of modules on this LDB connection " },
1961 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1962 "S.sequence_number(type) -> value\n"
1963 "Return the value of the sequence according to the requested type" },
1967 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1969 PyLdbModuleObject *ret;
1971 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1976 ret->mem_ctx = talloc_new(NULL);
1977 ret->mod = talloc_reference(ret->mem_ctx, mod);
1978 return (PyObject *)ret;
1981 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1983 return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1986 static PyGetSetDef py_ldb_getset[] = {
1987 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1991 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1993 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1995 struct ldb_result *result;
1999 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2003 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2005 if (ret != LDB_SUCCESS) {
2006 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2010 count = result->count;
2012 talloc_free(result);
2015 PyErr_Format(PyExc_RuntimeError,
2016 "Searching for [%s] dn gave %u results!",
2017 ldb_dn_get_linearized(dn),
2025 static PySequenceMethods py_ldb_seq = {
2026 .sq_contains = (objobjproc)py_ldb_contains,
2029 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2033 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2038 ret->mem_ctx = talloc_new(NULL);
2039 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2040 return (PyObject *)ret;
2043 static void py_ldb_dealloc(PyLdbObject *self)
2045 talloc_free(self->mem_ctx);
2046 Py_TYPE(self)->tp_free(self);
2049 static PyTypeObject PyLdb = {
2050 .tp_name = "ldb.Ldb",
2051 .tp_methods = py_ldb_methods,
2052 .tp_repr = (reprfunc)py_ldb_repr,
2053 .tp_new = py_ldb_new,
2054 .tp_init = (initproc)py_ldb_init,
2055 .tp_dealloc = (destructor)py_ldb_dealloc,
2056 .tp_getset = py_ldb_getset,
2057 .tp_getattro = PyObject_GenericGetAttr,
2058 .tp_basicsize = sizeof(PyLdbObject),
2059 .tp_doc = "Connection to a LDB database.",
2060 .tp_as_sequence = &py_ldb_seq,
2061 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2064 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2066 talloc_free(self->mem_ctx);
2067 Py_DECREF(self->msgs);
2068 Py_DECREF(self->referals);
2069 Py_DECREF(self->controls);
2070 Py_TYPE(self)->tp_free(self);
2073 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2075 Py_INCREF(self->msgs);
2079 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2081 Py_INCREF(self->controls);
2082 return self->controls;
2085 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2087 Py_INCREF(self->referals);
2088 return self->referals;
2091 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2094 if (self->msgs == NULL) {
2095 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2098 size = PyList_Size(self->msgs);
2099 return PyInt_FromLong(size);
2102 static PyGetSetDef py_ldb_result_getset[] = {
2103 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2104 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2105 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2106 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2110 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2112 return PyObject_GetIter(self->msgs);
2115 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2117 return PySequence_Size(self->msgs);
2120 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2122 return PySequence_GetItem(self->msgs, idx);
2125 static PySequenceMethods py_ldb_result_seq = {
2126 .sq_length = (lenfunc)py_ldb_result_len,
2127 .sq_item = (ssizeargfunc)py_ldb_result_find,
2130 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2132 return PyString_FromFormat("<ldb result>");
2136 static PyTypeObject PyLdbResult = {
2137 .tp_name = "ldb.Result",
2138 .tp_repr = (reprfunc)py_ldb_result_repr,
2139 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2140 .tp_iter = (getiterfunc)py_ldb_result_iter,
2141 .tp_getset = py_ldb_result_getset,
2142 .tp_getattro = PyObject_GenericGetAttr,
2143 .tp_basicsize = sizeof(PyLdbResultObject),
2144 .tp_as_sequence = &py_ldb_result_seq,
2145 .tp_doc = "LDB result.",
2146 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2149 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2151 return PyString_FromFormat("<ldb module '%s'>",
2152 pyldb_Module_AsModule(self)->ops->name);
2155 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2157 return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
2160 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2162 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2166 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2168 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2172 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2174 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2178 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2180 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2182 struct ldb_request *req;
2183 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2184 struct ldb_module *mod;
2185 const char * const*attrs;
2187 /* type "int" rather than "enum" for "scope" is intentional */
2188 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2189 discard_const_p(char *, kwnames),
2190 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2195 if (py_attrs == Py_None) {
2198 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
2203 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2204 scope, NULL /* expr */, attrs,
2205 NULL /* controls */, NULL, NULL, NULL);
2207 talloc_steal(req, attrs);
2209 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2211 req->op.search.res = NULL;
2213 ret = mod->ops->search(mod, req);
2215 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2217 py_ret = PyLdbResult_FromResult(req->op.search.res);
2225 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2227 struct ldb_request *req;
2228 PyObject *py_message;
2230 struct ldb_module *mod;
2232 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2235 req = talloc_zero(NULL, struct ldb_request);
2236 req->operation = LDB_ADD;
2237 req->op.add.message = pyldb_Message_AsMessage(py_message);
2239 mod = pyldb_Module_AsModule(self);
2240 ret = mod->ops->add(mod, req);
2242 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2247 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2250 struct ldb_request *req;
2251 PyObject *py_message;
2252 struct ldb_module *mod;
2254 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2257 req = talloc_zero(NULL, struct ldb_request);
2258 req->operation = LDB_MODIFY;
2259 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2261 mod = pyldb_Module_AsModule(self);
2262 ret = mod->ops->modify(mod, req);
2264 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2269 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2272 struct ldb_request *req;
2275 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2278 req = talloc_zero(NULL, struct ldb_request);
2279 req->operation = LDB_DELETE;
2280 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2282 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2284 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2289 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2292 struct ldb_request *req;
2293 PyObject *py_dn1, *py_dn2;
2295 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2298 req = talloc_zero(NULL, struct ldb_request);
2300 req->operation = LDB_RENAME;
2301 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2302 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2304 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2306 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2311 static PyMethodDef py_ldb_module_methods[] = {
2312 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2313 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2314 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2315 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2316 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2317 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2318 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2319 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2323 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2325 talloc_free(self->mem_ctx);
2329 static PyTypeObject PyLdbModule = {
2330 .tp_name = "ldb.LdbModule",
2331 .tp_methods = py_ldb_module_methods,
2332 .tp_repr = (reprfunc)py_ldb_module_repr,
2333 .tp_str = (reprfunc)py_ldb_module_str,
2334 .tp_basicsize = sizeof(PyLdbModuleObject),
2335 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2336 .tp_flags = Py_TPFLAGS_DEFAULT,
2337 .tp_doc = "LDB module (extension)",
2342 * Create a ldb_message_element from a Python object.
2344 * This will accept any sequence objects that contains strings, or
2347 * A reference to set_obj will be borrowed.
2349 * @param mem_ctx Memory context
2350 * @param set_obj Python object to convert
2351 * @param flags ldb_message_element flags to set
2352 * @param attr_name Name of the attribute
2353 * @return New ldb_message_element, allocated as child of mem_ctx
2355 static struct ldb_message_element *PyObject_AsMessageElement(
2356 TALLOC_CTX *mem_ctx,
2359 const char *attr_name)
2361 struct ldb_message_element *me;
2363 if (pyldb_MessageElement_Check(set_obj)) {
2364 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2365 /* We have to talloc_reference() the memory context, not the pointer
2366 * which may not actually be it's own context */
2367 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2368 return pyldb_MessageElement_AsMessageElement(set_obj);
2373 me = talloc(mem_ctx, struct ldb_message_element);
2379 me->name = talloc_strdup(me, attr_name);
2381 if (PyString_Check(set_obj)) {
2383 me->values = talloc_array(me, struct ldb_val, me->num_values);
2384 me->values[0].length = PyString_Size(set_obj);
2385 me->values[0].data = talloc_memdup(me,
2386 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2387 } else if (PySequence_Check(set_obj)) {
2389 me->num_values = PySequence_Size(set_obj);
2390 me->values = talloc_array(me, struct ldb_val, me->num_values);
2391 for (i = 0; i < me->num_values; i++) {
2392 PyObject *obj = PySequence_GetItem(set_obj, i);
2393 if (!PyString_Check(obj)) {
2394 PyErr_Format(PyExc_TypeError,
2395 "Expected string as element %zd in list", i);
2400 me->values[i].length = PyString_Size(obj);
2401 me->values[i].data = talloc_memdup(me,
2402 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2405 PyErr_Format(PyExc_TypeError,
2406 "String or List type expected for '%s' attribute", attr_name);
2415 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2416 struct ldb_message_element *me)
2421 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2422 result = PyList_New(me->num_values);
2424 for (i = 0; i < me->num_values; i++) {
2425 PyList_SetItem(result, i,
2426 PyObject_FromLdbValue(&me->values[i]));
2432 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2435 if (!PyArg_ParseTuple(args, "I", &i))
2437 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2440 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2443 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2445 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2446 return PyInt_FromLong(el->flags);
2449 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2452 struct ldb_message_element *el;
2453 if (!PyArg_ParseTuple(args, "I", &flags))
2456 el = pyldb_MessageElement_AsMessageElement(self);
2461 static PyMethodDef py_ldb_msg_element_methods[] = {
2462 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2463 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2464 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2468 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2470 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2473 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2475 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2476 if (idx < 0 || idx >= el->num_values) {
2477 PyErr_SetString(PyExc_IndexError, "Out of range");
2480 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2483 static PySequenceMethods py_ldb_msg_element_seq = {
2484 .sq_length = (lenfunc)py_ldb_msg_element_len,
2485 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2488 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
2491 if (!pyldb_MessageElement_Check(other)) {
2492 Py_INCREF(Py_NotImplemented);
2493 return Py_NotImplemented;
2495 ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2496 pyldb_MessageElement_AsMessageElement(other));
2497 return richcmp(ret, op);
2500 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2502 PyObject *el = ldb_msg_element_to_set(NULL,
2503 pyldb_MessageElement_AsMessageElement(self));
2504 PyObject *ret = PyObject_GetIter(el);
2509 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2511 PyLdbMessageElementObject *ret;
2512 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2517 ret->mem_ctx = talloc_new(NULL);
2518 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2523 return (PyObject *)ret;
2526 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2528 PyObject *py_elements = NULL;
2529 struct ldb_message_element *el;
2530 unsigned int flags = 0;
2532 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2533 PyLdbMessageElementObject *ret;
2534 TALLOC_CTX *mem_ctx;
2536 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2537 discard_const_p(char *, kwnames),
2538 &py_elements, &flags, &name))
2541 mem_ctx = talloc_new(NULL);
2542 if (mem_ctx == NULL) {
2547 el = talloc_zero(mem_ctx, struct ldb_message_element);
2550 talloc_free(mem_ctx);
2554 if (py_elements != NULL) {
2556 if (PyString_Check(py_elements)) {
2558 el->values = talloc_array(el, struct ldb_val, 1);
2559 if (el->values == NULL) {
2560 talloc_free(mem_ctx);
2564 el->values[0].length = PyString_Size(py_elements);
2565 el->values[0].data = talloc_memdup(el->values,
2566 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2567 } else if (PySequence_Check(py_elements)) {
2568 el->num_values = PySequence_Size(py_elements);
2569 el->values = talloc_array(el, struct ldb_val, el->num_values);
2570 if (el->values == NULL) {
2571 talloc_free(mem_ctx);
2575 for (i = 0; i < el->num_values; i++) {
2576 PyObject *item = PySequence_GetItem(py_elements, i);
2578 talloc_free(mem_ctx);
2581 if (!PyString_Check(item)) {
2582 PyErr_Format(PyExc_TypeError,
2583 "Expected string as element %zd in list", i);
2584 talloc_free(mem_ctx);
2587 el->values[i].length = PyString_Size(item);
2588 el->values[i].data = talloc_memdup(el,
2589 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2592 PyErr_SetString(PyExc_TypeError,
2593 "Expected string or list");
2594 talloc_free(mem_ctx);
2600 el->name = talloc_strdup(el, name);
2602 ret = PyObject_New(PyLdbMessageElementObject, type);
2604 talloc_free(mem_ctx);
2608 ret->mem_ctx = mem_ctx;
2610 return (PyObject *)ret;
2613 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2615 char *element_str = NULL;
2617 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2618 PyObject *ret, *repr;
2620 for (i = 0; i < el->num_values; i++) {
2621 PyObject *o = py_ldb_msg_element_find(self, i);
2622 repr = PyObject_Repr(o);
2623 if (element_str == NULL)
2624 element_str = talloc_strdup(NULL, PyString_AsString(repr));
2626 element_str = talloc_asprintf_append(element_str, ",%s", PyString_AsString(repr));
2630 if (element_str != NULL) {
2631 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2632 talloc_free(element_str);
2634 ret = PyString_FromString("MessageElement([])");
2640 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2642 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2644 if (el->num_values == 1)
2645 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2650 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2652 talloc_free(self->mem_ctx);
2656 static PyTypeObject PyLdbMessageElement = {
2657 .tp_name = "ldb.MessageElement",
2658 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2659 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2660 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2661 .tp_str = (reprfunc)py_ldb_msg_element_str,
2662 .tp_methods = py_ldb_msg_element_methods,
2663 .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
2664 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2665 .tp_as_sequence = &py_ldb_msg_element_seq,
2666 .tp_new = py_ldb_msg_element_new,
2667 .tp_flags = Py_TPFLAGS_DEFAULT,
2668 .tp_doc = "An element of a Message",
2672 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2677 struct ldb_message *msg;
2678 struct ldb_context *ldb_ctx;
2679 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2681 if (!PyArg_ParseTuple(args, "O!O!|I",
2682 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2687 if (!PyLdb_Check(py_ldb)) {
2688 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
2692 /* mask only flags we are going to use */
2693 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2695 PyErr_SetString(PyExc_ValueError,
2696 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2697 " expected as mod_flag value");
2701 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2703 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2708 py_ret = PyLdbMessage_FromMessage(msg);
2710 talloc_unlink(ldb_ctx, msg);
2715 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2718 if (!PyArg_ParseTuple(args, "s", &name))
2721 ldb_msg_remove_attr(self->msg, name);
2726 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2728 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2729 Py_ssize_t i, j = 0;
2730 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2731 if (msg->dn != NULL) {
2732 PyList_SetItem(obj, j, PyString_FromString("dn"));
2735 for (i = 0; i < msg->num_elements; i++) {
2736 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2742 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2744 struct ldb_message_element *el;
2746 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2747 if (!PyString_Check(py_name)) {
2748 PyErr_SetNone(PyExc_TypeError);
2751 name = PyString_AsString(py_name);
2752 if (!ldb_attr_cmp(name, "dn"))
2753 return pyldb_Dn_FromDn(msg->dn);
2754 el = ldb_msg_find_element(msg, name);
2758 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2761 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2763 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2765 PyErr_SetString(PyExc_KeyError, "No such element");
2771 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2773 PyObject *def = NULL;
2774 const char *kwnames[] = { "name", "default", "idx", NULL };
2775 const char *name = NULL;
2777 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2778 struct ldb_message_element *el;
2780 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2781 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2785 if (strcasecmp(name, "dn") == 0) {
2786 return pyldb_Dn_FromDn(msg->dn);
2789 el = ldb_msg_find_element(msg, name);
2791 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2800 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2803 return PyObject_FromLdbValue(&el->values[idx]);
2806 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2808 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2809 Py_ssize_t i, j = 0;
2810 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2811 if (msg->dn != NULL) {
2812 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2815 for (i = 0; i < msg->num_elements; i++, j++) {
2816 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2817 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2818 PyList_SetItem(l, j, value);
2823 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2825 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2827 PyObject *l = PyList_New(msg->num_elements);
2828 for (i = 0; i < msg->num_elements; i++) {
2829 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2834 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2836 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2837 PyLdbMessageElementObject *py_element;
2839 struct ldb_message_element *el;
2840 struct ldb_message_element *el_new;
2842 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2845 el = py_element->el;
2847 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
2851 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
2852 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2854 /* now deep copy all attribute values */
2855 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
2856 if (el_new->values == NULL) {
2860 el_new->num_values = el->num_values;
2862 for (i = 0; i < el->num_values; i++) {
2863 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
2864 if (el_new->values[i].data == NULL
2865 && el->values[i].length != 0) {
2874 static PyMethodDef py_ldb_msg_methods[] = {
2875 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2876 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2877 "Class method to create ldb.Message object from Dictionary.\n"
2878 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2879 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2880 "S.keys() -> list\n\n"
2881 "Return sequence of all attribute names." },
2882 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2883 "S.remove(name)\n\n"
2884 "Remove all entries for attributes with the specified name."},
2885 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2886 "msg.get(name,default=None,idx=None) -> string\n"
2887 "idx is the index into the values array\n"
2888 "if idx is None, then a list is returned\n"
2889 "if idx is not None, then the element with that index is returned\n"
2890 "if you pass the special name 'dn' then the DN object is returned\n"},
2891 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2892 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2893 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2894 "S.add(element)\n\n"
2895 "Add an element to this message." },
2899 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2901 PyObject *list, *iter;
2903 list = py_ldb_msg_keys(self);
2904 iter = PyObject_GetIter(list);
2909 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2913 if (!PyString_Check(name)) {
2914 PyErr_SetNone(PyExc_TypeError);
2918 attr_name = PyString_AsString(name);
2919 if (value == NULL) {
2921 ldb_msg_remove_attr(self->msg, attr_name);
2924 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2925 value, 0, attr_name);
2929 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2930 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2931 if (ret != LDB_SUCCESS) {
2932 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
2939 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2941 return pyldb_Message_AsMessage(self)->num_elements;
2944 static PyMappingMethods py_ldb_msg_mapping = {
2945 .mp_length = (lenfunc)py_ldb_msg_length,
2946 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2947 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2950 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2952 const char * const kwnames[] = { "dn", NULL };
2953 struct ldb_message *ret;
2954 TALLOC_CTX *mem_ctx;
2955 PyObject *pydn = NULL;
2956 PyLdbMessageObject *py_ret;
2958 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2959 discard_const_p(char *, kwnames),
2963 mem_ctx = talloc_new(NULL);
2964 if (mem_ctx == NULL) {
2969 ret = ldb_msg_new(mem_ctx);
2971 talloc_free(mem_ctx);
2978 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2979 talloc_free(mem_ctx);
2982 ret->dn = talloc_reference(ret, dn);
2985 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2986 if (py_ret == NULL) {
2988 talloc_free(mem_ctx);
2992 py_ret->mem_ctx = mem_ctx;
2994 return (PyObject *)py_ret;
2997 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2999 PyLdbMessageObject *ret;
3001 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3006 ret->mem_ctx = talloc_new(NULL);
3007 ret->msg = talloc_reference(ret->mem_ctx, msg);
3008 return (PyObject *)ret;
3011 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3013 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3014 return pyldb_Dn_FromDn(msg->dn);
3017 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3019 struct ldb_message *msg = pyldb_Message_AsMessage(self);
3020 if (!pyldb_Dn_Check(value)) {
3021 PyErr_SetString(PyExc_TypeError, "expected dn");
3025 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3029 static PyGetSetDef py_ldb_msg_getset[] = {
3030 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
3034 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3036 PyObject *dict = PyDict_New(), *ret, *repr;
3037 if (PyDict_Update(dict, (PyObject *)self) != 0)
3039 repr = PyObject_Repr(dict);
3044 ret = PyString_FromFormat("Message(%s)", PyString_AsString(repr));
3050 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3052 talloc_free(self->mem_ctx);
3056 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3057 PyLdbMessageObject *py_msg2, int op)
3059 struct ldb_message *msg1, *msg2;
3063 if (!PyLdbMessage_Check(py_msg2)) {
3064 Py_INCREF(Py_NotImplemented);
3065 return Py_NotImplemented;
3068 msg1 = pyldb_Message_AsMessage(py_msg1),
3069 msg2 = pyldb_Message_AsMessage(py_msg2);
3071 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3072 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3074 return richcmp(ret, op);
3078 ret = msg1->num_elements - msg2->num_elements;
3080 return richcmp(ret, op);
3083 for (i = 0; i < msg1->num_elements; i++) {
3084 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3085 &msg2->elements[i]);
3087 return richcmp(ret, op);
3090 ret = ldb_msg_element_compare(&msg1->elements[i],
3091 &msg2->elements[i]);
3093 return richcmp(ret, op);
3097 return richcmp(0, op);
3100 static PyTypeObject PyLdbMessage = {
3101 .tp_name = "ldb.Message",
3102 .tp_methods = py_ldb_msg_methods,
3103 .tp_getset = py_ldb_msg_getset,
3104 .tp_as_mapping = &py_ldb_msg_mapping,
3105 .tp_basicsize = sizeof(PyLdbMessageObject),
3106 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3107 .tp_new = py_ldb_msg_new,
3108 .tp_repr = (reprfunc)py_ldb_msg_repr,
3109 .tp_flags = Py_TPFLAGS_DEFAULT,
3110 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3111 .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3112 .tp_doc = "A LDB Message",
3115 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3117 PyLdbTreeObject *ret;
3119 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3125 ret->mem_ctx = talloc_new(NULL);
3126 ret->tree = talloc_reference(ret->mem_ctx, tree);
3127 return (PyObject *)ret;
3130 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3132 talloc_free(self->mem_ctx);
3136 static PyTypeObject PyLdbTree = {
3137 .tp_name = "ldb.Tree",
3138 .tp_basicsize = sizeof(PyLdbTreeObject),
3139 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3140 .tp_flags = Py_TPFLAGS_DEFAULT,
3141 .tp_doc = "A search tree",
3145 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3147 PyObject *py_ldb = (PyObject *)mod->private_data;
3148 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3150 py_base = pyldb_Dn_FromDn(req->op.search.base);
3152 if (py_base == NULL)
3153 return LDB_ERR_OPERATIONS_ERROR;
3155 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3157 if (py_tree == NULL)
3158 return LDB_ERR_OPERATIONS_ERROR;
3160 if (req->op.search.attrs == NULL) {
3164 for (len = 0; req->op.search.attrs[len]; len++);
3165 py_attrs = PyList_New(len);
3166 for (i = 0; i < len; i++)
3167 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
3170 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3171 discard_const_p(char, "OiOO"),
3172 py_base, req->op.search.scope, py_tree, py_attrs);
3174 Py_DECREF(py_attrs);
3178 if (py_result == NULL) {
3179 return LDB_ERR_PYTHON_EXCEPTION;
3182 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3183 if (req->op.search.res == NULL) {
3184 return LDB_ERR_PYTHON_EXCEPTION;
3187 Py_DECREF(py_result);
3192 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3194 PyObject *py_ldb = (PyObject *)mod->private_data;
3195 PyObject *py_result, *py_msg;
3197 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3199 if (py_msg == NULL) {
3200 return LDB_ERR_OPERATIONS_ERROR;
3203 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3204 discard_const_p(char, "O"),
3209 if (py_result == NULL) {
3210 return LDB_ERR_PYTHON_EXCEPTION;
3213 Py_DECREF(py_result);
3218 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3220 PyObject *py_ldb = (PyObject *)mod->private_data;
3221 PyObject *py_result, *py_msg;
3223 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3225 if (py_msg == NULL) {
3226 return LDB_ERR_OPERATIONS_ERROR;
3229 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3230 discard_const_p(char, "O"),
3235 if (py_result == NULL) {
3236 return LDB_ERR_PYTHON_EXCEPTION;
3239 Py_DECREF(py_result);
3244 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3246 PyObject *py_ldb = (PyObject *)mod->private_data;
3247 PyObject *py_result, *py_dn;
3249 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3252 return LDB_ERR_OPERATIONS_ERROR;
3254 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3255 discard_const_p(char, "O"),
3258 if (py_result == NULL) {
3259 return LDB_ERR_PYTHON_EXCEPTION;
3262 Py_DECREF(py_result);
3267 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3269 PyObject *py_ldb = (PyObject *)mod->private_data;
3270 PyObject *py_result, *py_olddn, *py_newdn;
3272 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3274 if (py_olddn == NULL)
3275 return LDB_ERR_OPERATIONS_ERROR;
3277 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3279 if (py_newdn == NULL)
3280 return LDB_ERR_OPERATIONS_ERROR;
3282 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3283 discard_const_p(char, "OO"),
3284 py_olddn, py_newdn);
3286 Py_DECREF(py_olddn);
3287 Py_DECREF(py_newdn);
3289 if (py_result == NULL) {
3290 return LDB_ERR_PYTHON_EXCEPTION;
3293 Py_DECREF(py_result);
3298 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3300 PyObject *py_ldb = (PyObject *)mod->private_data;
3301 PyObject *py_result;
3303 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3304 discard_const_p(char, ""));
3306 Py_XDECREF(py_result);
3308 return LDB_ERR_OPERATIONS_ERROR;
3311 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3313 PyObject *py_ldb = (PyObject *)mod->private_data;
3314 PyObject *py_result;
3316 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3317 discard_const_p(char, ""));
3319 Py_XDECREF(py_result);
3321 return LDB_ERR_OPERATIONS_ERROR;
3324 static int py_module_start_transaction(struct ldb_module *mod)
3326 PyObject *py_ldb = (PyObject *)mod->private_data;
3327 PyObject *py_result;
3329 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3330 discard_const_p(char, ""));
3332 if (py_result == NULL) {
3333 return LDB_ERR_PYTHON_EXCEPTION;
3336 Py_DECREF(py_result);
3341 static int py_module_end_transaction(struct ldb_module *mod)
3343 PyObject *py_ldb = (PyObject *)mod->private_data;
3344 PyObject *py_result;
3346 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3347 discard_const_p(char, ""));
3349 if (py_result == NULL) {
3350 return LDB_ERR_PYTHON_EXCEPTION;
3353 Py_DECREF(py_result);
3358 static int py_module_del_transaction(struct ldb_module *mod)
3360 PyObject *py_ldb = (PyObject *)mod->private_data;
3361 PyObject *py_result;
3363 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3364 discard_const_p(char, ""));
3366 if (py_result == NULL) {
3367 return LDB_ERR_PYTHON_EXCEPTION;
3370 Py_DECREF(py_result);
3375 static int py_module_destructor(struct ldb_module *mod)
3377 Py_DECREF((PyObject *)mod->private_data);
3381 static int py_module_init(struct ldb_module *mod)
3383 PyObject *py_class = (PyObject *)mod->ops->private_data;
3384 PyObject *py_result, *py_next, *py_ldb;
3386 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3389 return LDB_ERR_OPERATIONS_ERROR;
3391 py_next = PyLdbModule_FromModule(mod->next);
3393 if (py_next == NULL)
3394 return LDB_ERR_OPERATIONS_ERROR;
3396 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3399 if (py_result == NULL) {
3400 return LDB_ERR_PYTHON_EXCEPTION;
3403 mod->private_data = py_result;
3405 talloc_set_destructor(mod, py_module_destructor);
3407 return ldb_next_init(mod);
3410 static PyObject *py_register_module(PyObject *module, PyObject *args)
3413 struct ldb_module_ops *ops;
3416 if (!PyArg_ParseTuple(args, "O", &input))
3419 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3425 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3428 ops->private_data = input;
3429 ops->init_context = py_module_init;
3430 ops->search = py_module_search;
3431 ops->add = py_module_add;
3432 ops->modify = py_module_modify;
3433 ops->del = py_module_del;
3434 ops->rename = py_module_rename;
3435 ops->request = py_module_request;
3436 ops->extended = py_module_extended;
3437 ops->start_transaction = py_module_start_transaction;
3438 ops->end_transaction = py_module_end_transaction;
3439 ops->del_transaction = py_module_del_transaction;
3441 ret = ldb_register_module(ops);
3443 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3448 static PyObject *py_timestring(PyObject *module, PyObject *args)
3450 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3451 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3455 if (!PyArg_ParseTuple(args, "l", &t_val))
3457 tresult = ldb_timestring(NULL, (time_t) t_val);
3458 ret = PyString_FromString(tresult);
3459 talloc_free(tresult);
3463 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3466 if (!PyArg_ParseTuple(args, "s", &str))
3469 return PyInt_FromLong(ldb_string_to_time(str));
3472 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3475 if (!PyArg_ParseTuple(args, "s", &name))
3477 return PyBool_FromLong(ldb_valid_attr_name(name));
3481 encode a string using RFC2254 rules
3483 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3485 char *str, *encoded;
3490 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3492 val.data = (uint8_t *)str;
3495 encoded = ldb_binary_encode(NULL, val);
3496 if (encoded == NULL) {
3497 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3500 ret = PyString_FromString(encoded);
3501 talloc_free(encoded);
3506 decode a string using RFC2254 rules
3508 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3514 if (!PyArg_ParseTuple(args, "s", &str))
3517 val = ldb_binary_decode(NULL, str);
3518 if (val.data == NULL) {
3519 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3522 ret = Py_BuildValue("s#", val.data, val.length);
3523 talloc_free(val.data);
3527 static PyMethodDef py_ldb_global_methods[] = {
3528 { "register_module", py_register_module, METH_VARARGS,
3529 "S.register_module(module) -> None\n\n"
3530 "Register a LDB module."},
3531 { "timestring", py_timestring, METH_VARARGS,
3532 "S.timestring(int) -> string\n\n"
3533 "Generate a LDAP time string from a UNIX timestamp" },
3534 { "string_to_time", py_string_to_time, METH_VARARGS,
3535 "S.string_to_time(string) -> int\n\n"
3536 "Parse a LDAP time string into a UNIX timestamp." },
3537 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3538 "S.valid_attr_name(name) -> bool\n\nn"
3539 "Check whether the supplied name is a valid attribute name." },
3540 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3541 "S.open() -> Ldb\n\n"
3542 "Open a new LDB context." },
3543 { "binary_encode", py_binary_encode, METH_VARARGS,
3544 "S.binary_encode(string) -> string\n\n"
3545 "Perform a RFC2254 binary encoding on a string" },
3546 { "binary_decode", py_binary_decode, METH_VARARGS,
3547 "S.binary_decode(string) -> string\n\n"
3548 "Perform a RFC2254 binary decode on a string" },
3552 #define MODULE_DOC "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server."
3554 #if PY_MAJOR_VERSION >= 3
3555 static struct PyModuleDef moduledef = {
3556 PyModuleDef_HEAD_INIT,
3558 .m_doc = MODULE_DOC,
3560 .m_methods = py_ldb_global_methods,
3564 static PyObject* module_init(void)
3568 if (PyType_Ready(&PyLdbDn) < 0)
3571 if (PyType_Ready(&PyLdbMessage) < 0)
3574 if (PyType_Ready(&PyLdbMessageElement) < 0)
3577 if (PyType_Ready(&PyLdb) < 0)
3580 if (PyType_Ready(&PyLdbModule) < 0)
3583 if (PyType_Ready(&PyLdbTree) < 0)
3586 if (PyType_Ready(&PyLdbResult) < 0)
3589 if (PyType_Ready(&PyLdbControl) < 0)
3592 #if PY_MAJOR_VERSION >= 3
3593 m = PyModule_Create(&moduledef);
3595 m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC);
3600 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
3602 ADD_LDB_INT(SEQ_HIGHEST_SEQ);
3603 ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
3604 ADD_LDB_INT(SEQ_NEXT);
3605 ADD_LDB_INT(SCOPE_DEFAULT);
3606 ADD_LDB_INT(SCOPE_BASE);
3607 ADD_LDB_INT(SCOPE_ONELEVEL);
3608 ADD_LDB_INT(SCOPE_SUBTREE);
3610 ADD_LDB_INT(CHANGETYPE_NONE);
3611 ADD_LDB_INT(CHANGETYPE_ADD);
3612 ADD_LDB_INT(CHANGETYPE_DELETE);
3613 ADD_LDB_INT(CHANGETYPE_MODIFY);
3615 ADD_LDB_INT(FLAG_MOD_ADD);
3616 ADD_LDB_INT(FLAG_MOD_REPLACE);
3617 ADD_LDB_INT(FLAG_MOD_DELETE);
3619 ADD_LDB_INT(SUCCESS);
3620 ADD_LDB_INT(ERR_OPERATIONS_ERROR);
3621 ADD_LDB_INT(ERR_PROTOCOL_ERROR);
3622 ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
3623 ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
3624 ADD_LDB_INT(ERR_COMPARE_FALSE);
3625 ADD_LDB_INT(ERR_COMPARE_TRUE);
3626 ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
3627 ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
3628 ADD_LDB_INT(ERR_REFERRAL);
3629 ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
3630 ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
3631 ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
3632 ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
3633 ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
3634 ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
3635 ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
3636 ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
3637 ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
3638 ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
3639 ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
3640 ADD_LDB_INT(ERR_ALIAS_PROBLEM);
3641 ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
3642 ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
3643 ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
3644 ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
3645 ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
3646 ADD_LDB_INT(ERR_BUSY);
3647 ADD_LDB_INT(ERR_UNAVAILABLE);
3648 ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
3649 ADD_LDB_INT(ERR_LOOP_DETECT);
3650 ADD_LDB_INT(ERR_NAMING_VIOLATION);
3651 ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
3652 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
3653 ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
3654 ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
3655 ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
3656 ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
3657 ADD_LDB_INT(ERR_OTHER);
3659 ADD_LDB_INT(FLG_RDONLY);
3660 ADD_LDB_INT(FLG_NOSYNC);
3661 ADD_LDB_INT(FLG_RECONNECT);
3662 ADD_LDB_INT(FLG_NOMMAP);
3664 /* Historical misspelling */
3665 PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
3667 PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
3669 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3670 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3673 Py_INCREF(&PyLdbDn);
3674 Py_INCREF(&PyLdbModule);
3675 Py_INCREF(&PyLdbMessage);
3676 Py_INCREF(&PyLdbMessageElement);
3677 Py_INCREF(&PyLdbTree);
3678 Py_INCREF(&PyLdbResult);
3679 Py_INCREF(&PyLdbControl);
3681 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3682 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3683 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3684 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3685 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3686 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3687 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3689 PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
3691 #define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
3693 ADD_LDB_STRING(SYNTAX_DN);
3694 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3695 ADD_LDB_STRING(SYNTAX_INTEGER);
3696 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3697 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3698 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3699 ADD_LDB_STRING(OID_COMPARATOR_AND);
3700 ADD_LDB_STRING(OID_COMPARATOR_OR);
3705 #if PY_MAJOR_VERSION >= 3
3706 PyMODINIT_FUNC PyInit_ldb(void);
3707 PyMODINIT_FUNC PyInit_ldb(void)
3709 return module_init();