s4:dsdb - we don't need to check if a DN != NULL if we call "ldb_dn_validate"
[Samba/id10ts.git] / source4 / lib / ldb / pyldb.c
blobd14487ba02186daafc606c89f1e903d064025e78
1 /*
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
11 ** NOTE! The following LGPL license applies to the ldb
12 ** library. This does NOT imply that all of Samba is released
13 ** under the LGPL
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 3 of the License, or (at your option) any later version.
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Lesser General Public License for more details.
25 You should have received a copy of the GNU Lesser General Public
26 License along with this library; if not, see <http://www.gnu.org/licenses/>.
29 #include <Python.h>
30 #include <pytalloc.h>
31 #include "ldb_private.h"
32 #include "pyldb.h"
34 void initldb(void);
35 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
36 static PyObject *PyExc_LdbError;
38 staticforward PyTypeObject PyLdbControl;
39 staticforward PyTypeObject PyLdbResult;
40 staticforward PyTypeObject PyLdbMessage;
41 staticforward PyTypeObject PyLdbModule;
42 staticforward PyTypeObject PyLdbDn;
43 staticforward PyTypeObject PyLdb;
44 staticforward PyTypeObject PyLdbMessageElement;
45 staticforward PyTypeObject PyLdbTree;
46 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
47 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
48 static struct ldb_message_element *PyObject_AsMessageElement(
49 TALLOC_CTX *mem_ctx,
50 PyObject *set_obj,
51 int flags,
52 const char *attr_name);
54 /* There's no Py_ssize_t in 2.4, apparently */
55 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
56 typedef int Py_ssize_t;
57 typedef inquiry lenfunc;
58 typedef intargfunc ssizeargfunc;
59 #endif
61 #ifndef Py_RETURN_NONE
62 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
63 #endif
65 #define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
69 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
71 if (self->data != NULL) {
72 char* control = ldb_control_to_string(self->mem_ctx, self->data);
73 if (control == NULL) {
74 PyErr_NoMemory();
75 return NULL;
77 return PyString_FromString(control);
78 } else {
79 return PyString_FromFormat("ldb control");
83 static void py_ldb_control_dealloc(PyLdbControlObject *self)
85 if (self->mem_ctx != NULL) {
86 talloc_free(self->mem_ctx);
88 self->ob_type->tp_free(self);
91 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
93 return PyString_FromString(self->data->oid);
96 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
98 return PyBool_FromLong(self->data->critical);
101 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
103 if (PyObject_IsTrue(value)) {
104 self->data->critical = true;
105 } else {
106 self->data->critical = false;
108 return 0;
111 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
113 char *data = NULL;
114 const char *array[2];
115 const char * const kwnames[] = { "ldb", "data", NULL };
116 struct ldb_control *parsed_controls;
117 PyLdbControlObject *ret;
118 PyObject *py_ldb;
119 TALLOC_CTX *mem_ctx;
120 struct ldb_context *ldb_ctx;
122 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
123 discard_const_p(char *, kwnames),
124 &py_ldb, &data))
125 return NULL;
127 mem_ctx = talloc_new(NULL);
128 if (mem_ctx == NULL) {
129 PyErr_NoMemory();
130 return NULL;
133 ldb_ctx = PyLdb_AsLdbContext(py_ldb);
134 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
136 if (!parsed_controls) {
137 talloc_free(mem_ctx);
138 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
139 return NULL;
142 ret = PyObject_New(PyLdbControlObject, type);
143 if (ret == NULL) {
144 PyErr_NoMemory();
145 talloc_free(mem_ctx);
146 return NULL;
149 ret->mem_ctx = mem_ctx;
151 ret->data = talloc_steal(mem_ctx, parsed_controls);
152 if (ret->data == NULL) {
153 Py_DECREF(ret);
154 PyErr_NoMemory();
155 talloc_free(mem_ctx);
156 return NULL;
159 return (PyObject *)ret;
162 static PyGetSetDef py_ldb_control_getset[] = {
163 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
164 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
165 { NULL }
168 static PyTypeObject PyLdbControl = {
169 .tp_name = "ldb.control",
170 .tp_dealloc = (destructor)py_ldb_control_dealloc,
171 .tp_getattro = PyObject_GenericGetAttr,
172 .tp_basicsize = sizeof(PyLdbControlObject),
173 .tp_getset = py_ldb_control_getset,
174 .tp_doc = "LDB control.",
175 .tp_str = (reprfunc)py_ldb_control_str,
176 .tp_new = py_ldb_control_new,
177 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
180 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
182 if (ret == LDB_ERR_PYTHON_EXCEPTION)
183 return; /* Python exception should already be set, just keep that */
185 PyErr_SetObject(error,
186 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
187 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
190 static PyObject *PyObject_FromLdbValue(struct ldb_val *val)
192 return PyString_FromStringAndSize((const char *)val->data, val->length);
196 * Create a Python object from a ldb_result.
198 * @param result LDB result to convert
199 * @return Python object with converted result (a list object)
201 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
203 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
204 PyLdbControlObject *ctrl;
205 if (ctl_ctx == NULL) {
206 PyErr_NoMemory();
207 return NULL;
210 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
211 if (ctrl == NULL) {
212 PyErr_NoMemory();
213 return NULL;
215 ctrl->mem_ctx = ctl_ctx;
216 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
217 if (ctrl->data == NULL) {
218 Py_DECREF(ctrl);
219 PyErr_NoMemory();
220 return NULL;
222 return (PyObject*) ctrl;
226 * Create a Python object from a ldb_result.
228 * @param result LDB result to convert
229 * @return Python object with converted result (a list object)
231 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
233 PyLdbResultObject *ret;
234 PyObject *list, *controls, *referals;
235 Py_ssize_t i;
237 if (result == NULL) {
238 Py_RETURN_NONE;
241 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
242 if (ret == NULL) {
243 PyErr_NoMemory();
244 return NULL;
247 list = PyList_New(result->count);
248 if (list == NULL) {
249 PyErr_NoMemory();
250 Py_DECREF(ret);
251 return NULL;
254 for (i = 0; i < result->count; i++) {
255 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
258 ret->mem_ctx = talloc_new(NULL);
259 if (ret->mem_ctx == NULL) {
260 Py_DECREF(list);
261 Py_DECREF(ret);
262 PyErr_NoMemory();
263 return NULL;
266 ret->msgs = list;
268 if (result->controls) {
269 controls = PyList_New(1);
270 if (controls == NULL) {
271 Py_DECREF(ret);
272 PyErr_NoMemory();
273 return NULL;
275 for (i=0; result->controls[i]; i++) {
276 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
277 if (ctrl == NULL) {
278 Py_DECREF(ret);
279 Py_DECREF(controls);
280 PyErr_NoMemory();
281 return NULL;
283 PyList_SetItem(controls, i, ctrl);
285 } else {
287 * No controls so we keep an empty list
289 controls = PyList_New(0);
290 if (controls == NULL) {
291 Py_DECREF(ret);
292 PyErr_NoMemory();
293 return NULL;
297 ret->controls = controls;
299 i = 0;
301 while (result->refs && result->refs[i]) {
302 i++;
305 referals = PyList_New(i);
306 if (referals == NULL) {
307 Py_DECREF(ret);
308 PyErr_NoMemory();
309 return NULL;
312 for (i = 0;result->refs && result->refs[i]; i++) {
313 PyList_SetItem(referals, i, PyString_FromString(result->refs[i]));
315 ret->referals = referals;
316 return (PyObject *)ret;
320 * Create a LDB Result from a Python object.
321 * If conversion fails, NULL will be returned and a Python exception set.
323 * @param mem_ctx Memory context in which to allocate the LDB Result
324 * @param obj Python object to convert
325 * @return a ldb_result, or NULL if the conversion failed
327 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
328 PyObject *obj)
330 struct ldb_result *res;
331 Py_ssize_t i;
333 if (obj == Py_None)
334 return NULL;
336 res = talloc_zero(mem_ctx, struct ldb_result);
337 res->count = PyList_Size(obj);
338 res->msgs = talloc_array(res, struct ldb_message *, res->count);
339 for (i = 0; i < res->count; i++) {
340 PyObject *item = PyList_GetItem(obj, i);
341 res->msgs[i] = PyLdbMessage_AsMessage(item);
343 return res;
346 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
348 return PyBool_FromLong(ldb_dn_validate(self->dn));
351 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
353 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
356 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
358 return PyBool_FromLong(ldb_dn_is_special(self->dn));
361 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
363 return PyBool_FromLong(ldb_dn_is_null(self->dn));
366 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
368 return PyString_FromString(ldb_dn_get_casefold(self->dn));
371 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
373 return PyString_FromString(ldb_dn_get_linearized(self->dn));
376 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
378 return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
381 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
383 return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
386 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
388 return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
391 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
393 char *name;
395 if (!PyArg_ParseTuple(args, "s", &name))
396 return NULL;
398 return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
401 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
403 int ret;
404 ret = ldb_dn_compare(dn1->dn, dn2->dn);
405 if (ret < 0) ret = -1;
406 if (ret > 0) ret = 1;
407 return ret;
410 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
412 struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self);
413 struct ldb_dn *parent;
414 PyLdbDnObject *py_ret;
415 TALLOC_CTX *mem_ctx = talloc_new(NULL);
417 parent = ldb_dn_get_parent(mem_ctx, dn);
418 if (parent == NULL) {
419 talloc_free(mem_ctx);
420 Py_RETURN_NONE;
423 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
424 if (py_ret == NULL) {
425 PyErr_NoMemory();
426 talloc_free(mem_ctx);
427 return NULL;
429 py_ret->mem_ctx = mem_ctx;
430 py_ret->dn = parent;
431 return (PyObject *)py_ret;
434 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
436 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
438 PyObject *py_other;
439 struct ldb_dn *dn, *other;
440 if (!PyArg_ParseTuple(args, "O", &py_other))
441 return NULL;
443 dn = PyLdbDn_AsDn((PyObject *)self);
445 if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
446 return NULL;
448 return ldb_dn_add_child(dn, other)?Py_True:Py_False;
451 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
453 PyObject *py_other;
454 struct ldb_dn *other, *dn;
455 if (!PyArg_ParseTuple(args, "O", &py_other))
456 return NULL;
458 dn = PyLdbDn_AsDn((PyObject *)self);
460 if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
461 return NULL;
463 return ldb_dn_add_base(dn, other)?Py_True:Py_False;
466 static PyMethodDef py_ldb_dn_methods[] = {
467 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
468 "S.validate() -> bool\n"
469 "Validate DN is correct." },
470 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
471 "S.is_valid() -> bool\n" },
472 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
473 "S.is_special() -> bool\n"
474 "Check whether this is a special LDB DN." },
475 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
476 "Check whether this is a null DN." },
477 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
478 NULL },
479 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
480 NULL },
481 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
482 "S.canonical_str() -> string\n"
483 "Canonical version of this DN (like a posix path)." },
484 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
485 "S.canonical_ex_str() -> string\n"
486 "Canonical version of this DN (like a posix path, with terminating newline)." },
487 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
488 "S.parent() -> dn\n"
489 "Get the parent for this DN." },
490 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
491 "S.add_child(dn) -> None\n"
492 "Add a child DN to this DN." },
493 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
494 "S.add_base(dn) -> None\n"
495 "Add a base DN to this DN." },
496 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
497 "S.check_special(name) -> bool\n\n"
498 "Check if name is a special DN name"},
499 { NULL }
502 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
504 return ldb_dn_get_comp_num(PyLdbDn_AsDn((PyObject *)self));
507 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
509 struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self),
510 *other;
511 PyLdbDnObject *py_ret;
513 if (!PyObject_AsDn(NULL, py_other, NULL, &other))
514 return NULL;
516 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
517 if (py_ret == NULL) {
518 PyErr_NoMemory();
519 return NULL;
521 py_ret->mem_ctx = talloc_new(NULL);
522 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
523 ldb_dn_add_child(py_ret->dn, other);
524 return (PyObject *)py_ret;
527 static PySequenceMethods py_ldb_dn_seq = {
528 .sq_length = (lenfunc)py_ldb_dn_len,
529 .sq_concat = (binaryfunc)py_ldb_dn_concat,
532 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
534 struct ldb_dn *ret;
535 char *str;
536 PyObject *py_ldb;
537 struct ldb_context *ldb_ctx;
538 TALLOC_CTX *mem_ctx;
539 PyLdbDnObject *py_ret;
540 const char * const kwnames[] = { "ldb", "dn", NULL };
542 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
543 discard_const_p(char *, kwnames),
544 &py_ldb, &str))
545 return NULL;
547 ldb_ctx = PyLdb_AsLdbContext(py_ldb);
549 mem_ctx = talloc_new(NULL);
550 if (mem_ctx == NULL) {
551 PyErr_NoMemory();
552 return NULL;
555 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
556 if (!ldb_dn_validate(ret)) {
557 talloc_free(mem_ctx);
558 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
559 return NULL;
562 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
563 if (ret == NULL) {
564 talloc_free(mem_ctx);
565 PyErr_NoMemory();
566 return NULL;
568 py_ret->mem_ctx = mem_ctx;
569 py_ret->dn = ret;
570 return (PyObject *)py_ret;
573 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
575 talloc_free(self->mem_ctx);
576 PyObject_Del(self);
579 static PyTypeObject PyLdbDn = {
580 .tp_name = "ldb.Dn",
581 .tp_methods = py_ldb_dn_methods,
582 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
583 .tp_repr = (reprfunc)py_ldb_dn_repr,
584 .tp_compare = (cmpfunc)py_ldb_dn_compare,
585 .tp_as_sequence = &py_ldb_dn_seq,
586 .tp_doc = "A LDB distinguished name.",
587 .tp_new = py_ldb_dn_new,
588 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
589 .tp_basicsize = sizeof(PyLdbDnObject),
590 .tp_flags = Py_TPFLAGS_DEFAULT,
593 /* Debug */
594 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
595 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
597 PyObject *fn = (PyObject *)context;
598 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
601 static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args)
603 PyObject *cb;
605 if (!PyArg_ParseTuple(args, "O", &cb))
606 return NULL;
608 Py_INCREF(cb);
609 /* FIXME: Where do we DECREF cb ? */
610 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), PyLdb_AsLdbContext(self));
612 Py_RETURN_NONE;
615 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
617 unsigned int perms;
618 if (!PyArg_ParseTuple(args, "I", &perms))
619 return NULL;
621 ldb_set_create_perms(PyLdb_AsLdbContext(self), perms);
623 Py_RETURN_NONE;
626 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
628 char *modules_dir;
629 if (!PyArg_ParseTuple(args, "s", &modules_dir))
630 return NULL;
632 ldb_set_modules_dir(PyLdb_AsLdbContext(self), modules_dir);
634 Py_RETURN_NONE;
637 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
639 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_start(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
640 Py_RETURN_NONE;
643 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
645 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
646 Py_RETURN_NONE;
649 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
651 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_prepare_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
652 Py_RETURN_NONE;
655 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
657 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_cancel(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
658 Py_RETURN_NONE;
661 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
663 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_setup_wellknown_attributes(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
664 Py_RETURN_NONE;
667 static PyObject *py_ldb_repr(PyLdbObject *self)
669 return PyString_FromFormat("<ldb connection>");
672 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
674 struct ldb_dn *dn = ldb_get_root_basedn(PyLdb_AsLdbContext(self));
675 if (dn == NULL)
676 Py_RETURN_NONE;
677 return PyLdbDn_FromDn(dn);
681 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
683 struct ldb_dn *dn = ldb_get_schema_basedn(PyLdb_AsLdbContext(self));
684 if (dn == NULL)
685 Py_RETURN_NONE;
686 return PyLdbDn_FromDn(dn);
689 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
691 struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self));
692 if (dn == NULL)
693 Py_RETURN_NONE;
694 return PyLdbDn_FromDn(dn);
697 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
699 struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self));
700 if (dn == NULL)
701 Py_RETURN_NONE;
702 return PyLdbDn_FromDn(dn);
705 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
706 const char *paramname)
708 const char **ret;
709 Py_ssize_t i;
710 if (!PyList_Check(list)) {
711 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
712 return NULL;
714 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
715 if (ret == NULL) {
716 PyErr_NoMemory();
717 return NULL;
720 for (i = 0; i < PyList_Size(list); i++) {
721 PyObject *item = PyList_GetItem(list, i);
722 if (!PyString_Check(item)) {
723 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
724 return NULL;
726 ret[i] = talloc_strndup(ret, PyString_AsString(item),
727 PyString_Size(item));
729 ret[i] = NULL;
730 return ret;
733 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
735 const char * const kwnames[] = { "url", "flags", "options", NULL };
736 char *url = NULL;
737 PyObject *py_options = Py_None;
738 const char **options;
739 int flags = 0;
740 int ret;
741 struct ldb_context *ldb;
743 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO:Ldb.__init__",
744 discard_const_p(char *, kwnames),
745 &url, &flags, &py_options))
746 return -1;
748 ldb = PyLdb_AsLdbContext(self);
750 if (py_options == Py_None) {
751 options = NULL;
752 } else {
753 options = PyList_AsStringList(ldb, py_options, "options");
754 if (options == NULL)
755 return -1;
758 if (url != NULL) {
759 ret = ldb_connect(ldb, url, flags, options);
760 if (ret != LDB_SUCCESS) {
761 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
762 return -1;
766 talloc_free(options);
767 return 0;
770 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
772 PyLdbObject *ret;
773 struct ldb_context *ldb;
774 ret = (PyLdbObject *)type->tp_alloc(type, 0);
775 if (ret == NULL) {
776 PyErr_NoMemory();
777 return NULL;
779 ret->mem_ctx = talloc_new(NULL);
780 ldb = ldb_init(ret->mem_ctx, NULL);
782 if (ldb == NULL) {
783 PyErr_NoMemory();
784 return NULL;
787 ret->ldb_ctx = ldb;
788 return (PyObject *)ret;
791 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
793 char *url;
794 int flags = 0;
795 PyObject *py_options = Py_None;
796 int ret;
797 const char **options;
798 const char * const kwnames[] = { "url", "flags", "options", NULL };
800 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO",
801 discard_const_p(char *, kwnames),
802 &url, &flags, &py_options))
803 return NULL;
805 if (py_options == Py_None) {
806 options = NULL;
807 } else {
808 options = PyList_AsStringList(NULL, py_options, "options");
809 if (options == NULL)
810 return NULL;
813 ret = ldb_connect(PyLdb_AsLdbContext(self), url, flags, options);
814 talloc_free(options);
816 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
818 Py_RETURN_NONE;
821 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args)
823 PyObject *py_msg;
824 PyObject *py_controls = Py_None;
825 struct ldb_context *ldb_ctx;
826 struct ldb_request *req;
827 struct ldb_control **parsed_controls;
828 struct ldb_message *msg;
829 int ret;
830 TALLOC_CTX *mem_ctx;
832 if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls))
833 return NULL;
835 mem_ctx = talloc_new(NULL);
836 if (mem_ctx == NULL) {
837 PyErr_NoMemory();
838 return NULL;
840 ldb_ctx = PyLdb_AsLdbContext(self);
842 if (py_controls == Py_None) {
843 parsed_controls = NULL;
844 } else {
845 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
846 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
847 talloc_free(controls);
850 if (!PyLdbMessage_Check(py_msg)) {
851 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
852 talloc_free(mem_ctx);
853 return NULL;
855 msg = PyLdbMessage_AsMessage(py_msg);
857 ret = ldb_msg_sanity_check(ldb_ctx, msg);
858 if (ret != LDB_SUCCESS) {
859 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
860 talloc_free(mem_ctx);
861 return NULL;
864 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
865 NULL, ldb_op_default_callback, NULL);
866 if (ret != LDB_SUCCESS) {
867 PyErr_SetString(PyExc_TypeError, "failed to build request");
868 talloc_free(mem_ctx);
869 return NULL;
872 /* do request and autostart a transaction */
873 /* Then let's LDB handle the message error in case of pb as they are meaningful */
875 ret = ldb_transaction_start(ldb_ctx);
876 if (ret != LDB_SUCCESS) {
877 talloc_free(mem_ctx);
878 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
881 ret = ldb_request(ldb_ctx, req);
882 if (ret == LDB_SUCCESS) {
883 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
886 if (ret == LDB_SUCCESS) {
887 ret = ldb_transaction_commit(ldb_ctx);
888 } else {
889 ldb_transaction_cancel(ldb_ctx);
890 if (ldb_ctx->err_string == NULL) {
891 /* no error string was setup by the backend */
892 ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
896 talloc_free(mem_ctx);
897 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
899 Py_RETURN_NONE;
904 * Obtain a ldb message from a Python Dictionary object.
906 * @param mem_ctx Memory context
907 * @param py_obj Python Dictionary object
908 * @param ldb_ctx LDB context
909 * @param mod_flags Flags to be set on every message element
910 * @return ldb_message on success or NULL on failure
912 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
913 PyObject *py_obj,
914 struct ldb_context *ldb_ctx,
915 unsigned int mod_flags)
917 struct ldb_message *msg;
918 unsigned int msg_pos = 0;
919 Py_ssize_t dict_pos = 0;
920 PyObject *key, *value;
921 struct ldb_message_element *msg_el;
922 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
924 msg = ldb_msg_new(mem_ctx);
925 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
927 if (dn_value) {
928 if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
929 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
930 return NULL;
932 if (msg->dn == NULL) {
933 PyErr_SetString(PyExc_TypeError, "dn set but not found");
934 return NULL;
936 } else {
937 PyErr_SetString(PyExc_TypeError, "no dn set");
938 return NULL;
941 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
942 char *key_str = PyString_AsString(key);
943 if (strcmp(key_str, "dn") != 0) {
944 msg_el = PyObject_AsMessageElement(msg->elements, value,
945 mod_flags, key_str);
946 if (msg_el == NULL) {
947 PyErr_SetString(PyExc_TypeError, "unable to import element");
948 return NULL;
950 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
951 msg_pos++;
955 msg->num_elements = msg_pos;
957 return msg;
960 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
962 PyObject *py_obj;
963 int ret;
964 struct ldb_context *ldb_ctx;
965 struct ldb_request *req;
966 struct ldb_message *msg = NULL;
967 PyObject *py_controls = Py_None;
968 TALLOC_CTX *mem_ctx;
969 struct ldb_control **parsed_controls;
971 if (!PyArg_ParseTuple(args, "O|O", &py_obj, &py_controls ))
972 return NULL;
974 mem_ctx = talloc_new(NULL);
975 if (mem_ctx == NULL) {
976 PyErr_NoMemory();
977 return NULL;
979 ldb_ctx = PyLdb_AsLdbContext(self);
981 if (py_controls == Py_None) {
982 parsed_controls = NULL;
983 } else {
984 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
985 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
986 talloc_free(controls);
989 if (PyLdbMessage_Check(py_obj)) {
990 msg = PyLdbMessage_AsMessage(py_obj);
991 } else if (PyDict_Check(py_obj)) {
992 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
993 } else {
994 PyErr_SetString(PyExc_TypeError,
995 "Dictionary or LdbMessage object expected!");
998 if (!msg) {
999 /* we should have a PyErr already set */
1000 talloc_free(mem_ctx);
1001 return NULL;
1004 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1005 if (ret != LDB_SUCCESS) {
1006 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1007 talloc_free(mem_ctx);
1008 return NULL;
1011 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1012 NULL, ldb_op_default_callback, NULL);
1013 if (ret != LDB_SUCCESS) {
1014 PyErr_SetString(PyExc_TypeError, "failed to build request");
1015 talloc_free(mem_ctx);
1016 return NULL;
1019 /* do request and autostart a transaction */
1020 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1022 ret = ldb_transaction_start(ldb_ctx);
1023 if (ret != LDB_SUCCESS) {
1024 talloc_free(mem_ctx);
1025 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1028 ret = ldb_request(ldb_ctx, req);
1029 if (ret == LDB_SUCCESS) {
1030 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1033 if (ret == LDB_SUCCESS) {
1034 ret = ldb_transaction_commit(ldb_ctx);
1035 } else {
1036 ldb_transaction_cancel(ldb_ctx);
1037 if (ldb_ctx->err_string == NULL) {
1038 /* no error string was setup by the backend */
1039 ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
1043 talloc_free(mem_ctx);
1044 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1046 Py_RETURN_NONE;
1049 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args)
1051 PyObject *py_dn;
1052 struct ldb_dn *dn;
1053 int ret;
1054 struct ldb_context *ldb_ctx;
1055 struct ldb_request *req;
1056 PyObject *py_controls = Py_None;
1057 TALLOC_CTX *mem_ctx;
1058 struct ldb_control **parsed_controls;
1060 if (!PyArg_ParseTuple(args, "O|O", &py_dn, &py_controls))
1061 return NULL;
1063 mem_ctx = talloc_new(NULL);
1064 if (mem_ctx == NULL) {
1065 PyErr_NoMemory();
1066 return NULL;
1068 ldb_ctx = PyLdb_AsLdbContext(self);
1070 if (py_controls == Py_None) {
1071 parsed_controls = NULL;
1072 } else {
1073 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1074 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1075 talloc_free(controls);
1078 if (!PyObject_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1079 talloc_free(mem_ctx);
1080 return NULL;
1083 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1084 NULL, ldb_op_default_callback, NULL);
1085 if (ret != LDB_SUCCESS) {
1086 PyErr_SetString(PyExc_TypeError, "failed to build request");
1087 talloc_free(mem_ctx);
1088 return NULL;
1091 /* do request and autostart a transaction */
1092 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1094 ret = ldb_transaction_start(ldb_ctx);
1095 if (ret != LDB_SUCCESS) {
1096 talloc_free(mem_ctx);
1097 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1100 ret = ldb_request(ldb_ctx, req);
1101 if (ret == LDB_SUCCESS) {
1102 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1105 if (ret == LDB_SUCCESS) {
1106 ret = ldb_transaction_commit(ldb_ctx);
1107 } else {
1108 ldb_transaction_cancel(ldb_ctx);
1109 if (ldb_ctx->err_string == NULL) {
1110 /* no error string was setup by the backend */
1111 ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
1115 talloc_free(mem_ctx);
1116 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1118 Py_RETURN_NONE;
1121 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args)
1123 PyObject *py_dn1, *py_dn2;
1124 struct ldb_dn *dn1, *dn2;
1125 int ret;
1126 struct ldb_context *ldb;
1127 TALLOC_CTX *mem_ctx;
1128 PyObject *py_controls = Py_None;
1129 struct ldb_control **parsed_controls;
1130 struct ldb_context *ldb_ctx;
1131 struct ldb_request *req;
1133 ldb_ctx = PyLdb_AsLdbContext(self);
1135 if (!PyArg_ParseTuple(args, "OO|O", &py_dn1, &py_dn2, &py_controls))
1136 return NULL;
1139 mem_ctx = talloc_new(NULL);
1140 if (mem_ctx == NULL) {
1141 PyErr_NoMemory();
1142 return NULL;
1144 ldb = PyLdb_AsLdbContext(self);
1146 if (py_controls == Py_None) {
1147 parsed_controls = NULL;
1148 } else {
1149 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1150 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1151 talloc_free(controls);
1155 if (!PyObject_AsDn(mem_ctx, py_dn1, ldb, &dn1)) {
1156 talloc_free(mem_ctx);
1157 return NULL;
1160 if (!PyObject_AsDn(mem_ctx, py_dn2, ldb, &dn2)) {
1161 talloc_free(mem_ctx);
1162 return NULL;
1165 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1166 NULL, ldb_op_default_callback, NULL);
1167 if (ret != LDB_SUCCESS) {
1168 PyErr_SetString(PyExc_TypeError, "failed to build request");
1169 talloc_free(mem_ctx);
1170 return NULL;
1173 /* do request and autostart a transaction */
1174 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1176 ret = ldb_transaction_start(ldb_ctx);
1177 if (ret != LDB_SUCCESS) {
1178 talloc_free(mem_ctx);
1179 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1182 ret = ldb_request(ldb_ctx, req);
1183 if (ret == LDB_SUCCESS) {
1184 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1187 if (ret == LDB_SUCCESS) {
1188 ret = ldb_transaction_commit(ldb_ctx);
1189 } else {
1190 ldb_transaction_cancel(ldb_ctx);
1191 if (ldb_ctx->err_string == NULL) {
1192 /* no error string was setup by the backend */
1193 ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
1197 talloc_free(mem_ctx);
1198 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1200 Py_RETURN_NONE;
1203 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1205 char *name;
1206 if (!PyArg_ParseTuple(args, "s", &name))
1207 return NULL;
1209 ldb_schema_attribute_remove(PyLdb_AsLdbContext(self), name);
1211 Py_RETURN_NONE;
1214 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1216 char *attribute, *syntax;
1217 unsigned int flags;
1218 int ret;
1219 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1220 return NULL;
1222 ret = ldb_schema_attribute_add(PyLdb_AsLdbContext(self), attribute, flags, syntax);
1224 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
1226 Py_RETURN_NONE;
1229 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1231 if (ldif == NULL) {
1232 Py_RETURN_NONE;
1233 } else {
1234 /* We don't want this attached to the 'ldb' any more */
1235 return Py_BuildValue(discard_const_p(char, "(iO)"),
1236 ldif->changetype,
1237 PyLdbMessage_FromMessage(ldif->msg));
1242 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1244 int changetype;
1245 PyObject *py_msg;
1246 struct ldb_ldif ldif;
1247 PyObject *ret;
1248 char *string;
1249 TALLOC_CTX *mem_ctx;
1251 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1252 return NULL;
1254 if (!PyLdbMessage_Check(py_msg)) {
1255 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1256 return NULL;
1259 ldif.msg = PyLdbMessage_AsMessage(py_msg);
1260 ldif.changetype = changetype;
1262 mem_ctx = talloc_new(NULL);
1264 string = ldb_ldif_write_string(PyLdb_AsLdbContext(self), mem_ctx, &ldif);
1265 if (!string) {
1266 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1267 return NULL;
1270 ret = PyString_FromString(string);
1272 talloc_free(mem_ctx);
1274 return ret;
1277 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1279 PyObject *list;
1280 struct ldb_ldif *ldif;
1281 const char *s;
1283 TALLOC_CTX *mem_ctx;
1285 if (!PyArg_ParseTuple(args, "s", &s))
1286 return NULL;
1288 mem_ctx = talloc_new(NULL);
1289 if (!mem_ctx) {
1290 Py_RETURN_NONE;
1293 list = PyList_New(0);
1294 while (s && *s != '\0') {
1295 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1296 talloc_steal(mem_ctx, ldif);
1297 if (ldif) {
1298 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1299 } else {
1300 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1301 talloc_free(mem_ctx);
1302 return NULL;
1305 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1306 return PyObject_GetIter(list);
1309 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1311 int ldb_ret;
1312 PyObject *py_msg_old;
1313 PyObject *py_msg_new;
1314 struct ldb_message *diff;
1315 struct ldb_context *ldb;
1316 PyObject *py_ret;
1318 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1319 return NULL;
1321 if (!PyLdbMessage_Check(py_msg_old)) {
1322 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1323 return NULL;
1326 if (!PyLdbMessage_Check(py_msg_new)) {
1327 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1328 return NULL;
1331 ldb = PyLdb_AsLdbContext(self);
1332 ldb_ret = ldb_msg_difference(ldb, ldb,
1333 PyLdbMessage_AsMessage(py_msg_old),
1334 PyLdbMessage_AsMessage(py_msg_new),
1335 &diff);
1336 if (ldb_ret != LDB_SUCCESS) {
1337 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1338 return NULL;
1341 py_ret = PyLdbMessage_FromMessage(diff);
1343 talloc_unlink(ldb, diff);
1345 return py_ret;
1348 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1350 const struct ldb_schema_attribute *a;
1351 struct ldb_val old_val;
1352 struct ldb_val new_val;
1353 TALLOC_CTX *mem_ctx;
1354 PyObject *ret;
1355 char *element_name;
1356 PyObject *val;
1358 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1359 return NULL;
1361 mem_ctx = talloc_new(NULL);
1363 old_val.data = (uint8_t *)PyString_AsString(val);
1364 old_val.length = PyString_Size(val);
1366 a = ldb_schema_attribute_by_name(PyLdb_AsLdbContext(self), element_name);
1368 if (a == NULL) {
1369 Py_RETURN_NONE;
1372 if (a->syntax->ldif_write_fn(PyLdb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1373 talloc_free(mem_ctx);
1374 Py_RETURN_NONE;
1377 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1379 talloc_free(mem_ctx);
1381 return ret;
1384 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1386 PyObject *py_base = Py_None;
1387 int scope = LDB_SCOPE_DEFAULT;
1388 char *expr = NULL;
1389 PyObject *py_attrs = Py_None;
1390 PyObject *py_controls = Py_None;
1391 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1392 int ret;
1393 struct ldb_result *res;
1394 struct ldb_request *req;
1395 const char **attrs;
1396 struct ldb_context *ldb_ctx;
1397 struct ldb_control **parsed_controls;
1398 struct ldb_dn *base;
1399 PyObject *py_ret;
1400 TALLOC_CTX *mem_ctx;
1402 /* type "int" rather than "enum" for "scope" is intentional */
1403 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1404 discard_const_p(char *, kwnames),
1405 &py_base, &scope, &expr, &py_attrs, &py_controls))
1406 return NULL;
1409 mem_ctx = talloc_new(NULL);
1410 if (mem_ctx == NULL) {
1411 PyErr_NoMemory();
1412 return NULL;
1414 ldb_ctx = PyLdb_AsLdbContext(self);
1416 if (py_attrs == Py_None) {
1417 attrs = NULL;
1418 } else {
1419 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1420 if (attrs == NULL) {
1421 talloc_free(mem_ctx);
1422 return NULL;
1426 if (py_base == Py_None) {
1427 base = ldb_get_default_basedn(ldb_ctx);
1428 } else {
1429 if (!PyObject_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1430 talloc_free(attrs);
1431 return NULL;
1435 if (py_controls == Py_None) {
1436 parsed_controls = NULL;
1437 } else {
1438 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1439 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1440 talloc_free(controls);
1443 res = talloc_zero(mem_ctx, struct ldb_result);
1444 if (res == NULL) {
1445 PyErr_NoMemory();
1446 talloc_free(mem_ctx);
1447 return NULL;
1450 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1451 base,
1452 scope,
1453 expr,
1454 attrs,
1455 parsed_controls,
1456 res,
1457 ldb_search_default_callback,
1458 NULL);
1460 if (ret != LDB_SUCCESS) {
1461 talloc_free(mem_ctx);
1462 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1463 return NULL;
1466 talloc_steal(req, attrs);
1468 ret = ldb_request(ldb_ctx, req);
1470 if (ret == LDB_SUCCESS) {
1471 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1474 if (ret != LDB_SUCCESS) {
1475 talloc_free(mem_ctx);
1476 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1477 return NULL;
1480 py_ret = PyLdbResult_FromResult(res);
1482 talloc_free(mem_ctx);
1484 return py_ret;
1487 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1489 char *name;
1490 void *data;
1492 if (!PyArg_ParseTuple(args, "s", &name))
1493 return NULL;
1495 data = ldb_get_opaque(PyLdb_AsLdbContext(self), name);
1497 if (data == NULL)
1498 Py_RETURN_NONE;
1500 /* FIXME: More interpretation */
1502 return Py_True;
1505 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1507 char *name;
1508 PyObject *data;
1510 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1511 return NULL;
1513 /* FIXME: More interpretation */
1515 ldb_set_opaque(PyLdb_AsLdbContext(self), name, data);
1517 Py_RETURN_NONE;
1520 static PyObject *py_ldb_modules(PyLdbObject *self)
1522 struct ldb_context *ldb = PyLdb_AsLdbContext(self);
1523 PyObject *ret = PyList_New(0);
1524 struct ldb_module *mod;
1526 for (mod = ldb->modules; mod; mod = mod->next) {
1527 PyList_Append(ret, PyLdbModule_FromModule(mod));
1530 return ret;
1533 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1535 struct ldb_context *ldb = PyLdb_AsLdbContext(self);
1536 int type, ret;
1537 uint64_t value;
1539 if (!PyArg_ParseTuple(args, "i", &type))
1540 return NULL;
1542 /* FIXME: More interpretation */
1544 ret = ldb_sequence_number(ldb, type, &value);
1546 if (ret != LDB_SUCCESS) {
1547 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1548 return NULL;
1550 return PyLong_FromLongLong(value);
1552 static PyMethodDef py_ldb_methods[] = {
1553 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1554 "S.set_debug(callback) -> None\n"
1555 "Set callback for LDB debug messages.\n"
1556 "The callback should accept a debug level and debug text." },
1557 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1558 "S.set_create_perms(mode) -> None\n"
1559 "Set mode to use when creating new LDB files." },
1560 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1561 "S.set_modules_dir(path) -> None\n"
1562 "Set path LDB should search for modules" },
1563 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1564 "S.transaction_start() -> None\n"
1565 "Start a new transaction." },
1566 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1567 "S.transaction_prepare_commit() -> None\n"
1568 "prepare to commit a new transaction (2-stage commit)." },
1569 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1570 "S.transaction_commit() -> None\n"
1571 "commit a new transaction." },
1572 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1573 "S.transaction_cancel() -> None\n"
1574 "cancel a new transaction." },
1575 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1576 NULL },
1577 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1578 NULL },
1579 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1580 NULL },
1581 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1582 NULL },
1583 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1584 NULL },
1585 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1586 "S.connect(url, flags=0, options=None) -> None\n"
1587 "Connect to a LDB URL." },
1588 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS,
1589 "S.modify(message) -> None\n"
1590 "Modify an entry." },
1591 { "add", (PyCFunction)py_ldb_add, METH_VARARGS,
1592 "S.add(message) -> None\n"
1593 "Add an entry." },
1594 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS,
1595 "S.delete(dn) -> None\n"
1596 "Remove an entry." },
1597 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS,
1598 "S.rename(old_dn, new_dn) -> None\n"
1599 "Rename an entry." },
1600 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1601 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1602 "Search in a database.\n"
1603 "\n"
1604 ":param base: Optional base DN to search\n"
1605 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1606 ":param expression: Optional search expression\n"
1607 ":param attrs: Attributes to return (defaults to all)\n"
1608 ":param controls: Optional list of controls\n"
1609 ":return: Iterator over Message objects\n"
1611 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1612 NULL },
1613 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1614 NULL },
1615 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1616 NULL },
1617 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1618 "S.parse_ldif(ldif) -> iter(messages)\n"
1619 "Parse a string formatted using LDIF." },
1620 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1621 "S.write_ldif(message, changetype) -> ldif\n"
1622 "Print the message as a string formatted using LDIF." },
1623 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1624 "S.msg_diff(Message) -> Message\n"
1625 "Return an LDB Message of the difference between two Message objects." },
1626 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1627 "S.get_opaque(name) -> value\n"
1628 "Get an opaque value set on this LDB connection. \n"
1629 ":note: The returned value may not be useful in Python."
1631 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1632 "S.set_opaque(name, value) -> None\n"
1633 "Set an opaque value on this LDB connection. \n"
1634 ":note: Passing incorrect values may cause crashes." },
1635 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1636 "S.modules() -> list\n"
1637 "Return the list of modules on this LDB connection " },
1638 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1639 "S.sequence_number(type) -> value\n"
1640 "Return the value of the sequence according to the requested type" },
1641 { NULL },
1644 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1646 PyLdbModuleObject *ret;
1648 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1649 if (ret == NULL) {
1650 PyErr_NoMemory();
1651 return NULL;
1653 ret->mem_ctx = talloc_new(NULL);
1654 ret->mod = talloc_reference(ret->mem_ctx, mod);
1655 return (PyObject *)ret;
1658 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1660 return PyLdbModule_FromModule(PyLdb_AsLdbContext(self)->modules);
1663 static PyGetSetDef py_ldb_getset[] = {
1664 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1665 { NULL }
1668 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1670 struct ldb_context *ldb_ctx = PyLdb_AsLdbContext(self);
1671 struct ldb_dn *dn;
1672 struct ldb_result *result;
1673 unsigned int count;
1674 int ret;
1676 if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1677 return -1;
1680 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1681 NULL);
1682 if (ret != LDB_SUCCESS) {
1683 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1684 return -1;
1687 count = result->count;
1689 talloc_free(result);
1691 if (count > 1) {
1692 PyErr_Format(PyExc_RuntimeError,
1693 "Searching for [%s] dn gave %u results!",
1694 ldb_dn_get_linearized(dn),
1695 count);
1696 return -1;
1699 return count;
1702 static PySequenceMethods py_ldb_seq = {
1703 .sq_contains = (objobjproc)py_ldb_contains,
1706 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1708 PyLdbObject *ret;
1710 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1711 if (ret == NULL) {
1712 PyErr_NoMemory();
1713 return NULL;
1715 ret->mem_ctx = talloc_new(NULL);
1716 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1717 return (PyObject *)ret;
1720 static void py_ldb_dealloc(PyLdbObject *self)
1722 talloc_free(self->mem_ctx);
1723 self->ob_type->tp_free(self);
1726 static PyTypeObject PyLdb = {
1727 .tp_name = "ldb.Ldb",
1728 .tp_methods = py_ldb_methods,
1729 .tp_repr = (reprfunc)py_ldb_repr,
1730 .tp_new = py_ldb_new,
1731 .tp_init = (initproc)py_ldb_init,
1732 .tp_dealloc = (destructor)py_ldb_dealloc,
1733 .tp_getset = py_ldb_getset,
1734 .tp_getattro = PyObject_GenericGetAttr,
1735 .tp_basicsize = sizeof(PyLdbObject),
1736 .tp_doc = "Connection to a LDB database.",
1737 .tp_as_sequence = &py_ldb_seq,
1738 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1741 static void py_ldb_result_dealloc(PyLdbResultObject *self)
1743 talloc_free(self->mem_ctx);
1744 Py_DECREF(self->msgs);
1745 Py_DECREF(self->referals);
1746 Py_DECREF(self->controls);
1747 self->ob_type->tp_free(self);
1750 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
1752 Py_INCREF(self->msgs);
1753 return self->msgs;
1756 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
1758 Py_INCREF(self->controls);
1759 return self->controls;
1762 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
1764 Py_INCREF(self->referals);
1765 return self->referals;
1768 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
1770 Py_ssize_t size;
1771 if (self->msgs == NULL) {
1772 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
1773 return NULL;
1775 size = PyList_Size(self->msgs);
1776 return PyInt_FromLong(size);
1779 static PyGetSetDef py_ldb_result_getset[] = {
1780 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
1781 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
1782 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
1783 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
1784 { NULL }
1787 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
1789 return PyObject_GetIter(self->msgs);
1792 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
1794 return PySequence_Size(self->msgs);
1797 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
1799 return PySequence_GetItem(self->msgs, idx);
1802 static PySequenceMethods py_ldb_result_seq = {
1803 .sq_length = (lenfunc)py_ldb_result_len,
1804 .sq_item = (ssizeargfunc)py_ldb_result_find,
1807 static PyObject *py_ldb_result_repr(PyLdbObject *self)
1809 return PyString_FromFormat("<ldb result>");
1813 static PyTypeObject PyLdbResult = {
1814 .tp_name = "ldb.Result",
1815 .tp_repr = (reprfunc)py_ldb_result_repr,
1816 .tp_dealloc = (destructor)py_ldb_result_dealloc,
1817 .tp_iter = (getiterfunc)py_ldb_result_iter,
1818 .tp_getset = py_ldb_result_getset,
1819 .tp_getattro = PyObject_GenericGetAttr,
1820 .tp_basicsize = sizeof(PyLdbResultObject),
1821 .tp_as_sequence = &py_ldb_result_seq,
1822 .tp_doc = "LDB result.",
1823 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1826 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1828 return PyString_FromFormat("<ldb module '%s'>", PyLdbModule_AsModule(self)->ops->name);
1831 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1833 return PyString_FromString(PyLdbModule_AsModule(self)->ops->name);
1836 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1838 PyLdbModule_AsModule(self)->ops->start_transaction(PyLdbModule_AsModule(self));
1839 Py_RETURN_NONE;
1842 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1844 PyLdbModule_AsModule(self)->ops->end_transaction(PyLdbModule_AsModule(self));
1845 Py_RETURN_NONE;
1848 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
1850 PyLdbModule_AsModule(self)->ops->del_transaction(PyLdbModule_AsModule(self));
1851 Py_RETURN_NONE;
1854 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
1856 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
1857 int ret, scope;
1858 struct ldb_request *req;
1859 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
1860 struct ldb_module *mod;
1861 const char * const*attrs;
1863 /* type "int" rather than "enum" for "scope" is intentional */
1864 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
1865 discard_const_p(char *, kwnames),
1866 &py_base, &scope, &py_tree, &py_attrs))
1867 return NULL;
1869 mod = self->mod;
1871 if (py_attrs == Py_None) {
1872 attrs = NULL;
1873 } else {
1874 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
1875 if (attrs == NULL)
1876 return NULL;
1879 ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base),
1880 scope, NULL /* expr */, attrs,
1881 NULL /* controls */, NULL, NULL, NULL);
1883 talloc_steal(req, attrs);
1885 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1887 req->op.search.res = NULL;
1889 ret = mod->ops->search(mod, req);
1891 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1893 py_ret = PyLdbResult_FromResult(req->op.search.res);
1895 talloc_free(req);
1897 return py_ret;
1901 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
1903 struct ldb_request *req;
1904 PyObject *py_message;
1905 int ret;
1906 struct ldb_module *mod;
1908 if (!PyArg_ParseTuple(args, "O", &py_message))
1909 return NULL;
1911 req = talloc_zero(NULL, struct ldb_request);
1912 req->operation = LDB_ADD;
1913 req->op.add.message = PyLdbMessage_AsMessage(py_message);
1915 mod = PyLdbModule_AsModule(self);
1916 ret = mod->ops->add(mod, req);
1918 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1920 Py_RETURN_NONE;
1923 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
1925 int ret;
1926 struct ldb_request *req;
1927 PyObject *py_message;
1928 struct ldb_module *mod;
1930 if (!PyArg_ParseTuple(args, "O", &py_message))
1931 return NULL;
1933 req = talloc_zero(NULL, struct ldb_request);
1934 req->operation = LDB_MODIFY;
1935 req->op.mod.message = PyLdbMessage_AsMessage(py_message);
1937 mod = PyLdbModule_AsModule(self);
1938 ret = mod->ops->modify(mod, req);
1940 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1942 Py_RETURN_NONE;
1945 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
1947 int ret;
1948 struct ldb_request *req;
1949 PyObject *py_dn;
1951 if (!PyArg_ParseTuple(args, "O", &py_dn))
1952 return NULL;
1954 req = talloc_zero(NULL, struct ldb_request);
1955 req->operation = LDB_DELETE;
1956 req->op.del.dn = PyLdbDn_AsDn(py_dn);
1958 ret = PyLdbModule_AsModule(self)->ops->del(PyLdbModule_AsModule(self), req);
1960 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1962 Py_RETURN_NONE;
1965 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
1967 int ret;
1968 struct ldb_request *req;
1969 PyObject *py_dn1, *py_dn2;
1971 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
1972 return NULL;
1974 req = talloc_zero(NULL, struct ldb_request);
1976 req->operation = LDB_RENAME;
1977 req->op.rename.olddn = PyLdbDn_AsDn(py_dn1);
1978 req->op.rename.newdn = PyLdbDn_AsDn(py_dn2);
1980 ret = PyLdbModule_AsModule(self)->ops->rename(PyLdbModule_AsModule(self), req);
1982 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1984 Py_RETURN_NONE;
1987 static PyMethodDef py_ldb_module_methods[] = {
1988 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
1989 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
1990 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
1991 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
1992 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
1993 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
1994 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
1995 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
1996 { NULL },
1999 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2001 talloc_free(self->mem_ctx);
2002 PyObject_Del(self);
2005 static PyTypeObject PyLdbModule = {
2006 .tp_name = "ldb.LdbModule",
2007 .tp_methods = py_ldb_module_methods,
2008 .tp_repr = (reprfunc)py_ldb_module_repr,
2009 .tp_str = (reprfunc)py_ldb_module_str,
2010 .tp_basicsize = sizeof(PyLdbModuleObject),
2011 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2012 .tp_flags = Py_TPFLAGS_DEFAULT,
2017 * Create a ldb_message_element from a Python object.
2019 * This will accept any sequence objects that contains strings, or
2020 * a string object.
2022 * A reference to set_obj will be borrowed.
2024 * @param mem_ctx Memory context
2025 * @param set_obj Python object to convert
2026 * @param flags ldb_message_element flags to set
2027 * @param attr_name Name of the attribute
2028 * @return New ldb_message_element, allocated as child of mem_ctx
2030 static struct ldb_message_element *PyObject_AsMessageElement(
2031 TALLOC_CTX *mem_ctx,
2032 PyObject *set_obj,
2033 int flags,
2034 const char *attr_name)
2036 struct ldb_message_element *me;
2038 if (PyLdbMessageElement_Check(set_obj)) {
2039 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2040 /* We have to talloc_reference() the memory context, not the pointer
2041 * which may not actually be it's own context */
2042 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2043 return PyLdbMessageElement_AsMessageElement(set_obj);
2045 return NULL;
2048 me = talloc(mem_ctx, struct ldb_message_element);
2049 if (me == NULL) {
2050 PyErr_NoMemory();
2051 return NULL;
2054 me->name = talloc_strdup(me, attr_name);
2055 me->flags = flags;
2056 if (PyString_Check(set_obj)) {
2057 me->num_values = 1;
2058 me->values = talloc_array(me, struct ldb_val, me->num_values);
2059 me->values[0].length = PyString_Size(set_obj);
2060 me->values[0].data = talloc_memdup(me,
2061 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2062 } else if (PySequence_Check(set_obj)) {
2063 Py_ssize_t i;
2064 me->num_values = PySequence_Size(set_obj);
2065 me->values = talloc_array(me, struct ldb_val, me->num_values);
2066 for (i = 0; i < me->num_values; i++) {
2067 PyObject *obj = PySequence_GetItem(set_obj, i);
2068 if (!PyString_Check(obj)) {
2069 PyErr_Format(PyExc_TypeError,
2070 "Expected string as element %zd in list", i);
2071 talloc_free(me);
2072 return NULL;
2075 me->values[i].length = PyString_Size(obj);
2076 me->values[i].data = talloc_memdup(me,
2077 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2079 } else {
2080 talloc_free(me);
2081 me = NULL;
2084 return me;
2088 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2089 struct ldb_message_element *me)
2091 Py_ssize_t i;
2092 PyObject *result;
2094 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2095 result = PyList_New(me->num_values);
2097 for (i = 0; i < me->num_values; i++) {
2098 PyList_SetItem(result, i,
2099 PyObject_FromLdbValue(&me->values[i]));
2102 return result;
2105 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2107 unsigned int i;
2108 if (!PyArg_ParseTuple(args, "I", &i))
2109 return NULL;
2110 if (i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
2111 Py_RETURN_NONE;
2113 return PyObject_FromLdbValue(&(PyLdbMessageElement_AsMessageElement(self)->values[i]));
2116 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2118 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
2119 return PyInt_FromLong(el->flags);
2122 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2124 int flags;
2125 struct ldb_message_element *el;
2126 if (!PyArg_ParseTuple(args, "i", &flags))
2127 return NULL;
2129 el = PyLdbMessageElement_AsMessageElement(self);
2130 el->flags = flags;
2131 Py_RETURN_NONE;
2134 static PyMethodDef py_ldb_msg_element_methods[] = {
2135 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2136 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2137 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2138 { NULL },
2141 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2143 return PyLdbMessageElement_AsMessageElement(self)->num_values;
2146 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2148 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
2149 if (idx < 0 || idx >= el->num_values) {
2150 PyErr_SetString(PyExc_IndexError, "Out of range");
2151 return NULL;
2153 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2156 static PySequenceMethods py_ldb_msg_element_seq = {
2157 .sq_length = (lenfunc)py_ldb_msg_element_len,
2158 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2161 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2163 int ret = ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self),
2164 PyLdbMessageElement_AsMessageElement(other));
2165 return SIGN(ret);
2168 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2170 return PyObject_GetIter(ldb_msg_element_to_set(NULL, PyLdbMessageElement_AsMessageElement(self)));
2173 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2175 PyLdbMessageElementObject *ret;
2176 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2177 if (ret == NULL) {
2178 PyErr_NoMemory();
2179 return NULL;
2181 ret->mem_ctx = talloc_new(NULL);
2182 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2183 PyErr_NoMemory();
2184 return NULL;
2186 ret->el = el;
2187 return (PyObject *)ret;
2190 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2192 PyObject *py_elements = NULL;
2193 struct ldb_message_element *el;
2194 int flags = 0;
2195 char *name = NULL;
2196 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2197 PyLdbMessageElementObject *ret;
2198 TALLOC_CTX *mem_ctx;
2200 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Ois",
2201 discard_const_p(char *, kwnames),
2202 &py_elements, &flags, &name))
2203 return NULL;
2205 mem_ctx = talloc_new(NULL);
2206 if (mem_ctx == NULL) {
2207 PyErr_NoMemory();
2208 return NULL;
2211 el = talloc_zero(mem_ctx, struct ldb_message_element);
2212 if (el == NULL) {
2213 PyErr_NoMemory();
2214 talloc_free(mem_ctx);
2215 return NULL;
2218 if (py_elements != NULL) {
2219 Py_ssize_t i;
2220 if (PyString_Check(py_elements)) {
2221 el->num_values = 1;
2222 el->values = talloc_array(el, struct ldb_val, 1);
2223 if (el->values == NULL) {
2224 talloc_free(mem_ctx);
2225 PyErr_NoMemory();
2226 return NULL;
2228 el->values[0].length = PyString_Size(py_elements);
2229 el->values[0].data = talloc_memdup(el->values,
2230 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2231 } else if (PySequence_Check(py_elements)) {
2232 el->num_values = PySequence_Size(py_elements);
2233 el->values = talloc_array(el, struct ldb_val, el->num_values);
2234 if (el->values == NULL) {
2235 talloc_free(mem_ctx);
2236 PyErr_NoMemory();
2237 return NULL;
2239 for (i = 0; i < el->num_values; i++) {
2240 PyObject *item = PySequence_GetItem(py_elements, i);
2241 if (item == NULL) {
2242 talloc_free(mem_ctx);
2243 return NULL;
2245 if (!PyString_Check(item)) {
2246 PyErr_Format(PyExc_TypeError,
2247 "Expected string as element %zd in list", i);
2248 talloc_free(mem_ctx);
2249 return NULL;
2251 el->values[i].length = PyString_Size(item);
2252 el->values[i].data = talloc_memdup(el,
2253 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2255 } else {
2256 PyErr_SetString(PyExc_TypeError,
2257 "Expected string or list");
2258 talloc_free(mem_ctx);
2259 return NULL;
2263 el->flags = flags;
2264 el->name = talloc_strdup(el, name);
2266 ret = PyObject_New(PyLdbMessageElementObject, type);
2267 if (ret == NULL) {
2268 talloc_free(mem_ctx);
2269 return NULL;
2272 ret->mem_ctx = mem_ctx;
2273 ret->el = el;
2274 return (PyObject *)ret;
2277 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2279 char *element_str = NULL;
2280 Py_ssize_t i;
2281 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
2282 PyObject *ret;
2284 for (i = 0; i < el->num_values; i++) {
2285 PyObject *o = py_ldb_msg_element_find(self, i);
2286 if (element_str == NULL)
2287 element_str = talloc_strdup(NULL, PyObject_REPR(o));
2288 else
2289 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2292 if (element_str != NULL) {
2293 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2294 talloc_free(element_str);
2295 } else {
2296 ret = PyString_FromString("MessageElement([])");
2299 return ret;
2302 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2304 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
2306 if (el->num_values == 1)
2307 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2308 else
2309 Py_RETURN_NONE;
2312 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2314 talloc_free(self->mem_ctx);
2315 PyObject_Del(self);
2318 static PyTypeObject PyLdbMessageElement = {
2319 .tp_name = "ldb.MessageElement",
2320 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2321 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2322 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2323 .tp_str = (reprfunc)py_ldb_msg_element_str,
2324 .tp_methods = py_ldb_msg_element_methods,
2325 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2326 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2327 .tp_as_sequence = &py_ldb_msg_element_seq,
2328 .tp_new = py_ldb_msg_element_new,
2329 .tp_flags = Py_TPFLAGS_DEFAULT,
2333 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2335 PyObject *py_ldb;
2336 PyObject *py_dict;
2337 PyObject *py_ret;
2338 struct ldb_message *msg;
2339 struct ldb_context *ldb_ctx;
2340 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2342 if (!PyArg_ParseTuple(args, "O!O!|I",
2343 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2344 &mod_flags)) {
2345 return NULL;
2348 /* mask only flags we are going to use */
2349 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2350 if (!mod_flags) {
2351 PyErr_SetString(PyExc_ValueError,
2352 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2353 " expected as mod_flag value");
2354 return NULL;
2357 ldb_ctx = PyLdb_AsLdbContext(py_ldb);
2359 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2360 if (!msg) {
2361 return NULL;
2364 py_ret = PyLdbMessage_FromMessage(msg);
2366 talloc_unlink(ldb_ctx, msg);
2368 return py_ret;
2371 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2373 char *name;
2374 if (!PyArg_ParseTuple(args, "s", &name))
2375 return NULL;
2377 ldb_msg_remove_attr(self->msg, name);
2379 Py_RETURN_NONE;
2382 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2384 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2385 Py_ssize_t i, j = 0;
2386 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2387 if (msg->dn != NULL) {
2388 PyList_SetItem(obj, j, PyString_FromString("dn"));
2389 j++;
2391 for (i = 0; i < msg->num_elements; i++) {
2392 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2393 j++;
2395 return obj;
2398 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2400 struct ldb_message_element *el;
2401 char *name;
2402 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2403 if (!PyString_Check(py_name)) {
2404 PyErr_SetNone(PyExc_TypeError);
2405 return NULL;
2407 name = PyString_AsString(py_name);
2408 if (!strcmp(name, "dn"))
2409 return PyLdbDn_FromDn(msg->dn);
2410 el = ldb_msg_find_element(msg, name);
2411 if (el == NULL) {
2412 return NULL;
2414 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2417 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2419 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2420 if (ret == NULL) {
2421 PyErr_SetString(PyExc_KeyError, "No such element");
2422 return NULL;
2424 return ret;
2427 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args)
2429 PyObject *name, *ret;
2430 if (!PyArg_ParseTuple(args, "O", &name))
2431 return NULL;
2433 ret = py_ldb_msg_getitem_helper(self, name);
2434 if (ret == NULL) {
2435 if (PyErr_Occurred())
2436 return NULL;
2437 Py_RETURN_NONE;
2439 return ret;
2442 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2444 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2445 Py_ssize_t i, j = 0;
2446 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2447 if (msg->dn != NULL) {
2448 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn)));
2449 j++;
2451 for (i = 0; i < msg->num_elements; i++, j++) {
2452 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2453 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2454 PyList_SetItem(l, j, value);
2456 return l;
2459 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2461 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2462 Py_ssize_t i = 0;
2463 PyObject *l = PyList_New(msg->num_elements);
2464 for (i = 0; i < msg->num_elements; i++) {
2465 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2467 return l;
2470 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2472 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2473 PyLdbMessageElementObject *py_element;
2474 int ret;
2475 struct ldb_message_element *el;
2477 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2478 return NULL;
2480 el = talloc_reference(msg, py_element->el);
2481 if (el == NULL) {
2482 PyErr_NoMemory();
2483 return NULL;
2486 ret = ldb_msg_add(msg, el, el->flags);
2487 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2489 Py_RETURN_NONE;
2492 static PyMethodDef py_ldb_msg_methods[] = {
2493 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2494 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2495 "Class method to create ldb.Message object from Dictionary.\n"
2496 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2497 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2498 "S.keys() -> list\n\n"
2499 "Return sequence of all attribute names." },
2500 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2501 "S.remove(name)\n\n"
2502 "Remove all entries for attributes with the specified name."},
2503 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL },
2504 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2505 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2506 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2507 "S.append(element)\n\n"
2508 "Add an element to this message." },
2509 { NULL },
2512 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2514 PyObject *list, *iter;
2516 list = py_ldb_msg_keys(self);
2517 iter = PyObject_GetIter(list);
2518 Py_DECREF(list);
2519 return iter;
2522 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2524 char *attr_name;
2526 if (!PyString_Check(name)) {
2527 PyErr_SetNone(PyExc_TypeError);
2528 return -1;
2531 attr_name = PyString_AsString(name);
2532 if (value == NULL) {
2533 /* delitem */
2534 ldb_msg_remove_attr(self->msg, attr_name);
2535 } else {
2536 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2537 value, 0, attr_name);
2538 if (el == NULL)
2539 return -1;
2540 ldb_msg_remove_attr(PyLdbMessage_AsMessage(self), attr_name);
2541 ldb_msg_add(PyLdbMessage_AsMessage(self), el, el->flags);
2543 return 0;
2546 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2548 return PyLdbMessage_AsMessage(self)->num_elements;
2551 static PyMappingMethods py_ldb_msg_mapping = {
2552 .mp_length = (lenfunc)py_ldb_msg_length,
2553 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2554 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2557 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2559 const char * const kwnames[] = { "dn", NULL };
2560 struct ldb_message *ret;
2561 TALLOC_CTX *mem_ctx;
2562 PyObject *pydn = NULL;
2563 PyLdbMessageObject *py_ret;
2565 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2566 discard_const_p(char *, kwnames),
2567 &pydn))
2568 return NULL;
2570 mem_ctx = talloc_new(NULL);
2571 if (mem_ctx == NULL) {
2572 PyErr_NoMemory();
2573 return NULL;
2576 ret = ldb_msg_new(mem_ctx);
2577 if (ret == NULL) {
2578 talloc_free(mem_ctx);
2579 PyErr_NoMemory();
2580 return NULL;
2583 if (pydn != NULL) {
2584 struct ldb_dn *dn;
2585 if (!PyObject_AsDn(NULL, pydn, NULL, &dn)) {
2586 talloc_free(mem_ctx);
2587 return NULL;
2589 ret->dn = talloc_reference(ret, dn);
2592 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2593 if (py_ret == NULL) {
2594 PyErr_NoMemory();
2595 talloc_free(mem_ctx);
2596 return NULL;
2599 py_ret->mem_ctx = mem_ctx;
2600 py_ret->msg = ret;
2601 return (PyObject *)py_ret;
2604 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2606 PyLdbMessageObject *ret;
2608 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2609 if (ret == NULL) {
2610 PyErr_NoMemory();
2611 return NULL;
2613 ret->mem_ctx = talloc_new(NULL);
2614 ret->msg = talloc_reference(ret->mem_ctx, msg);
2615 return (PyObject *)ret;
2618 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2620 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2621 return PyLdbDn_FromDn(msg->dn);
2624 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2626 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2627 if (!PyLdbDn_Check(value)) {
2628 PyErr_SetNone(PyExc_TypeError);
2629 return -1;
2632 msg->dn = talloc_reference(msg, PyLdbDn_AsDn(value));
2633 return 0;
2636 static PyGetSetDef py_ldb_msg_getset[] = {
2637 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2638 { NULL }
2641 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2643 PyObject *dict = PyDict_New(), *ret;
2644 if (PyDict_Update(dict, (PyObject *)self) != 0)
2645 return NULL;
2646 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2647 Py_DECREF(dict);
2648 return ret;
2651 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2653 talloc_free(self->mem_ctx);
2654 PyObject_Del(self);
2657 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2658 PyLdbMessageObject *py_msg2)
2660 struct ldb_message *msg1 = PyLdbMessage_AsMessage(py_msg1),
2661 *msg2 = PyLdbMessage_AsMessage(py_msg2);
2662 unsigned int i;
2663 int ret;
2665 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2666 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2667 if (ret != 0) {
2668 return SIGN(ret);
2672 ret = msg1->num_elements - msg2->num_elements;
2673 if (ret != 0) {
2674 return SIGN(ret);
2677 for (i = 0; i < msg1->num_elements; i++) {
2678 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2679 &msg2->elements[i]);
2680 if (ret != 0) {
2681 return SIGN(ret);
2684 ret = ldb_msg_element_compare(&msg1->elements[i],
2685 &msg2->elements[i]);
2686 if (ret != 0) {
2687 return SIGN(ret);
2691 return 0;
2694 static PyTypeObject PyLdbMessage = {
2695 .tp_name = "ldb.Message",
2696 .tp_methods = py_ldb_msg_methods,
2697 .tp_getset = py_ldb_msg_getset,
2698 .tp_as_mapping = &py_ldb_msg_mapping,
2699 .tp_basicsize = sizeof(PyLdbMessageObject),
2700 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2701 .tp_new = py_ldb_msg_new,
2702 .tp_repr = (reprfunc)py_ldb_msg_repr,
2703 .tp_flags = Py_TPFLAGS_DEFAULT,
2704 .tp_iter = (getiterfunc)py_ldb_msg_iter,
2705 .tp_compare = (cmpfunc)py_ldb_msg_compare,
2708 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2710 PyLdbTreeObject *ret;
2712 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2713 if (ret == NULL) {
2714 PyErr_NoMemory();
2715 return NULL;
2718 ret->mem_ctx = talloc_new(NULL);
2719 ret->tree = talloc_reference(ret->mem_ctx, tree);
2720 return (PyObject *)ret;
2723 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2725 talloc_free(self->mem_ctx);
2726 PyObject_Del(self);
2729 static PyTypeObject PyLdbTree = {
2730 .tp_name = "ldb.Tree",
2731 .tp_basicsize = sizeof(PyLdbTreeObject),
2732 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2733 .tp_flags = Py_TPFLAGS_DEFAULT,
2736 /* Ldb_module */
2737 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2739 PyObject *py_ldb = (PyObject *)mod->private_data;
2740 PyObject *py_result, *py_base, *py_attrs, *py_tree;
2742 py_base = PyLdbDn_FromDn(req->op.search.base);
2744 if (py_base == NULL)
2745 return LDB_ERR_OPERATIONS_ERROR;
2747 py_tree = PyLdbTree_FromTree(req->op.search.tree);
2749 if (py_tree == NULL)
2750 return LDB_ERR_OPERATIONS_ERROR;
2752 if (req->op.search.attrs == NULL) {
2753 py_attrs = Py_None;
2754 } else {
2755 int i, len;
2756 for (len = 0; req->op.search.attrs[len]; len++);
2757 py_attrs = PyList_New(len);
2758 for (i = 0; i < len; i++)
2759 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2762 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2763 discard_const_p(char, "OiOO"),
2764 py_base, req->op.search.scope, py_tree, py_attrs);
2766 Py_DECREF(py_attrs);
2767 Py_DECREF(py_tree);
2768 Py_DECREF(py_base);
2770 if (py_result == NULL) {
2771 return LDB_ERR_PYTHON_EXCEPTION;
2774 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2775 if (req->op.search.res == NULL) {
2776 return LDB_ERR_PYTHON_EXCEPTION;
2779 Py_DECREF(py_result);
2781 return LDB_SUCCESS;
2784 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2786 PyObject *py_ldb = (PyObject *)mod->private_data;
2787 PyObject *py_result, *py_msg;
2789 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2791 if (py_msg == NULL) {
2792 return LDB_ERR_OPERATIONS_ERROR;
2795 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2796 discard_const_p(char, "O"),
2797 py_msg);
2799 Py_DECREF(py_msg);
2801 if (py_result == NULL) {
2802 return LDB_ERR_PYTHON_EXCEPTION;
2805 Py_DECREF(py_result);
2807 return LDB_SUCCESS;
2810 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
2812 PyObject *py_ldb = (PyObject *)mod->private_data;
2813 PyObject *py_result, *py_msg;
2815 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
2817 if (py_msg == NULL) {
2818 return LDB_ERR_OPERATIONS_ERROR;
2821 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
2822 discard_const_p(char, "O"),
2823 py_msg);
2825 Py_DECREF(py_msg);
2827 if (py_result == NULL) {
2828 return LDB_ERR_PYTHON_EXCEPTION;
2831 Py_DECREF(py_result);
2833 return LDB_SUCCESS;
2836 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
2838 PyObject *py_ldb = (PyObject *)mod->private_data;
2839 PyObject *py_result, *py_dn;
2841 py_dn = PyLdbDn_FromDn(req->op.del.dn);
2843 if (py_dn == NULL)
2844 return LDB_ERR_OPERATIONS_ERROR;
2846 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
2847 discard_const_p(char, "O"),
2848 py_dn);
2850 if (py_result == NULL) {
2851 return LDB_ERR_PYTHON_EXCEPTION;
2854 Py_DECREF(py_result);
2856 return LDB_SUCCESS;
2859 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
2861 PyObject *py_ldb = (PyObject *)mod->private_data;
2862 PyObject *py_result, *py_olddn, *py_newdn;
2864 py_olddn = PyLdbDn_FromDn(req->op.rename.olddn);
2866 if (py_olddn == NULL)
2867 return LDB_ERR_OPERATIONS_ERROR;
2869 py_newdn = PyLdbDn_FromDn(req->op.rename.newdn);
2871 if (py_newdn == NULL)
2872 return LDB_ERR_OPERATIONS_ERROR;
2874 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
2875 discard_const_p(char, "OO"),
2876 py_olddn, py_newdn);
2878 Py_DECREF(py_olddn);
2879 Py_DECREF(py_newdn);
2881 if (py_result == NULL) {
2882 return LDB_ERR_PYTHON_EXCEPTION;
2885 Py_DECREF(py_result);
2887 return LDB_SUCCESS;
2890 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
2892 PyObject *py_ldb = (PyObject *)mod->private_data;
2893 PyObject *py_result;
2895 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
2896 discard_const_p(char, ""));
2898 return LDB_ERR_OPERATIONS_ERROR;
2901 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
2903 PyObject *py_ldb = (PyObject *)mod->private_data;
2904 PyObject *py_result;
2906 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
2907 discard_const_p(char, ""));
2909 return LDB_ERR_OPERATIONS_ERROR;
2912 static int py_module_start_transaction(struct ldb_module *mod)
2914 PyObject *py_ldb = (PyObject *)mod->private_data;
2915 PyObject *py_result;
2917 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
2918 discard_const_p(char, ""));
2920 if (py_result == NULL) {
2921 return LDB_ERR_PYTHON_EXCEPTION;
2924 Py_DECREF(py_result);
2926 return LDB_SUCCESS;
2929 static int py_module_end_transaction(struct ldb_module *mod)
2931 PyObject *py_ldb = (PyObject *)mod->private_data;
2932 PyObject *py_result;
2934 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
2935 discard_const_p(char, ""));
2937 if (py_result == NULL) {
2938 return LDB_ERR_PYTHON_EXCEPTION;
2941 Py_DECREF(py_result);
2943 return LDB_SUCCESS;
2946 static int py_module_del_transaction(struct ldb_module *mod)
2948 PyObject *py_ldb = (PyObject *)mod->private_data;
2949 PyObject *py_result;
2951 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
2952 discard_const_p(char, ""));
2954 if (py_result == NULL) {
2955 return LDB_ERR_PYTHON_EXCEPTION;
2958 Py_DECREF(py_result);
2960 return LDB_SUCCESS;
2963 static int py_module_destructor(struct ldb_module *mod)
2965 Py_DECREF((PyObject *)mod->private_data);
2966 return 0;
2969 static int py_module_init(struct ldb_module *mod)
2971 PyObject *py_class = (PyObject *)mod->ops->private_data;
2972 PyObject *py_result, *py_next, *py_ldb;
2974 py_ldb = PyLdb_FromLdbContext(mod->ldb);
2976 if (py_ldb == NULL)
2977 return LDB_ERR_OPERATIONS_ERROR;
2979 py_next = PyLdbModule_FromModule(mod->next);
2981 if (py_next == NULL)
2982 return LDB_ERR_OPERATIONS_ERROR;
2984 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
2985 py_ldb, py_next);
2987 if (py_result == NULL) {
2988 return LDB_ERR_PYTHON_EXCEPTION;
2991 mod->private_data = py_result;
2993 talloc_set_destructor(mod, py_module_destructor);
2995 return ldb_next_init(mod);
2998 static PyObject *py_register_module(PyObject *module, PyObject *args)
3000 int ret;
3001 struct ldb_module_ops *ops;
3002 PyObject *input;
3004 if (!PyArg_ParseTuple(args, "O", &input))
3005 return NULL;
3007 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3008 if (ops == NULL) {
3009 PyErr_NoMemory();
3010 return NULL;
3013 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3015 Py_INCREF(input);
3016 ops->private_data = input;
3017 ops->init_context = py_module_init;
3018 ops->search = py_module_search;
3019 ops->add = py_module_add;
3020 ops->modify = py_module_modify;
3021 ops->del = py_module_del;
3022 ops->rename = py_module_rename;
3023 ops->request = py_module_request;
3024 ops->extended = py_module_extended;
3025 ops->start_transaction = py_module_start_transaction;
3026 ops->end_transaction = py_module_end_transaction;
3027 ops->del_transaction = py_module_del_transaction;
3029 ret = ldb_register_module(ops);
3031 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3033 Py_RETURN_NONE;
3036 static PyObject *py_timestring(PyObject *module, PyObject *args)
3038 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3039 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3040 long int t_val;
3041 char *tresult;
3042 PyObject *ret;
3043 if (!PyArg_ParseTuple(args, "l", &t_val))
3044 return NULL;
3045 tresult = ldb_timestring(NULL, (time_t) t_val);
3046 ret = PyString_FromString(tresult);
3047 talloc_free(tresult);
3048 return ret;
3051 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3053 char *str;
3054 if (!PyArg_ParseTuple(args, "s", &str))
3055 return NULL;
3057 return PyInt_FromLong(ldb_string_to_time(str));
3060 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3062 char *name;
3063 if (!PyArg_ParseTuple(args, "s", &name))
3064 return NULL;
3065 return PyBool_FromLong(ldb_valid_attr_name(name));
3068 static PyMethodDef py_ldb_global_methods[] = {
3069 { "register_module", py_register_module, METH_VARARGS,
3070 "S.register_module(module) -> None\n"
3071 "Register a LDB module."},
3072 { "timestring", py_timestring, METH_VARARGS,
3073 "S.timestring(int) -> string\n"
3074 "Generate a LDAP time string from a UNIX timestamp" },
3075 { "string_to_time", py_string_to_time, METH_VARARGS,
3076 "S.string_to_time(string) -> int\n"
3077 "Parse a LDAP time string into a UNIX timestamp." },
3078 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3079 "S.valid_attr_name(name) -> bool\n"
3080 "Check whether the supplied name is a valid attribute name." },
3081 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3082 NULL },
3083 { NULL }
3086 void initldb(void)
3088 PyObject *m;
3090 if (PyType_Ready(&PyLdbDn) < 0)
3091 return;
3093 if (PyType_Ready(&PyLdbMessage) < 0)
3094 return;
3096 if (PyType_Ready(&PyLdbMessageElement) < 0)
3097 return;
3099 if (PyType_Ready(&PyLdb) < 0)
3100 return;
3102 if (PyType_Ready(&PyLdbModule) < 0)
3103 return;
3105 if (PyType_Ready(&PyLdbTree) < 0)
3106 return;
3108 if (PyType_Ready(&PyLdbResult) < 0)
3109 return;
3111 if (PyType_Ready(&PyLdbControl) < 0)
3112 return;
3114 m = Py_InitModule3("ldb", py_ldb_global_methods,
3115 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3116 if (m == NULL)
3117 return;
3119 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3120 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3121 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3122 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3123 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3124 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3125 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3127 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3128 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3129 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3130 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3132 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3133 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3134 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3136 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3137 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3138 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3139 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3140 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3141 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3142 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3143 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3144 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3145 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3146 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3147 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3148 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3149 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3150 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3151 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3152 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3153 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3154 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3155 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3156 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3157 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3158 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3159 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3160 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3161 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3162 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3163 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3164 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3165 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3166 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3167 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3168 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3169 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3170 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3171 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3172 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3173 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3174 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3176 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3177 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3178 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3179 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3181 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3183 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3184 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3186 Py_INCREF(&PyLdb);
3187 Py_INCREF(&PyLdbDn);
3188 Py_INCREF(&PyLdbModule);
3189 Py_INCREF(&PyLdbMessage);
3190 Py_INCREF(&PyLdbMessageElement);
3191 Py_INCREF(&PyLdbTree);
3192 Py_INCREF(&PyLdbResult);
3193 Py_INCREF(&PyLdbControl);
3195 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3196 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3197 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3198 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3199 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3200 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3201 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3203 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));