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 staticforward PyTypeObject PyLdbControl;
40 staticforward PyTypeObject PyLdbResult;
41 staticforward PyTypeObject PyLdbMessage;
42 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
43 staticforward PyTypeObject PyLdbModule;
44 staticforward PyTypeObject PyLdbDn;
45 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
46 staticforward PyTypeObject PyLdb;
47 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
48 staticforward PyTypeObject PyLdbMessageElement;
49 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
51 staticforward 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 #ifndef Py_RETURN_NONE
68 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
71 #define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
75 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
77 if (self->data != NULL) {
78 char* control = ldb_control_to_string(self->mem_ctx, self->data);
79 if (control == NULL) {
83 return PyString_FromString(control);
85 return PyString_FromFormat("ldb control");
89 static void py_ldb_control_dealloc(PyLdbControlObject *self)
91 if (self->mem_ctx != NULL) {
92 talloc_free(self->mem_ctx);
95 self->ob_type->tp_free(self);
98 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
100 return PyString_FromString(self->data->oid);
103 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
105 return PyBool_FromLong(self->data->critical);
108 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
110 if (PyObject_IsTrue(value)) {
111 self->data->critical = true;
113 self->data->critical = false;
118 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
121 const char * const kwnames[] = { "ldb", "data", NULL };
122 struct ldb_control *parsed_controls;
123 PyLdbControlObject *ret;
126 struct ldb_context *ldb_ctx;
128 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
129 discard_const_p(char *, kwnames),
133 mem_ctx = talloc_new(NULL);
134 if (mem_ctx == NULL) {
139 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
140 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
142 if (!parsed_controls) {
143 talloc_free(mem_ctx);
144 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
148 ret = PyObject_New(PyLdbControlObject, type);
151 talloc_free(mem_ctx);
155 ret->mem_ctx = mem_ctx;
157 ret->data = talloc_move(mem_ctx, &parsed_controls);
158 if (ret->data == NULL) {
161 talloc_free(mem_ctx);
165 return (PyObject *)ret;
168 static PyGetSetDef py_ldb_control_getset[] = {
169 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
170 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
174 static PyTypeObject PyLdbControl = {
175 .tp_name = "ldb.control",
176 .tp_dealloc = (destructor)py_ldb_control_dealloc,
177 .tp_getattro = PyObject_GenericGetAttr,
178 .tp_basicsize = sizeof(PyLdbControlObject),
179 .tp_getset = py_ldb_control_getset,
180 .tp_doc = "LDB control.",
181 .tp_str = (reprfunc)py_ldb_control_str,
182 .tp_new = py_ldb_control_new,
183 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
186 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
188 if (ret == LDB_ERR_PYTHON_EXCEPTION)
189 return; /* Python exception should already be set, just keep that */
191 PyErr_SetObject(error,
192 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
193 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
196 static PyObject *PyObject_FromLdbValue(struct ldb_val *val)
198 return PyString_FromStringAndSize((const char *)val->data, val->length);
202 * Create a Python object from a ldb_result.
204 * @param result LDB result to convert
205 * @return Python object with converted result (a list object)
207 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
209 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
210 PyLdbControlObject *ctrl;
211 if (ctl_ctx == NULL) {
216 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
218 talloc_free(ctl_ctx);
222 ctrl->mem_ctx = ctl_ctx;
223 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
224 if (ctrl->data == NULL) {
229 return (PyObject*) ctrl;
233 * Create a Python object from a ldb_result.
235 * @param result LDB result to convert
236 * @return Python object with converted result (a list object)
238 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
240 PyLdbResultObject *ret;
241 PyObject *list, *controls, *referals;
244 if (result == NULL) {
248 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
254 list = PyList_New(result->count);
261 for (i = 0; i < result->count; i++) {
262 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
265 ret->mem_ctx = talloc_new(NULL);
266 if (ret->mem_ctx == NULL) {
275 if (result->controls) {
276 controls = PyList_New(1);
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 ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
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 ldb_dn_add_child(dn, other)?Py_True:Py_False;
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 ldb_dn_add_base(dn, other)?Py_True:Py_False;
532 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
535 struct ldb_dn *dn, *base;
536 if (!PyArg_ParseTuple(args, "O", &py_base))
539 dn = pyldb_Dn_AsDn((PyObject *)self);
541 if (!pyldb_Object_AsDn(NULL, py_base, dn_ldb_ctx(dn), &base))
544 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
547 static PyMethodDef py_ldb_dn_methods[] = {
548 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
549 "S.validate() -> bool\n"
550 "Validate DN is correct." },
551 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
552 "S.is_valid() -> bool\n" },
553 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
554 "S.is_special() -> bool\n"
555 "Check whether this is a special LDB DN." },
556 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
557 "Check whether this is a null DN." },
558 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
560 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
562 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
563 "S.canonical_str() -> string\n"
564 "Canonical version of this DN (like a posix path)." },
565 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
566 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
567 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
568 "S.canonical_ex_str() -> string\n"
569 "Canonical version of this DN (like a posix path, with terminating newline)." },
570 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
571 "S.extended_str(mode=1) -> string\n"
572 "Extended version of this DN" },
573 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
575 "Get the parent for this DN." },
576 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
577 "S.add_child(dn) -> None\n"
578 "Add a child DN to this DN." },
579 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
580 "S.add_base(dn) -> None\n"
581 "Add a base DN to this DN." },
582 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
583 "S.check_special(name) -> bool\n\n"
584 "Check if name is a special DN name"},
585 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
586 "S.get_extended_component(name) -> string\n\n"
587 "returns a DN extended component as a binary string"},
588 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
589 "S.set_extended_component(name, value) -> string\n\n"
590 "set a DN extended component as a binary string"},
594 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
596 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
600 copy a DN as a python object
602 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
604 PyLdbDnObject *py_ret;
606 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
607 if (py_ret == NULL) {
611 py_ret->mem_ctx = talloc_new(NULL);
612 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
613 return (PyObject *)py_ret;
616 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
618 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
620 PyLdbDnObject *py_ret;
622 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
625 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
626 if (py_ret == NULL) {
630 py_ret->mem_ctx = talloc_new(NULL);
631 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
632 ldb_dn_add_child(py_ret->dn, other);
633 return (PyObject *)py_ret;
636 static PySequenceMethods py_ldb_dn_seq = {
637 .sq_length = (lenfunc)py_ldb_dn_len,
638 .sq_concat = (binaryfunc)py_ldb_dn_concat,
641 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
646 struct ldb_context *ldb_ctx;
648 PyLdbDnObject *py_ret;
649 const char * const kwnames[] = { "ldb", "dn", NULL };
651 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
652 discard_const_p(char *, kwnames),
656 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
658 mem_ctx = talloc_new(NULL);
659 if (mem_ctx == NULL) {
664 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
665 if (!ldb_dn_validate(ret)) {
666 talloc_free(mem_ctx);
667 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
671 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
673 talloc_free(mem_ctx);
677 py_ret->mem_ctx = mem_ctx;
679 return (PyObject *)py_ret;
682 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
684 talloc_free(self->mem_ctx);
688 static PyTypeObject PyLdbDn = {
690 .tp_methods = py_ldb_dn_methods,
691 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
692 .tp_repr = (reprfunc)py_ldb_dn_repr,
693 .tp_compare = (cmpfunc)py_ldb_dn_compare,
694 .tp_as_sequence = &py_ldb_dn_seq,
695 .tp_doc = "A LDB distinguished name.",
696 .tp_new = py_ldb_dn_new,
697 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
698 .tp_basicsize = sizeof(PyLdbDnObject),
699 .tp_flags = Py_TPFLAGS_DEFAULT,
703 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
704 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
706 PyObject *fn = (PyObject *)context;
707 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
710 static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args)
714 if (!PyArg_ParseTuple(args, "O", &cb))
718 /* FIXME: Where do we DECREF cb ? */
719 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), pyldb_Ldb_AsLdbContext(self));
724 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
727 if (!PyArg_ParseTuple(args, "I", &perms))
730 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
735 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
738 if (!PyArg_ParseTuple(args, "s", &modules_dir))
741 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
746 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
748 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_start(pyldb_Ldb_AsLdbContext(self)), pyldb_Ldb_AsLdbContext(self));
752 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
754 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(pyldb_Ldb_AsLdbContext(self)), pyldb_Ldb_AsLdbContext(self));
758 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
760 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_prepare_commit(pyldb_Ldb_AsLdbContext(self)), pyldb_Ldb_AsLdbContext(self));
764 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
766 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_cancel(pyldb_Ldb_AsLdbContext(self)), pyldb_Ldb_AsLdbContext(self));
770 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
772 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_setup_wellknown_attributes(pyldb_Ldb_AsLdbContext(self)), pyldb_Ldb_AsLdbContext(self));
776 static PyObject *py_ldb_repr(PyLdbObject *self)
778 return PyString_FromFormat("<ldb connection>");
781 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
783 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
786 return py_ldb_dn_copy(dn);
790 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
792 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
795 return py_ldb_dn_copy(dn);
798 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
800 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
803 return py_ldb_dn_copy(dn);
806 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
808 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
811 return py_ldb_dn_copy(dn);
814 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
815 const char *paramname)
819 if (!PyList_Check(list)) {
820 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
823 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
829 for (i = 0; i < PyList_Size(list); i++) {
830 PyObject *item = PyList_GetItem(list, i);
831 if (!PyString_Check(item)) {
832 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
835 ret[i] = talloc_strndup(ret, PyString_AsString(item),
836 PyString_Size(item));
842 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
844 const char * const kwnames[] = { "url", "flags", "options", NULL };
846 PyObject *py_options = Py_None;
847 const char **options;
848 unsigned int flags = 0;
850 struct ldb_context *ldb;
852 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
853 discard_const_p(char *, kwnames),
854 &url, &flags, &py_options))
857 ldb = pyldb_Ldb_AsLdbContext(self);
859 if (py_options == Py_None) {
862 options = PyList_AsStringList(ldb, py_options, "options");
868 ret = ldb_connect(ldb, url, flags, options);
869 if (ret != LDB_SUCCESS) {
870 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
875 talloc_free(options);
879 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
882 struct ldb_context *ldb;
883 ret = (PyLdbObject *)type->tp_alloc(type, 0);
888 ret->mem_ctx = talloc_new(NULL);
889 ldb = ldb_init(ret->mem_ctx, NULL);
897 return (PyObject *)ret;
900 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
903 unsigned int flags = 0;
904 PyObject *py_options = Py_None;
906 const char **options;
907 const char * const kwnames[] = { "url", "flags", "options", NULL };
909 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
910 discard_const_p(char *, kwnames),
911 &url, &flags, &py_options))
914 if (py_options == Py_None) {
917 options = PyList_AsStringList(NULL, py_options, "options");
922 ret = ldb_connect(pyldb_Ldb_AsLdbContext(self), url, flags, options);
923 talloc_free(options);
925 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, pyldb_Ldb_AsLdbContext(self));
930 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
933 PyObject *py_controls = Py_None;
934 struct ldb_context *ldb_ctx;
935 struct ldb_request *req;
936 struct ldb_control **parsed_controls;
937 struct ldb_message *msg;
941 const char * const kwnames[] = { "message", "controls", "validate", NULL };
943 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
944 discard_const_p(char *, kwnames),
945 &py_msg, &py_controls, &validate))
948 mem_ctx = talloc_new(NULL);
949 if (mem_ctx == NULL) {
953 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
955 if (py_controls == Py_None) {
956 parsed_controls = NULL;
958 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
959 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
960 talloc_free(controls);
963 if (!PyLdbMessage_Check(py_msg)) {
964 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
965 talloc_free(mem_ctx);
968 msg = pyldb_Message_AsMessage(py_msg);
971 ret = ldb_msg_sanity_check(ldb_ctx, msg);
972 if (ret != LDB_SUCCESS) {
973 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
974 talloc_free(mem_ctx);
979 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
980 NULL, ldb_op_default_callback, NULL);
981 if (ret != LDB_SUCCESS) {
982 PyErr_SetString(PyExc_TypeError, "failed to build request");
983 talloc_free(mem_ctx);
987 /* do request and autostart a transaction */
988 /* Then let's LDB handle the message error in case of pb as they are meaningful */
990 ret = ldb_transaction_start(ldb_ctx);
991 if (ret != LDB_SUCCESS) {
992 talloc_free(mem_ctx);
993 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
996 ret = ldb_request(ldb_ctx, req);
997 if (ret == LDB_SUCCESS) {
998 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1001 if (ret == LDB_SUCCESS) {
1002 ret = ldb_transaction_commit(ldb_ctx);
1004 ldb_transaction_cancel(ldb_ctx);
1007 talloc_free(mem_ctx);
1008 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1015 * Obtain a ldb message from a Python Dictionary object.
1017 * @param mem_ctx Memory context
1018 * @param py_obj Python Dictionary object
1019 * @param ldb_ctx LDB context
1020 * @param mod_flags Flags to be set on every message element
1021 * @return ldb_message on success or NULL on failure
1023 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1025 struct ldb_context *ldb_ctx,
1026 unsigned int mod_flags)
1028 struct ldb_message *msg;
1029 unsigned int msg_pos = 0;
1030 Py_ssize_t dict_pos = 0;
1031 PyObject *key, *value;
1032 struct ldb_message_element *msg_el;
1033 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1035 msg = ldb_msg_new(mem_ctx);
1036 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1039 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1040 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1043 if (msg->dn == NULL) {
1044 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1048 PyErr_SetString(PyExc_TypeError, "no dn set");
1052 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1053 char *key_str = PyString_AsString(key);
1054 if (strcmp(key_str, "dn") != 0) {
1055 msg_el = PyObject_AsMessageElement(msg->elements, value,
1056 mod_flags, key_str);
1057 if (msg_el == NULL) {
1058 PyErr_SetString(PyExc_TypeError, "unable to import element");
1061 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1066 msg->num_elements = msg_pos;
1071 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1075 struct ldb_context *ldb_ctx;
1076 struct ldb_request *req;
1077 struct ldb_message *msg = NULL;
1078 PyObject *py_controls = Py_None;
1079 TALLOC_CTX *mem_ctx;
1080 struct ldb_control **parsed_controls;
1081 const char * const kwnames[] = { "message", "controls", NULL };
1083 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1084 discard_const_p(char *, kwnames),
1085 &py_obj, &py_controls))
1088 mem_ctx = talloc_new(NULL);
1089 if (mem_ctx == NULL) {
1093 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1095 if (py_controls == Py_None) {
1096 parsed_controls = NULL;
1098 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1099 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1100 talloc_free(controls);
1103 if (PyLdbMessage_Check(py_obj)) {
1104 msg = pyldb_Message_AsMessage(py_obj);
1105 } else if (PyDict_Check(py_obj)) {
1106 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1108 PyErr_SetString(PyExc_TypeError,
1109 "Dictionary or LdbMessage object expected!");
1113 /* we should have a PyErr already set */
1114 talloc_free(mem_ctx);
1118 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1119 if (ret != LDB_SUCCESS) {
1120 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1121 talloc_free(mem_ctx);
1125 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1126 NULL, ldb_op_default_callback, NULL);
1127 if (ret != LDB_SUCCESS) {
1128 PyErr_SetString(PyExc_TypeError, "failed to build request");
1129 talloc_free(mem_ctx);
1133 /* do request and autostart a transaction */
1134 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1136 ret = ldb_transaction_start(ldb_ctx);
1137 if (ret != LDB_SUCCESS) {
1138 talloc_free(mem_ctx);
1139 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1142 ret = ldb_request(ldb_ctx, req);
1143 if (ret == LDB_SUCCESS) {
1144 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1147 if (ret == LDB_SUCCESS) {
1148 ret = ldb_transaction_commit(ldb_ctx);
1150 ldb_transaction_cancel(ldb_ctx);
1153 talloc_free(mem_ctx);
1154 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1159 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1164 struct ldb_context *ldb_ctx;
1165 struct ldb_request *req;
1166 PyObject *py_controls = Py_None;
1167 TALLOC_CTX *mem_ctx;
1168 struct ldb_control **parsed_controls;
1169 const char * const kwnames[] = { "dn", "controls", NULL };
1171 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1172 discard_const_p(char *, kwnames),
1173 &py_dn, &py_controls))
1176 mem_ctx = talloc_new(NULL);
1177 if (mem_ctx == NULL) {
1181 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1183 if (py_controls == Py_None) {
1184 parsed_controls = NULL;
1186 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1187 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1188 talloc_free(controls);
1191 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1192 talloc_free(mem_ctx);
1196 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1197 NULL, ldb_op_default_callback, NULL);
1198 if (ret != LDB_SUCCESS) {
1199 PyErr_SetString(PyExc_TypeError, "failed to build request");
1200 talloc_free(mem_ctx);
1204 /* do request and autostart a transaction */
1205 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1207 ret = ldb_transaction_start(ldb_ctx);
1208 if (ret != LDB_SUCCESS) {
1209 talloc_free(mem_ctx);
1210 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1213 ret = ldb_request(ldb_ctx, req);
1214 if (ret == LDB_SUCCESS) {
1215 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1218 if (ret == LDB_SUCCESS) {
1219 ret = ldb_transaction_commit(ldb_ctx);
1221 ldb_transaction_cancel(ldb_ctx);
1224 talloc_free(mem_ctx);
1225 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1230 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1232 PyObject *py_dn1, *py_dn2;
1233 struct ldb_dn *dn1, *dn2;
1235 TALLOC_CTX *mem_ctx;
1236 PyObject *py_controls = Py_None;
1237 struct ldb_control **parsed_controls;
1238 struct ldb_context *ldb_ctx;
1239 struct ldb_request *req;
1240 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1242 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1244 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1245 discard_const_p(char *, kwnames),
1246 &py_dn1, &py_dn2, &py_controls))
1250 mem_ctx = talloc_new(NULL);
1251 if (mem_ctx == NULL) {
1256 if (py_controls == Py_None) {
1257 parsed_controls = NULL;
1259 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1260 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1261 talloc_free(controls);
1265 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1266 talloc_free(mem_ctx);
1270 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1271 talloc_free(mem_ctx);
1275 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1276 NULL, ldb_op_default_callback, NULL);
1277 if (ret != LDB_SUCCESS) {
1278 PyErr_SetString(PyExc_TypeError, "failed to build request");
1279 talloc_free(mem_ctx);
1283 /* do request and autostart a transaction */
1284 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1286 ret = ldb_transaction_start(ldb_ctx);
1287 if (ret != LDB_SUCCESS) {
1288 talloc_free(mem_ctx);
1289 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1292 ret = ldb_request(ldb_ctx, req);
1293 if (ret == LDB_SUCCESS) {
1294 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1297 if (ret == LDB_SUCCESS) {
1298 ret = ldb_transaction_commit(ldb_ctx);
1300 ldb_transaction_cancel(ldb_ctx);
1303 talloc_free(mem_ctx);
1304 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1309 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1312 if (!PyArg_ParseTuple(args, "s", &name))
1315 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1320 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1322 char *attribute, *syntax;
1325 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1328 ret = ldb_schema_attribute_add(pyldb_Ldb_AsLdbContext(self), attribute, flags, syntax);
1330 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, pyldb_Ldb_AsLdbContext(self));
1335 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1340 /* We don't want this attached to the 'ldb' any more */
1341 return Py_BuildValue(discard_const_p(char, "(iO)"),
1343 PyLdbMessage_FromMessage(ldif->msg));
1348 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1352 struct ldb_ldif ldif;
1355 TALLOC_CTX *mem_ctx;
1357 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1360 if (!PyLdbMessage_Check(py_msg)) {
1361 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1365 ldif.msg = pyldb_Message_AsMessage(py_msg);
1366 ldif.changetype = changetype;
1368 mem_ctx = talloc_new(NULL);
1370 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1372 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1376 ret = PyString_FromString(string);
1378 talloc_free(mem_ctx);
1383 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1386 struct ldb_ldif *ldif;
1389 TALLOC_CTX *mem_ctx;
1391 if (!PyArg_ParseTuple(args, "s", &s))
1394 mem_ctx = talloc_new(NULL);
1399 list = PyList_New(0);
1400 while (s && *s != '\0') {
1401 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1402 talloc_steal(mem_ctx, ldif);
1404 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1406 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1407 talloc_free(mem_ctx);
1411 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1412 return PyObject_GetIter(list);
1415 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1418 PyObject *py_msg_old;
1419 PyObject *py_msg_new;
1420 struct ldb_message *diff;
1421 struct ldb_context *ldb;
1424 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1427 if (!PyLdbMessage_Check(py_msg_old)) {
1428 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1432 if (!PyLdbMessage_Check(py_msg_new)) {
1433 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1437 ldb = pyldb_Ldb_AsLdbContext(self);
1438 ldb_ret = ldb_msg_difference(ldb, ldb,
1439 pyldb_Message_AsMessage(py_msg_old),
1440 pyldb_Message_AsMessage(py_msg_new),
1442 if (ldb_ret != LDB_SUCCESS) {
1443 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1447 py_ret = PyLdbMessage_FromMessage(diff);
1449 talloc_unlink(ldb, diff);
1454 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1456 const struct ldb_schema_attribute *a;
1457 struct ldb_val old_val;
1458 struct ldb_val new_val;
1459 TALLOC_CTX *mem_ctx;
1464 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1467 mem_ctx = talloc_new(NULL);
1469 old_val.data = (uint8_t *)PyString_AsString(val);
1470 old_val.length = PyString_Size(val);
1472 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1478 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1479 talloc_free(mem_ctx);
1483 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1485 talloc_free(mem_ctx);
1490 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1492 PyObject *py_base = Py_None;
1493 int scope = LDB_SCOPE_DEFAULT;
1495 PyObject *py_attrs = Py_None;
1496 PyObject *py_controls = Py_None;
1497 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1499 struct ldb_result *res;
1500 struct ldb_request *req;
1502 struct ldb_context *ldb_ctx;
1503 struct ldb_control **parsed_controls;
1504 struct ldb_dn *base;
1506 TALLOC_CTX *mem_ctx;
1508 /* type "int" rather than "enum" for "scope" is intentional */
1509 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1510 discard_const_p(char *, kwnames),
1511 &py_base, &scope, &expr, &py_attrs, &py_controls))
1515 mem_ctx = talloc_new(NULL);
1516 if (mem_ctx == NULL) {
1520 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1522 if (py_attrs == Py_None) {
1525 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1526 if (attrs == NULL) {
1527 talloc_free(mem_ctx);
1532 if (py_base == Py_None) {
1533 base = ldb_get_default_basedn(ldb_ctx);
1535 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1541 if (py_controls == Py_None) {
1542 parsed_controls = NULL;
1544 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1545 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1546 talloc_free(controls);
1549 res = talloc_zero(mem_ctx, struct ldb_result);
1552 talloc_free(mem_ctx);
1556 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1563 ldb_search_default_callback,
1566 if (ret != LDB_SUCCESS) {
1567 talloc_free(mem_ctx);
1568 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1572 talloc_steal(req, attrs);
1574 ret = ldb_request(ldb_ctx, req);
1576 if (ret == LDB_SUCCESS) {
1577 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1580 if (ret != LDB_SUCCESS) {
1581 talloc_free(mem_ctx);
1582 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1586 py_ret = PyLdbResult_FromResult(res);
1588 talloc_free(mem_ctx);
1593 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1598 if (!PyArg_ParseTuple(args, "s", &name))
1601 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1606 /* FIXME: More interpretation */
1611 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1616 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1619 /* FIXME: More interpretation */
1621 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1626 static PyObject *py_ldb_modules(PyLdbObject *self)
1628 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1629 PyObject *ret = PyList_New(0);
1630 struct ldb_module *mod;
1632 for (mod = ldb->modules; mod; mod = mod->next) {
1633 PyList_Append(ret, PyLdbModule_FromModule(mod));
1639 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1641 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1645 if (!PyArg_ParseTuple(args, "i", &type))
1648 /* FIXME: More interpretation */
1650 ret = ldb_sequence_number(ldb, type, &value);
1652 if (ret != LDB_SUCCESS) {
1653 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1656 return PyLong_FromLongLong(value);
1658 static PyMethodDef py_ldb_methods[] = {
1659 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1660 "S.set_debug(callback) -> None\n"
1661 "Set callback for LDB debug messages.\n"
1662 "The callback should accept a debug level and debug text." },
1663 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1664 "S.set_create_perms(mode) -> None\n"
1665 "Set mode to use when creating new LDB files." },
1666 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1667 "S.set_modules_dir(path) -> None\n"
1668 "Set path LDB should search for modules" },
1669 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1670 "S.transaction_start() -> None\n"
1671 "Start a new transaction." },
1672 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1673 "S.transaction_prepare_commit() -> None\n"
1674 "prepare to commit a new transaction (2-stage commit)." },
1675 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1676 "S.transaction_commit() -> None\n"
1677 "commit a new transaction." },
1678 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1679 "S.transaction_cancel() -> None\n"
1680 "cancel a new transaction." },
1681 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1683 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1685 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1687 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1689 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1691 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1692 "S.connect(url, flags=0, options=None) -> None\n"
1693 "Connect to a LDB URL." },
1694 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1695 "S.modify(message, controls=None, validate=False) -> None\n"
1696 "Modify an entry." },
1697 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1698 "S.add(message, controls=None) -> None\n"
1700 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1701 "S.delete(dn, controls=None) -> None\n"
1702 "Remove an entry." },
1703 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1704 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1705 "Rename an entry." },
1706 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1707 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1708 "Search in a database.\n"
1710 ":param base: Optional base DN to search\n"
1711 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1712 ":param expression: Optional search expression\n"
1713 ":param attrs: Attributes to return (defaults to all)\n"
1714 ":param controls: Optional list of controls\n"
1715 ":return: Iterator over Message objects\n"
1717 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1719 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1721 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1723 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1724 "S.parse_ldif(ldif) -> iter(messages)\n"
1725 "Parse a string formatted using LDIF." },
1726 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1727 "S.write_ldif(message, changetype) -> ldif\n"
1728 "Print the message as a string formatted using LDIF." },
1729 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1730 "S.msg_diff(Message) -> Message\n"
1731 "Return an LDB Message of the difference between two Message objects." },
1732 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1733 "S.get_opaque(name) -> value\n"
1734 "Get an opaque value set on this LDB connection. \n"
1735 ":note: The returned value may not be useful in Python."
1737 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1738 "S.set_opaque(name, value) -> None\n"
1739 "Set an opaque value on this LDB connection. \n"
1740 ":note: Passing incorrect values may cause crashes." },
1741 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1742 "S.modules() -> list\n"
1743 "Return the list of modules on this LDB connection " },
1744 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1745 "S.sequence_number(type) -> value\n"
1746 "Return the value of the sequence according to the requested type" },
1750 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1752 PyLdbModuleObject *ret;
1754 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1759 ret->mem_ctx = talloc_new(NULL);
1760 ret->mod = talloc_reference(ret->mem_ctx, mod);
1761 return (PyObject *)ret;
1764 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1766 return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1769 static PyGetSetDef py_ldb_getset[] = {
1770 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1774 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1776 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1778 struct ldb_result *result;
1782 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1786 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1788 if (ret != LDB_SUCCESS) {
1789 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1793 count = result->count;
1795 talloc_free(result);
1798 PyErr_Format(PyExc_RuntimeError,
1799 "Searching for [%s] dn gave %u results!",
1800 ldb_dn_get_linearized(dn),
1808 static PySequenceMethods py_ldb_seq = {
1809 .sq_contains = (objobjproc)py_ldb_contains,
1812 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1816 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1821 ret->mem_ctx = talloc_new(NULL);
1822 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1823 return (PyObject *)ret;
1826 static void py_ldb_dealloc(PyLdbObject *self)
1828 talloc_free(self->mem_ctx);
1829 self->ob_type->tp_free(self);
1832 static PyTypeObject PyLdb = {
1833 .tp_name = "ldb.Ldb",
1834 .tp_methods = py_ldb_methods,
1835 .tp_repr = (reprfunc)py_ldb_repr,
1836 .tp_new = py_ldb_new,
1837 .tp_init = (initproc)py_ldb_init,
1838 .tp_dealloc = (destructor)py_ldb_dealloc,
1839 .tp_getset = py_ldb_getset,
1840 .tp_getattro = PyObject_GenericGetAttr,
1841 .tp_basicsize = sizeof(PyLdbObject),
1842 .tp_doc = "Connection to a LDB database.",
1843 .tp_as_sequence = &py_ldb_seq,
1844 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1847 static void py_ldb_result_dealloc(PyLdbResultObject *self)
1849 talloc_free(self->mem_ctx);
1850 Py_DECREF(self->msgs);
1851 Py_DECREF(self->referals);
1852 Py_DECREF(self->controls);
1853 self->ob_type->tp_free(self);
1856 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
1858 Py_INCREF(self->msgs);
1862 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
1864 Py_INCREF(self->controls);
1865 return self->controls;
1868 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
1870 Py_INCREF(self->referals);
1871 return self->referals;
1874 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
1877 if (self->msgs == NULL) {
1878 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
1881 size = PyList_Size(self->msgs);
1882 return PyInt_FromLong(size);
1885 static PyGetSetDef py_ldb_result_getset[] = {
1886 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
1887 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
1888 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
1889 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
1893 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
1895 return PyObject_GetIter(self->msgs);
1898 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
1900 return PySequence_Size(self->msgs);
1903 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
1905 return PySequence_GetItem(self->msgs, idx);
1908 static PySequenceMethods py_ldb_result_seq = {
1909 .sq_length = (lenfunc)py_ldb_result_len,
1910 .sq_item = (ssizeargfunc)py_ldb_result_find,
1913 static PyObject *py_ldb_result_repr(PyLdbObject *self)
1915 return PyString_FromFormat("<ldb result>");
1919 static PyTypeObject PyLdbResult = {
1920 .tp_name = "ldb.Result",
1921 .tp_repr = (reprfunc)py_ldb_result_repr,
1922 .tp_dealloc = (destructor)py_ldb_result_dealloc,
1923 .tp_iter = (getiterfunc)py_ldb_result_iter,
1924 .tp_getset = py_ldb_result_getset,
1925 .tp_getattro = PyObject_GenericGetAttr,
1926 .tp_basicsize = sizeof(PyLdbResultObject),
1927 .tp_as_sequence = &py_ldb_result_seq,
1928 .tp_doc = "LDB result.",
1929 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1932 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1934 return PyString_FromFormat("<ldb module '%s'>",
1935 pyldb_Module_AsModule(self)->ops->name);
1938 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1940 return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
1943 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1945 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
1949 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1951 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
1955 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
1957 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
1961 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
1963 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
1965 struct ldb_request *req;
1966 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
1967 struct ldb_module *mod;
1968 const char * const*attrs;
1970 /* type "int" rather than "enum" for "scope" is intentional */
1971 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
1972 discard_const_p(char *, kwnames),
1973 &py_base, &scope, &py_tree, &py_attrs))
1978 if (py_attrs == Py_None) {
1981 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
1986 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
1987 scope, NULL /* expr */, attrs,
1988 NULL /* controls */, NULL, NULL, NULL);
1990 talloc_steal(req, attrs);
1992 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1994 req->op.search.res = NULL;
1996 ret = mod->ops->search(mod, req);
1998 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2000 py_ret = PyLdbResult_FromResult(req->op.search.res);
2008 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2010 struct ldb_request *req;
2011 PyObject *py_message;
2013 struct ldb_module *mod;
2015 if (!PyArg_ParseTuple(args, "O", &py_message))
2018 req = talloc_zero(NULL, struct ldb_request);
2019 req->operation = LDB_ADD;
2020 req->op.add.message = pyldb_Message_AsMessage(py_message);
2022 mod = pyldb_Module_AsModule(self);
2023 ret = mod->ops->add(mod, req);
2025 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2030 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2033 struct ldb_request *req;
2034 PyObject *py_message;
2035 struct ldb_module *mod;
2037 if (!PyArg_ParseTuple(args, "O", &py_message))
2040 req = talloc_zero(NULL, struct ldb_request);
2041 req->operation = LDB_MODIFY;
2042 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2044 mod = pyldb_Module_AsModule(self);
2045 ret = mod->ops->modify(mod, req);
2047 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2052 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2055 struct ldb_request *req;
2058 if (!PyArg_ParseTuple(args, "O", &py_dn))
2061 req = talloc_zero(NULL, struct ldb_request);
2062 req->operation = LDB_DELETE;
2063 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2065 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2067 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2072 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2075 struct ldb_request *req;
2076 PyObject *py_dn1, *py_dn2;
2078 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
2081 req = talloc_zero(NULL, struct ldb_request);
2083 req->operation = LDB_RENAME;
2084 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2085 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2087 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2089 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2094 static PyMethodDef py_ldb_module_methods[] = {
2095 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2096 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2097 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2098 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2099 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2100 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2101 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2102 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2106 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2108 talloc_free(self->mem_ctx);
2112 static PyTypeObject PyLdbModule = {
2113 .tp_name = "ldb.LdbModule",
2114 .tp_methods = py_ldb_module_methods,
2115 .tp_repr = (reprfunc)py_ldb_module_repr,
2116 .tp_str = (reprfunc)py_ldb_module_str,
2117 .tp_basicsize = sizeof(PyLdbModuleObject),
2118 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2119 .tp_flags = Py_TPFLAGS_DEFAULT,
2124 * Create a ldb_message_element from a Python object.
2126 * This will accept any sequence objects that contains strings, or
2129 * A reference to set_obj will be borrowed.
2131 * @param mem_ctx Memory context
2132 * @param set_obj Python object to convert
2133 * @param flags ldb_message_element flags to set
2134 * @param attr_name Name of the attribute
2135 * @return New ldb_message_element, allocated as child of mem_ctx
2137 static struct ldb_message_element *PyObject_AsMessageElement(
2138 TALLOC_CTX *mem_ctx,
2141 const char *attr_name)
2143 struct ldb_message_element *me;
2145 if (pyldb_MessageElement_Check(set_obj)) {
2146 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2147 /* We have to talloc_reference() the memory context, not the pointer
2148 * which may not actually be it's own context */
2149 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2150 return pyldb_MessageElement_AsMessageElement(set_obj);
2155 me = talloc(mem_ctx, struct ldb_message_element);
2161 me->name = talloc_strdup(me, attr_name);
2163 if (PyString_Check(set_obj)) {
2165 me->values = talloc_array(me, struct ldb_val, me->num_values);
2166 me->values[0].length = PyString_Size(set_obj);
2167 me->values[0].data = talloc_memdup(me,
2168 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2169 } else if (PySequence_Check(set_obj)) {
2171 me->num_values = PySequence_Size(set_obj);
2172 me->values = talloc_array(me, struct ldb_val, me->num_values);
2173 for (i = 0; i < me->num_values; i++) {
2174 PyObject *obj = PySequence_GetItem(set_obj, i);
2175 if (!PyString_Check(obj)) {
2176 PyErr_Format(PyExc_TypeError,
2177 "Expected string as element %zd in list", i);
2182 me->values[i].length = PyString_Size(obj);
2183 me->values[i].data = talloc_memdup(me,
2184 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2195 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2196 struct ldb_message_element *me)
2201 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2202 result = PyList_New(me->num_values);
2204 for (i = 0; i < me->num_values; i++) {
2205 PyList_SetItem(result, i,
2206 PyObject_FromLdbValue(&me->values[i]));
2212 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2215 if (!PyArg_ParseTuple(args, "I", &i))
2217 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2220 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2223 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2225 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2226 return PyInt_FromLong(el->flags);
2229 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2232 struct ldb_message_element *el;
2233 if (!PyArg_ParseTuple(args, "I", &flags))
2236 el = pyldb_MessageElement_AsMessageElement(self);
2241 static PyMethodDef py_ldb_msg_element_methods[] = {
2242 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2243 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2244 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2248 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2250 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2253 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2255 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2256 if (idx < 0 || idx >= el->num_values) {
2257 PyErr_SetString(PyExc_IndexError, "Out of range");
2260 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2263 static PySequenceMethods py_ldb_msg_element_seq = {
2264 .sq_length = (lenfunc)py_ldb_msg_element_len,
2265 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2268 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2270 int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2271 pyldb_MessageElement_AsMessageElement(other));
2275 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2277 PyObject *el = ldb_msg_element_to_set(NULL,
2278 pyldb_MessageElement_AsMessageElement(self));
2279 return PyObject_GetIter(el);
2282 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2284 PyLdbMessageElementObject *ret;
2285 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2290 ret->mem_ctx = talloc_new(NULL);
2291 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2296 return (PyObject *)ret;
2299 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2301 PyObject *py_elements = NULL;
2302 struct ldb_message_element *el;
2303 unsigned int flags = 0;
2305 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2306 PyLdbMessageElementObject *ret;
2307 TALLOC_CTX *mem_ctx;
2309 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2310 discard_const_p(char *, kwnames),
2311 &py_elements, &flags, &name))
2314 mem_ctx = talloc_new(NULL);
2315 if (mem_ctx == NULL) {
2320 el = talloc_zero(mem_ctx, struct ldb_message_element);
2323 talloc_free(mem_ctx);
2327 if (py_elements != NULL) {
2329 if (PyString_Check(py_elements)) {
2331 el->values = talloc_array(el, struct ldb_val, 1);
2332 if (el->values == NULL) {
2333 talloc_free(mem_ctx);
2337 el->values[0].length = PyString_Size(py_elements);
2338 el->values[0].data = talloc_memdup(el->values,
2339 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2340 } else if (PySequence_Check(py_elements)) {
2341 el->num_values = PySequence_Size(py_elements);
2342 el->values = talloc_array(el, struct ldb_val, el->num_values);
2343 if (el->values == NULL) {
2344 talloc_free(mem_ctx);
2348 for (i = 0; i < el->num_values; i++) {
2349 PyObject *item = PySequence_GetItem(py_elements, i);
2351 talloc_free(mem_ctx);
2354 if (!PyString_Check(item)) {
2355 PyErr_Format(PyExc_TypeError,
2356 "Expected string as element %zd in list", i);
2357 talloc_free(mem_ctx);
2360 el->values[i].length = PyString_Size(item);
2361 el->values[i].data = talloc_memdup(el,
2362 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2365 PyErr_SetString(PyExc_TypeError,
2366 "Expected string or list");
2367 talloc_free(mem_ctx);
2373 el->name = talloc_strdup(el, name);
2375 ret = PyObject_New(PyLdbMessageElementObject, type);
2377 talloc_free(mem_ctx);
2381 ret->mem_ctx = mem_ctx;
2383 return (PyObject *)ret;
2386 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2388 char *element_str = NULL;
2390 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2393 for (i = 0; i < el->num_values; i++) {
2394 PyObject *o = py_ldb_msg_element_find(self, i);
2395 if (element_str == NULL)
2396 element_str = talloc_strdup(NULL, PyObject_REPR(o));
2398 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2401 if (element_str != NULL) {
2402 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2403 talloc_free(element_str);
2405 ret = PyString_FromString("MessageElement([])");
2411 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2413 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2415 if (el->num_values == 1)
2416 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2421 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2423 talloc_free(self->mem_ctx);
2427 static PyTypeObject PyLdbMessageElement = {
2428 .tp_name = "ldb.MessageElement",
2429 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2430 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2431 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2432 .tp_str = (reprfunc)py_ldb_msg_element_str,
2433 .tp_methods = py_ldb_msg_element_methods,
2434 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2435 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2436 .tp_as_sequence = &py_ldb_msg_element_seq,
2437 .tp_new = py_ldb_msg_element_new,
2438 .tp_flags = Py_TPFLAGS_DEFAULT,
2442 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2447 struct ldb_message *msg;
2448 struct ldb_context *ldb_ctx;
2449 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2451 if (!PyArg_ParseTuple(args, "O!O!|I",
2452 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2457 /* mask only flags we are going to use */
2458 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2460 PyErr_SetString(PyExc_ValueError,
2461 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2462 " expected as mod_flag value");
2466 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2468 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2473 py_ret = PyLdbMessage_FromMessage(msg);
2475 talloc_unlink(ldb_ctx, msg);
2480 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2483 if (!PyArg_ParseTuple(args, "s", &name))
2486 ldb_msg_remove_attr(self->msg, name);
2491 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2493 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2494 Py_ssize_t i, j = 0;
2495 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2496 if (msg->dn != NULL) {
2497 PyList_SetItem(obj, j, PyString_FromString("dn"));
2500 for (i = 0; i < msg->num_elements; i++) {
2501 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2507 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2509 struct ldb_message_element *el;
2511 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2512 if (!PyString_Check(py_name)) {
2513 PyErr_SetNone(PyExc_TypeError);
2516 name = PyString_AsString(py_name);
2517 if (!strcmp(name, "dn"))
2518 return pyldb_Dn_FromDn(msg->dn);
2519 el = ldb_msg_find_element(msg, name);
2523 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2526 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2528 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2530 PyErr_SetString(PyExc_KeyError, "No such element");
2536 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2538 PyObject *def = NULL;
2539 const char *kwnames[] = { "name", "default", "idx", NULL };
2540 const char *name = NULL;
2542 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2543 struct ldb_message_element *el;
2545 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2546 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2550 if (strcasecmp(name, "dn") == 0) {
2551 return pyldb_Dn_FromDn(msg->dn);
2554 el = ldb_msg_find_element(msg, name);
2556 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2564 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2567 return PyObject_FromLdbValue(&el->values[idx]);
2570 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2572 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2573 Py_ssize_t i, j = 0;
2574 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2575 if (msg->dn != NULL) {
2576 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2579 for (i = 0; i < msg->num_elements; i++, j++) {
2580 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2581 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2582 PyList_SetItem(l, j, value);
2587 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2589 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2591 PyObject *l = PyList_New(msg->num_elements);
2592 for (i = 0; i < msg->num_elements; i++) {
2593 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2598 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2600 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2601 PyLdbMessageElementObject *py_element;
2603 struct ldb_message_element *el;
2605 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2608 el = talloc_reference(msg, py_element->el);
2614 ret = ldb_msg_add(msg, el, el->flags);
2615 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2620 static PyMethodDef py_ldb_msg_methods[] = {
2621 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2622 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2623 "Class method to create ldb.Message object from Dictionary.\n"
2624 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2625 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2626 "S.keys() -> list\n\n"
2627 "Return sequence of all attribute names." },
2628 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2629 "S.remove(name)\n\n"
2630 "Remove all entries for attributes with the specified name."},
2631 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2632 "msg.get(name,default=None,idx=None) -> string\n"
2633 "idx is the index into the values array\n"
2634 "if idx is None, then a list is returned\n"
2635 "if idx is not None, then the element with that index is returned\n"
2636 "if you pass the special name 'dn' then the DN object is returned\n"},
2637 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2638 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2639 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2640 "S.append(element)\n\n"
2641 "Add an element to this message." },
2645 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2647 PyObject *list, *iter;
2649 list = py_ldb_msg_keys(self);
2650 iter = PyObject_GetIter(list);
2655 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2659 if (!PyString_Check(name)) {
2660 PyErr_SetNone(PyExc_TypeError);
2664 attr_name = PyString_AsString(name);
2665 if (value == NULL) {
2667 ldb_msg_remove_attr(self->msg, attr_name);
2669 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2670 value, 0, attr_name);
2673 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2674 ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2679 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2681 return pyldb_Message_AsMessage(self)->num_elements;
2684 static PyMappingMethods py_ldb_msg_mapping = {
2685 .mp_length = (lenfunc)py_ldb_msg_length,
2686 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2687 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2690 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2692 const char * const kwnames[] = { "dn", NULL };
2693 struct ldb_message *ret;
2694 TALLOC_CTX *mem_ctx;
2695 PyObject *pydn = NULL;
2696 PyLdbMessageObject *py_ret;
2698 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2699 discard_const_p(char *, kwnames),
2703 mem_ctx = talloc_new(NULL);
2704 if (mem_ctx == NULL) {
2709 ret = ldb_msg_new(mem_ctx);
2711 talloc_free(mem_ctx);
2718 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2719 talloc_free(mem_ctx);
2722 ret->dn = talloc_reference(ret, dn);
2725 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2726 if (py_ret == NULL) {
2728 talloc_free(mem_ctx);
2732 py_ret->mem_ctx = mem_ctx;
2734 return (PyObject *)py_ret;
2737 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2739 PyLdbMessageObject *ret;
2741 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2746 ret->mem_ctx = talloc_new(NULL);
2747 ret->msg = talloc_reference(ret->mem_ctx, msg);
2748 return (PyObject *)ret;
2751 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2753 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2754 return pyldb_Dn_FromDn(msg->dn);
2757 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2759 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2760 if (!pyldb_Dn_Check(value)) {
2761 PyErr_SetNone(PyExc_TypeError);
2765 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2769 static PyGetSetDef py_ldb_msg_getset[] = {
2770 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2774 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2776 PyObject *dict = PyDict_New(), *ret;
2777 if (PyDict_Update(dict, (PyObject *)self) != 0)
2779 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2784 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2786 talloc_free(self->mem_ctx);
2790 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2791 PyLdbMessageObject *py_msg2)
2793 struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
2794 *msg2 = pyldb_Message_AsMessage(py_msg2);
2798 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2799 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2805 ret = msg1->num_elements - msg2->num_elements;
2810 for (i = 0; i < msg1->num_elements; i++) {
2811 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2812 &msg2->elements[i]);
2817 ret = ldb_msg_element_compare(&msg1->elements[i],
2818 &msg2->elements[i]);
2827 static PyTypeObject PyLdbMessage = {
2828 .tp_name = "ldb.Message",
2829 .tp_methods = py_ldb_msg_methods,
2830 .tp_getset = py_ldb_msg_getset,
2831 .tp_as_mapping = &py_ldb_msg_mapping,
2832 .tp_basicsize = sizeof(PyLdbMessageObject),
2833 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2834 .tp_new = py_ldb_msg_new,
2835 .tp_repr = (reprfunc)py_ldb_msg_repr,
2836 .tp_flags = Py_TPFLAGS_DEFAULT,
2837 .tp_iter = (getiterfunc)py_ldb_msg_iter,
2838 .tp_compare = (cmpfunc)py_ldb_msg_compare,
2841 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2843 PyLdbTreeObject *ret;
2845 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2851 ret->mem_ctx = talloc_new(NULL);
2852 ret->tree = talloc_reference(ret->mem_ctx, tree);
2853 return (PyObject *)ret;
2856 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2858 talloc_free(self->mem_ctx);
2862 static PyTypeObject PyLdbTree = {
2863 .tp_name = "ldb.Tree",
2864 .tp_basicsize = sizeof(PyLdbTreeObject),
2865 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2866 .tp_flags = Py_TPFLAGS_DEFAULT,
2870 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2872 PyObject *py_ldb = (PyObject *)mod->private_data;
2873 PyObject *py_result, *py_base, *py_attrs, *py_tree;
2875 py_base = pyldb_Dn_FromDn(req->op.search.base);
2877 if (py_base == NULL)
2878 return LDB_ERR_OPERATIONS_ERROR;
2880 py_tree = PyLdbTree_FromTree(req->op.search.tree);
2882 if (py_tree == NULL)
2883 return LDB_ERR_OPERATIONS_ERROR;
2885 if (req->op.search.attrs == NULL) {
2889 for (len = 0; req->op.search.attrs[len]; len++);
2890 py_attrs = PyList_New(len);
2891 for (i = 0; i < len; i++)
2892 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2895 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2896 discard_const_p(char, "OiOO"),
2897 py_base, req->op.search.scope, py_tree, py_attrs);
2899 Py_DECREF(py_attrs);
2903 if (py_result == NULL) {
2904 return LDB_ERR_PYTHON_EXCEPTION;
2907 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2908 if (req->op.search.res == NULL) {
2909 return LDB_ERR_PYTHON_EXCEPTION;
2912 Py_DECREF(py_result);
2917 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2919 PyObject *py_ldb = (PyObject *)mod->private_data;
2920 PyObject *py_result, *py_msg;
2922 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2924 if (py_msg == NULL) {
2925 return LDB_ERR_OPERATIONS_ERROR;
2928 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2929 discard_const_p(char, "O"),
2934 if (py_result == NULL) {
2935 return LDB_ERR_PYTHON_EXCEPTION;
2938 Py_DECREF(py_result);
2943 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
2945 PyObject *py_ldb = (PyObject *)mod->private_data;
2946 PyObject *py_result, *py_msg;
2948 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
2950 if (py_msg == NULL) {
2951 return LDB_ERR_OPERATIONS_ERROR;
2954 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
2955 discard_const_p(char, "O"),
2960 if (py_result == NULL) {
2961 return LDB_ERR_PYTHON_EXCEPTION;
2964 Py_DECREF(py_result);
2969 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
2971 PyObject *py_ldb = (PyObject *)mod->private_data;
2972 PyObject *py_result, *py_dn;
2974 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
2977 return LDB_ERR_OPERATIONS_ERROR;
2979 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
2980 discard_const_p(char, "O"),
2983 if (py_result == NULL) {
2984 return LDB_ERR_PYTHON_EXCEPTION;
2987 Py_DECREF(py_result);
2992 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
2994 PyObject *py_ldb = (PyObject *)mod->private_data;
2995 PyObject *py_result, *py_olddn, *py_newdn;
2997 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
2999 if (py_olddn == NULL)
3000 return LDB_ERR_OPERATIONS_ERROR;
3002 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3004 if (py_newdn == NULL)
3005 return LDB_ERR_OPERATIONS_ERROR;
3007 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3008 discard_const_p(char, "OO"),
3009 py_olddn, py_newdn);
3011 Py_DECREF(py_olddn);
3012 Py_DECREF(py_newdn);
3014 if (py_result == NULL) {
3015 return LDB_ERR_PYTHON_EXCEPTION;
3018 Py_DECREF(py_result);
3023 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3025 PyObject *py_ldb = (PyObject *)mod->private_data;
3026 PyObject *py_result;
3028 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3029 discard_const_p(char, ""));
3031 return LDB_ERR_OPERATIONS_ERROR;
3034 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3036 PyObject *py_ldb = (PyObject *)mod->private_data;
3037 PyObject *py_result;
3039 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3040 discard_const_p(char, ""));
3042 return LDB_ERR_OPERATIONS_ERROR;
3045 static int py_module_start_transaction(struct ldb_module *mod)
3047 PyObject *py_ldb = (PyObject *)mod->private_data;
3048 PyObject *py_result;
3050 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3051 discard_const_p(char, ""));
3053 if (py_result == NULL) {
3054 return LDB_ERR_PYTHON_EXCEPTION;
3057 Py_DECREF(py_result);
3062 static int py_module_end_transaction(struct ldb_module *mod)
3064 PyObject *py_ldb = (PyObject *)mod->private_data;
3065 PyObject *py_result;
3067 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3068 discard_const_p(char, ""));
3070 if (py_result == NULL) {
3071 return LDB_ERR_PYTHON_EXCEPTION;
3074 Py_DECREF(py_result);
3079 static int py_module_del_transaction(struct ldb_module *mod)
3081 PyObject *py_ldb = (PyObject *)mod->private_data;
3082 PyObject *py_result;
3084 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3085 discard_const_p(char, ""));
3087 if (py_result == NULL) {
3088 return LDB_ERR_PYTHON_EXCEPTION;
3091 Py_DECREF(py_result);
3096 static int py_module_destructor(struct ldb_module *mod)
3098 Py_DECREF((PyObject *)mod->private_data);
3102 static int py_module_init(struct ldb_module *mod)
3104 PyObject *py_class = (PyObject *)mod->ops->private_data;
3105 PyObject *py_result, *py_next, *py_ldb;
3107 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3110 return LDB_ERR_OPERATIONS_ERROR;
3112 py_next = PyLdbModule_FromModule(mod->next);
3114 if (py_next == NULL)
3115 return LDB_ERR_OPERATIONS_ERROR;
3117 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3120 if (py_result == NULL) {
3121 return LDB_ERR_PYTHON_EXCEPTION;
3124 mod->private_data = py_result;
3126 talloc_set_destructor(mod, py_module_destructor);
3128 return ldb_next_init(mod);
3131 static PyObject *py_register_module(PyObject *module, PyObject *args)
3134 struct ldb_module_ops *ops;
3137 if (!PyArg_ParseTuple(args, "O", &input))
3140 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3146 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3149 ops->private_data = input;
3150 ops->init_context = py_module_init;
3151 ops->search = py_module_search;
3152 ops->add = py_module_add;
3153 ops->modify = py_module_modify;
3154 ops->del = py_module_del;
3155 ops->rename = py_module_rename;
3156 ops->request = py_module_request;
3157 ops->extended = py_module_extended;
3158 ops->start_transaction = py_module_start_transaction;
3159 ops->end_transaction = py_module_end_transaction;
3160 ops->del_transaction = py_module_del_transaction;
3162 ret = ldb_register_module(ops);
3164 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3169 static PyObject *py_timestring(PyObject *module, PyObject *args)
3171 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3172 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3176 if (!PyArg_ParseTuple(args, "l", &t_val))
3178 tresult = ldb_timestring(NULL, (time_t) t_val);
3179 ret = PyString_FromString(tresult);
3180 talloc_free(tresult);
3184 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3187 if (!PyArg_ParseTuple(args, "s", &str))
3190 return PyInt_FromLong(ldb_string_to_time(str));
3193 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3196 if (!PyArg_ParseTuple(args, "s", &name))
3198 return PyBool_FromLong(ldb_valid_attr_name(name));
3202 encode a string using RFC2254 rules
3204 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3206 char *str, *encoded;
3211 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3213 val.data = (uint8_t *)str;
3216 encoded = ldb_binary_encode(NULL, val);
3217 if (encoded == NULL) {
3218 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3221 ret = PyString_FromString(encoded);
3222 talloc_free(encoded);
3227 decode a string using RFC2254 rules
3229 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3235 if (!PyArg_ParseTuple(args, "s", &str))
3238 val = ldb_binary_decode(NULL, str);
3239 if (val.data == NULL) {
3240 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3243 ret = Py_BuildValue("s#", val.data, val.length);
3244 talloc_free(val.data);
3248 static PyMethodDef py_ldb_global_methods[] = {
3249 { "register_module", py_register_module, METH_VARARGS,
3250 "S.register_module(module) -> None\n"
3251 "Register a LDB module."},
3252 { "timestring", py_timestring, METH_VARARGS,
3253 "S.timestring(int) -> string\n"
3254 "Generate a LDAP time string from a UNIX timestamp" },
3255 { "string_to_time", py_string_to_time, METH_VARARGS,
3256 "S.string_to_time(string) -> int\n"
3257 "Parse a LDAP time string into a UNIX timestamp." },
3258 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3259 "S.valid_attr_name(name) -> bool\n"
3260 "Check whether the supplied name is a valid attribute name." },
3261 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3263 { "binary_encode", py_binary_encode, METH_VARARGS,
3264 "S.binary_encode(string) -> string\n"
3265 "Perform a RFC2254 binary encoding on a string" },
3266 { "binary_decode", py_binary_decode, METH_VARARGS,
3267 "S.binary_decode(string) -> string\n"
3268 "Perform a RFC2254 binary decode on a string" },
3276 if (PyType_Ready(&PyLdbDn) < 0)
3279 if (PyType_Ready(&PyLdbMessage) < 0)
3282 if (PyType_Ready(&PyLdbMessageElement) < 0)
3285 if (PyType_Ready(&PyLdb) < 0)
3288 if (PyType_Ready(&PyLdbModule) < 0)
3291 if (PyType_Ready(&PyLdbTree) < 0)
3294 if (PyType_Ready(&PyLdbResult) < 0)
3297 if (PyType_Ready(&PyLdbControl) < 0)
3300 m = Py_InitModule3("ldb", py_ldb_global_methods,
3301 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3305 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3306 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3307 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3308 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3309 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3310 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3311 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3313 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3314 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3315 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3316 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3318 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3319 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3320 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3322 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3323 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3324 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3325 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3326 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3327 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3328 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3329 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3330 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3331 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3332 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3333 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3334 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3335 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3336 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3337 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3338 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3339 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3340 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3341 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3342 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3343 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3344 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3345 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3346 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3347 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3348 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3349 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3350 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3351 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3352 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3353 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3354 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3355 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3356 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3357 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3358 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3359 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3360 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3362 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3363 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3364 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3365 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3367 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3369 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3370 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3373 Py_INCREF(&PyLdbDn);
3374 Py_INCREF(&PyLdbModule);
3375 Py_INCREF(&PyLdbMessage);
3376 Py_INCREF(&PyLdbMessageElement);
3377 Py_INCREF(&PyLdbTree);
3378 Py_INCREF(&PyLdbResult);
3379 Py_INCREF(&PyLdbControl);
3381 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3382 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3383 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3384 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3385 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3386 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3387 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3389 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3391 #define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3393 ADD_LDB_STRING(SYNTAX_DN);
3394 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3395 ADD_LDB_STRING(SYNTAX_INTEGER);
3396 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3397 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3398 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3399 ADD_LDB_STRING(OID_COMPARATOR_AND);
3400 ADD_LDB_STRING(OID_COMPARATOR_OR);