pyldb: enhanced get() method on msg object
[Samba/gebeck_regimport.git] / lib / ldb / pyldb.c
blob2f1a6a3486c42a04b80436c1118e1deaec3f9764
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
10 Copyright (C) 2009-2011 Andrew Tridgell
11 Copyright (C) 2009-2011 Andrew Bartlett
13 ** NOTE! The following LGPL license applies to the ldb
14 ** library. This does NOT imply that all of Samba is released
15 ** under the LGPL
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public
19 License as published by the Free Software Foundation; either
20 version 3 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, see <http://www.gnu.org/licenses/>.
31 #include <Python.h>
32 #include "ldb_private.h"
33 #include "pyldb.h"
35 void initldb(void);
36 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
37 static PyObject *PyExc_LdbError;
39 staticforward PyTypeObject PyLdbControl;
40 staticforward PyTypeObject PyLdbResult;
41 staticforward PyTypeObject PyLdbMessage;
42 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
43 staticforward PyTypeObject PyLdbModule;
44 staticforward PyTypeObject PyLdbDn;
45 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
46 staticforward PyTypeObject PyLdb;
47 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
48 staticforward PyTypeObject PyLdbMessageElement;
49 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
51 staticforward PyTypeObject PyLdbTree;
52 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
53 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
54 static struct ldb_message_element *PyObject_AsMessageElement(
55 TALLOC_CTX *mem_ctx,
56 PyObject *set_obj,
57 unsigned int flags,
58 const char *attr_name);
60 /* There's no Py_ssize_t in 2.4, apparently */
61 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
62 typedef int Py_ssize_t;
63 typedef inquiry lenfunc;
64 typedef intargfunc ssizeargfunc;
65 #endif
67 #ifndef Py_RETURN_NONE
68 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
69 #endif
71 #define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
75 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
77 if (self->data != NULL) {
78 char* control = ldb_control_to_string(self->mem_ctx, self->data);
79 if (control == NULL) {
80 PyErr_NoMemory();
81 return NULL;
83 return PyString_FromString(control);
84 } else {
85 return PyString_FromFormat("ldb control");
89 static void py_ldb_control_dealloc(PyLdbControlObject *self)
91 if (self->mem_ctx != NULL) {
92 talloc_free(self->mem_ctx);
94 self->data = NULL;
95 self->ob_type->tp_free(self);
98 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
100 return PyString_FromString(self->data->oid);
103 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
105 return PyBool_FromLong(self->data->critical);
108 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
110 if (PyObject_IsTrue(value)) {
111 self->data->critical = true;
112 } else {
113 self->data->critical = false;
115 return 0;
118 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
120 char *data = NULL;
121 const char * const kwnames[] = { "ldb", "data", NULL };
122 struct ldb_control *parsed_controls;
123 PyLdbControlObject *ret;
124 PyObject *py_ldb;
125 TALLOC_CTX *mem_ctx;
126 struct ldb_context *ldb_ctx;
128 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
129 discard_const_p(char *, kwnames),
130 &py_ldb, &data))
131 return NULL;
133 mem_ctx = talloc_new(NULL);
134 if (mem_ctx == NULL) {
135 PyErr_NoMemory();
136 return NULL;
139 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
140 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
142 if (!parsed_controls) {
143 talloc_free(mem_ctx);
144 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
145 return NULL;
148 ret = PyObject_New(PyLdbControlObject, type);
149 if (ret == NULL) {
150 PyErr_NoMemory();
151 talloc_free(mem_ctx);
152 return NULL;
155 ret->mem_ctx = mem_ctx;
157 ret->data = talloc_move(mem_ctx, &parsed_controls);
158 if (ret->data == NULL) {
159 Py_DECREF(ret);
160 PyErr_NoMemory();
161 talloc_free(mem_ctx);
162 return NULL;
165 return (PyObject *)ret;
168 static PyGetSetDef py_ldb_control_getset[] = {
169 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
170 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
171 { NULL }
174 static PyTypeObject PyLdbControl = {
175 .tp_name = "ldb.control",
176 .tp_dealloc = (destructor)py_ldb_control_dealloc,
177 .tp_getattro = PyObject_GenericGetAttr,
178 .tp_basicsize = sizeof(PyLdbControlObject),
179 .tp_getset = py_ldb_control_getset,
180 .tp_doc = "LDB control.",
181 .tp_str = (reprfunc)py_ldb_control_str,
182 .tp_new = py_ldb_control_new,
183 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
186 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
188 if (ret == LDB_ERR_PYTHON_EXCEPTION)
189 return; /* Python exception should already be set, just keep that */
191 PyErr_SetObject(error,
192 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
193 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
196 static PyObject *PyObject_FromLdbValue(struct ldb_val *val)
198 return PyString_FromStringAndSize((const char *)val->data, val->length);
202 * Create a Python object from a ldb_result.
204 * @param result LDB result to convert
205 * @return Python object with converted result (a list object)
207 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
209 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
210 PyLdbControlObject *ctrl;
211 if (ctl_ctx == NULL) {
212 PyErr_NoMemory();
213 return NULL;
216 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
217 if (ctrl == NULL) {
218 talloc_free(ctl_ctx);
219 PyErr_NoMemory();
220 return NULL;
222 ctrl->mem_ctx = ctl_ctx;
223 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
224 if (ctrl->data == NULL) {
225 Py_DECREF(ctrl);
226 PyErr_NoMemory();
227 return NULL;
229 return (PyObject*) ctrl;
233 * Create a Python object from a ldb_result.
235 * @param result LDB result to convert
236 * @return Python object with converted result (a list object)
238 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
240 PyLdbResultObject *ret;
241 PyObject *list, *controls, *referals;
242 Py_ssize_t i;
244 if (result == NULL) {
245 Py_RETURN_NONE;
248 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
249 if (ret == NULL) {
250 PyErr_NoMemory();
251 return NULL;
254 list = PyList_New(result->count);
255 if (list == NULL) {
256 PyErr_NoMemory();
257 Py_DECREF(ret);
258 return NULL;
261 for (i = 0; i < result->count; i++) {
262 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
265 ret->mem_ctx = talloc_new(NULL);
266 if (ret->mem_ctx == NULL) {
267 Py_DECREF(list);
268 Py_DECREF(ret);
269 PyErr_NoMemory();
270 return NULL;
273 ret->msgs = list;
275 if (result->controls) {
276 controls = PyList_New(1);
277 if (controls == NULL) {
278 Py_DECREF(ret);
279 PyErr_NoMemory();
280 return NULL;
282 for (i=0; result->controls[i]; i++) {
283 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
284 if (ctrl == NULL) {
285 Py_DECREF(ret);
286 Py_DECREF(controls);
287 PyErr_NoMemory();
288 return NULL;
290 PyList_SetItem(controls, i, ctrl);
292 } else {
294 * No controls so we keep an empty list
296 controls = PyList_New(0);
297 if (controls == NULL) {
298 Py_DECREF(ret);
299 PyErr_NoMemory();
300 return NULL;
304 ret->controls = controls;
306 i = 0;
308 while (result->refs && result->refs[i]) {
309 i++;
312 referals = PyList_New(i);
313 if (referals == NULL) {
314 Py_DECREF(ret);
315 PyErr_NoMemory();
316 return NULL;
319 for (i = 0;result->refs && result->refs[i]; i++) {
320 PyList_SetItem(referals, i, PyString_FromString(result->refs[i]));
322 ret->referals = referals;
323 return (PyObject *)ret;
327 * Create a LDB Result from a Python object.
328 * If conversion fails, NULL will be returned and a Python exception set.
330 * Note: the result object only includes the messages at the moment; extended
331 * result, controls and referrals are ignored.
333 * @param mem_ctx Memory context in which to allocate the LDB Result
334 * @param obj Python object to convert
335 * @return a ldb_result, or NULL if the conversion failed
337 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
338 PyObject *obj)
340 struct ldb_result *res;
341 Py_ssize_t i;
343 if (obj == Py_None)
344 return NULL;
346 res = talloc_zero(mem_ctx, struct ldb_result);
347 res->count = PyList_Size(obj);
348 res->msgs = talloc_array(res, struct ldb_message *, res->count);
349 for (i = 0; i < res->count; i++) {
350 PyObject *item = PyList_GetItem(obj, i);
351 res->msgs[i] = pyldb_Message_AsMessage(item);
353 return res;
356 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
358 return PyBool_FromLong(ldb_dn_validate(self->dn));
361 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
363 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
366 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
368 return PyBool_FromLong(ldb_dn_is_special(self->dn));
371 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
373 return PyBool_FromLong(ldb_dn_is_null(self->dn));
376 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
378 return PyString_FromString(ldb_dn_get_casefold(self->dn));
381 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
383 return PyString_FromString(ldb_dn_get_linearized(self->dn));
386 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
388 return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
391 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
393 return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
396 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
398 const char * const kwnames[] = { "mode", NULL };
399 int mode = 1;
400 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
401 discard_const_p(char *, kwnames),
402 &mode))
403 return NULL;
404 return PyString_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
407 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
409 char *name;
410 const struct ldb_val *val;
412 if (!PyArg_ParseTuple(args, "s", &name))
413 return NULL;
414 val = ldb_dn_get_extended_component(self->dn, name);
415 if (val == NULL) {
416 Py_RETURN_NONE;
419 return PyString_FromStringAndSize((const char *)val->data, val->length);
422 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
424 char *name;
425 PyObject *value;
426 int err;
428 if (!PyArg_ParseTuple(args, "sO", &name, &value))
429 return NULL;
431 if (value == Py_None) {
432 err = ldb_dn_set_extended_component(self->dn, name, NULL);
433 } else {
434 struct ldb_val val;
435 if (!PyString_Check(value)) {
436 PyErr_SetString(PyExc_TypeError, "Expected a string argument");
437 return NULL;
439 val.data = (uint8_t *)PyString_AsString(value);
440 val.length = PyString_Size(value);
441 err = ldb_dn_set_extended_component(self->dn, name, &val);
444 if (err != LDB_SUCCESS) {
445 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
446 return NULL;
449 Py_RETURN_NONE;
452 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
454 return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
457 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
459 char *name;
461 if (!PyArg_ParseTuple(args, "s", &name))
462 return NULL;
464 return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
467 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
469 int ret;
470 ret = ldb_dn_compare(dn1->dn, dn2->dn);
471 if (ret < 0) ret = -1;
472 if (ret > 0) ret = 1;
473 return ret;
476 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
478 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
479 struct ldb_dn *parent;
480 PyLdbDnObject *py_ret;
481 TALLOC_CTX *mem_ctx = talloc_new(NULL);
483 parent = ldb_dn_get_parent(mem_ctx, dn);
484 if (parent == NULL) {
485 talloc_free(mem_ctx);
486 Py_RETURN_NONE;
489 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
490 if (py_ret == NULL) {
491 PyErr_NoMemory();
492 talloc_free(mem_ctx);
493 return NULL;
495 py_ret->mem_ctx = mem_ctx;
496 py_ret->dn = parent;
497 return (PyObject *)py_ret;
500 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
502 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
504 PyObject *py_other;
505 struct ldb_dn *dn, *other;
506 if (!PyArg_ParseTuple(args, "O", &py_other))
507 return NULL;
509 dn = pyldb_Dn_AsDn((PyObject *)self);
511 if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
512 return NULL;
514 return ldb_dn_add_child(dn, other)?Py_True:Py_False;
517 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
519 PyObject *py_other;
520 struct ldb_dn *other, *dn;
521 if (!PyArg_ParseTuple(args, "O", &py_other))
522 return NULL;
524 dn = pyldb_Dn_AsDn((PyObject *)self);
526 if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
527 return NULL;
529 return ldb_dn_add_base(dn, other)?Py_True:Py_False;
532 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
534 PyObject *py_base;
535 struct ldb_dn *dn, *base;
536 if (!PyArg_ParseTuple(args, "O", &py_base))
537 return NULL;
539 dn = pyldb_Dn_AsDn((PyObject *)self);
541 if (!pyldb_Object_AsDn(NULL, py_base, dn_ldb_ctx(dn), &base))
542 return NULL;
544 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
547 static PyMethodDef py_ldb_dn_methods[] = {
548 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
549 "S.validate() -> bool\n"
550 "Validate DN is correct." },
551 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
552 "S.is_valid() -> bool\n" },
553 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
554 "S.is_special() -> bool\n"
555 "Check whether this is a special LDB DN." },
556 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
557 "Check whether this is a null DN." },
558 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
559 NULL },
560 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
561 NULL },
562 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
563 "S.canonical_str() -> string\n"
564 "Canonical version of this DN (like a posix path)." },
565 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
566 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
567 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
568 "S.canonical_ex_str() -> string\n"
569 "Canonical version of this DN (like a posix path, with terminating newline)." },
570 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
571 "S.extended_str(mode=1) -> string\n"
572 "Extended version of this DN" },
573 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
574 "S.parent() -> dn\n"
575 "Get the parent for this DN." },
576 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
577 "S.add_child(dn) -> None\n"
578 "Add a child DN to this DN." },
579 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
580 "S.add_base(dn) -> None\n"
581 "Add a base DN to this DN." },
582 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
583 "S.check_special(name) -> bool\n\n"
584 "Check if name is a special DN name"},
585 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
586 "S.get_extended_component(name) -> string\n\n"
587 "returns a DN extended component as a binary string"},
588 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
589 "S.set_extended_component(name, value) -> string\n\n"
590 "set a DN extended component as a binary string"},
591 { NULL }
594 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
596 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
600 copy a DN as a python object
602 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
604 PyLdbDnObject *py_ret;
606 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
607 if (py_ret == NULL) {
608 PyErr_NoMemory();
609 return NULL;
611 py_ret->mem_ctx = talloc_new(NULL);
612 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
613 return (PyObject *)py_ret;
616 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
618 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
619 *other;
620 PyLdbDnObject *py_ret;
622 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
623 return NULL;
625 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
626 if (py_ret == NULL) {
627 PyErr_NoMemory();
628 return NULL;
630 py_ret->mem_ctx = talloc_new(NULL);
631 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
632 ldb_dn_add_child(py_ret->dn, other);
633 return (PyObject *)py_ret;
636 static PySequenceMethods py_ldb_dn_seq = {
637 .sq_length = (lenfunc)py_ldb_dn_len,
638 .sq_concat = (binaryfunc)py_ldb_dn_concat,
641 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
643 struct ldb_dn *ret;
644 char *str;
645 PyObject *py_ldb;
646 struct ldb_context *ldb_ctx;
647 TALLOC_CTX *mem_ctx;
648 PyLdbDnObject *py_ret;
649 const char * const kwnames[] = { "ldb", "dn", NULL };
651 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
652 discard_const_p(char *, kwnames),
653 &py_ldb, &str))
654 return NULL;
656 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
658 mem_ctx = talloc_new(NULL);
659 if (mem_ctx == NULL) {
660 PyErr_NoMemory();
661 return NULL;
664 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
665 if (!ldb_dn_validate(ret)) {
666 talloc_free(mem_ctx);
667 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
668 return NULL;
671 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
672 if (ret == NULL) {
673 talloc_free(mem_ctx);
674 PyErr_NoMemory();
675 return NULL;
677 py_ret->mem_ctx = mem_ctx;
678 py_ret->dn = ret;
679 return (PyObject *)py_ret;
682 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
684 talloc_free(self->mem_ctx);
685 PyObject_Del(self);
688 static PyTypeObject PyLdbDn = {
689 .tp_name = "ldb.Dn",
690 .tp_methods = py_ldb_dn_methods,
691 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
692 .tp_repr = (reprfunc)py_ldb_dn_repr,
693 .tp_compare = (cmpfunc)py_ldb_dn_compare,
694 .tp_as_sequence = &py_ldb_dn_seq,
695 .tp_doc = "A LDB distinguished name.",
696 .tp_new = py_ldb_dn_new,
697 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
698 .tp_basicsize = sizeof(PyLdbDnObject),
699 .tp_flags = Py_TPFLAGS_DEFAULT,
702 /* Debug */
703 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
704 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
706 PyObject *fn = (PyObject *)context;
707 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
710 static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args)
712 PyObject *cb;
714 if (!PyArg_ParseTuple(args, "O", &cb))
715 return NULL;
717 Py_INCREF(cb);
718 /* FIXME: Where do we DECREF cb ? */
719 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), pyldb_Ldb_AsLdbContext(self));
721 Py_RETURN_NONE;
724 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
726 unsigned int perms;
727 if (!PyArg_ParseTuple(args, "I", &perms))
728 return NULL;
730 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
732 Py_RETURN_NONE;
735 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
737 char *modules_dir;
738 if (!PyArg_ParseTuple(args, "s", &modules_dir))
739 return NULL;
741 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
743 Py_RETURN_NONE;
746 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
748 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_start(pyldb_Ldb_AsLdbContext(self)), pyldb_Ldb_AsLdbContext(self));
749 Py_RETURN_NONE;
752 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
754 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(pyldb_Ldb_AsLdbContext(self)), pyldb_Ldb_AsLdbContext(self));
755 Py_RETURN_NONE;
758 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
760 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_prepare_commit(pyldb_Ldb_AsLdbContext(self)), pyldb_Ldb_AsLdbContext(self));
761 Py_RETURN_NONE;
764 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
766 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_cancel(pyldb_Ldb_AsLdbContext(self)), pyldb_Ldb_AsLdbContext(self));
767 Py_RETURN_NONE;
770 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
772 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_setup_wellknown_attributes(pyldb_Ldb_AsLdbContext(self)), pyldb_Ldb_AsLdbContext(self));
773 Py_RETURN_NONE;
776 static PyObject *py_ldb_repr(PyLdbObject *self)
778 return PyString_FromFormat("<ldb connection>");
781 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
783 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
784 if (dn == NULL)
785 Py_RETURN_NONE;
786 return py_ldb_dn_copy(dn);
790 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
792 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
793 if (dn == NULL)
794 Py_RETURN_NONE;
795 return py_ldb_dn_copy(dn);
798 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
800 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
801 if (dn == NULL)
802 Py_RETURN_NONE;
803 return py_ldb_dn_copy(dn);
806 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
808 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
809 if (dn == NULL)
810 Py_RETURN_NONE;
811 return py_ldb_dn_copy(dn);
814 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
815 const char *paramname)
817 const char **ret;
818 Py_ssize_t i;
819 if (!PyList_Check(list)) {
820 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
821 return NULL;
823 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
824 if (ret == NULL) {
825 PyErr_NoMemory();
826 return NULL;
829 for (i = 0; i < PyList_Size(list); i++) {
830 PyObject *item = PyList_GetItem(list, i);
831 if (!PyString_Check(item)) {
832 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
833 return NULL;
835 ret[i] = talloc_strndup(ret, PyString_AsString(item),
836 PyString_Size(item));
838 ret[i] = NULL;
839 return ret;
842 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
844 const char * const kwnames[] = { "url", "flags", "options", NULL };
845 char *url = NULL;
846 PyObject *py_options = Py_None;
847 const char **options;
848 unsigned int flags = 0;
849 int ret;
850 struct ldb_context *ldb;
852 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
853 discard_const_p(char *, kwnames),
854 &url, &flags, &py_options))
855 return -1;
857 ldb = pyldb_Ldb_AsLdbContext(self);
859 if (py_options == Py_None) {
860 options = NULL;
861 } else {
862 options = PyList_AsStringList(ldb, py_options, "options");
863 if (options == NULL)
864 return -1;
867 if (url != NULL) {
868 ret = ldb_connect(ldb, url, flags, options);
869 if (ret != LDB_SUCCESS) {
870 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
871 return -1;
875 talloc_free(options);
876 return 0;
879 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
881 PyLdbObject *ret;
882 struct ldb_context *ldb;
883 ret = (PyLdbObject *)type->tp_alloc(type, 0);
884 if (ret == NULL) {
885 PyErr_NoMemory();
886 return NULL;
888 ret->mem_ctx = talloc_new(NULL);
889 ldb = ldb_init(ret->mem_ctx, NULL);
891 if (ldb == NULL) {
892 PyErr_NoMemory();
893 return NULL;
896 ret->ldb_ctx = ldb;
897 return (PyObject *)ret;
900 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
902 char *url;
903 unsigned int flags = 0;
904 PyObject *py_options = Py_None;
905 int ret;
906 const char **options;
907 const char * const kwnames[] = { "url", "flags", "options", NULL };
909 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
910 discard_const_p(char *, kwnames),
911 &url, &flags, &py_options))
912 return NULL;
914 if (py_options == Py_None) {
915 options = NULL;
916 } else {
917 options = PyList_AsStringList(NULL, py_options, "options");
918 if (options == NULL)
919 return NULL;
922 ret = ldb_connect(pyldb_Ldb_AsLdbContext(self), url, flags, options);
923 talloc_free(options);
925 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, pyldb_Ldb_AsLdbContext(self));
927 Py_RETURN_NONE;
930 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
932 PyObject *py_msg;
933 PyObject *py_controls = Py_None;
934 struct ldb_context *ldb_ctx;
935 struct ldb_request *req;
936 struct ldb_control **parsed_controls;
937 struct ldb_message *msg;
938 int ret;
939 TALLOC_CTX *mem_ctx;
940 bool validate=true;
941 const char * const kwnames[] = { "message", "controls", "validate", NULL };
943 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
944 discard_const_p(char *, kwnames),
945 &py_msg, &py_controls, &validate))
946 return NULL;
948 mem_ctx = talloc_new(NULL);
949 if (mem_ctx == NULL) {
950 PyErr_NoMemory();
951 return NULL;
953 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
955 if (py_controls == Py_None) {
956 parsed_controls = NULL;
957 } else {
958 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
959 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
960 talloc_free(controls);
963 if (!PyLdbMessage_Check(py_msg)) {
964 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
965 talloc_free(mem_ctx);
966 return NULL;
968 msg = pyldb_Message_AsMessage(py_msg);
970 if (validate) {
971 ret = ldb_msg_sanity_check(ldb_ctx, msg);
972 if (ret != LDB_SUCCESS) {
973 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
974 talloc_free(mem_ctx);
975 return NULL;
979 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
980 NULL, ldb_op_default_callback, NULL);
981 if (ret != LDB_SUCCESS) {
982 PyErr_SetString(PyExc_TypeError, "failed to build request");
983 talloc_free(mem_ctx);
984 return NULL;
987 /* do request and autostart a transaction */
988 /* Then let's LDB handle the message error in case of pb as they are meaningful */
990 ret = ldb_transaction_start(ldb_ctx);
991 if (ret != LDB_SUCCESS) {
992 talloc_free(mem_ctx);
993 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
996 ret = ldb_request(ldb_ctx, req);
997 if (ret == LDB_SUCCESS) {
998 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1001 if (ret == LDB_SUCCESS) {
1002 ret = ldb_transaction_commit(ldb_ctx);
1003 } else {
1004 ldb_transaction_cancel(ldb_ctx);
1007 talloc_free(mem_ctx);
1008 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1010 Py_RETURN_NONE;
1015 * Obtain a ldb message from a Python Dictionary object.
1017 * @param mem_ctx Memory context
1018 * @param py_obj Python Dictionary object
1019 * @param ldb_ctx LDB context
1020 * @param mod_flags Flags to be set on every message element
1021 * @return ldb_message on success or NULL on failure
1023 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1024 PyObject *py_obj,
1025 struct ldb_context *ldb_ctx,
1026 unsigned int mod_flags)
1028 struct ldb_message *msg;
1029 unsigned int msg_pos = 0;
1030 Py_ssize_t dict_pos = 0;
1031 PyObject *key, *value;
1032 struct ldb_message_element *msg_el;
1033 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1035 msg = ldb_msg_new(mem_ctx);
1036 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1038 if (dn_value) {
1039 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1040 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1041 return NULL;
1043 if (msg->dn == NULL) {
1044 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1045 return NULL;
1047 } else {
1048 PyErr_SetString(PyExc_TypeError, "no dn set");
1049 return NULL;
1052 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1053 char *key_str = PyString_AsString(key);
1054 if (strcmp(key_str, "dn") != 0) {
1055 msg_el = PyObject_AsMessageElement(msg->elements, value,
1056 mod_flags, key_str);
1057 if (msg_el == NULL) {
1058 PyErr_SetString(PyExc_TypeError, "unable to import element");
1059 return NULL;
1061 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1062 msg_pos++;
1066 msg->num_elements = msg_pos;
1068 return msg;
1071 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1073 PyObject *py_obj;
1074 int ret;
1075 struct ldb_context *ldb_ctx;
1076 struct ldb_request *req;
1077 struct ldb_message *msg = NULL;
1078 PyObject *py_controls = Py_None;
1079 TALLOC_CTX *mem_ctx;
1080 struct ldb_control **parsed_controls;
1081 const char * const kwnames[] = { "message", "controls", NULL };
1083 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1084 discard_const_p(char *, kwnames),
1085 &py_obj, &py_controls))
1086 return NULL;
1088 mem_ctx = talloc_new(NULL);
1089 if (mem_ctx == NULL) {
1090 PyErr_NoMemory();
1091 return NULL;
1093 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1095 if (py_controls == Py_None) {
1096 parsed_controls = NULL;
1097 } else {
1098 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1099 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1100 talloc_free(controls);
1103 if (PyLdbMessage_Check(py_obj)) {
1104 msg = pyldb_Message_AsMessage(py_obj);
1105 } else if (PyDict_Check(py_obj)) {
1106 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1107 } else {
1108 PyErr_SetString(PyExc_TypeError,
1109 "Dictionary or LdbMessage object expected!");
1112 if (!msg) {
1113 /* we should have a PyErr already set */
1114 talloc_free(mem_ctx);
1115 return NULL;
1118 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1119 if (ret != LDB_SUCCESS) {
1120 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1121 talloc_free(mem_ctx);
1122 return NULL;
1125 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1126 NULL, ldb_op_default_callback, NULL);
1127 if (ret != LDB_SUCCESS) {
1128 PyErr_SetString(PyExc_TypeError, "failed to build request");
1129 talloc_free(mem_ctx);
1130 return NULL;
1133 /* do request and autostart a transaction */
1134 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1136 ret = ldb_transaction_start(ldb_ctx);
1137 if (ret != LDB_SUCCESS) {
1138 talloc_free(mem_ctx);
1139 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1142 ret = ldb_request(ldb_ctx, req);
1143 if (ret == LDB_SUCCESS) {
1144 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1147 if (ret == LDB_SUCCESS) {
1148 ret = ldb_transaction_commit(ldb_ctx);
1149 } else {
1150 ldb_transaction_cancel(ldb_ctx);
1153 talloc_free(mem_ctx);
1154 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1156 Py_RETURN_NONE;
1159 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1161 PyObject *py_dn;
1162 struct ldb_dn *dn;
1163 int ret;
1164 struct ldb_context *ldb_ctx;
1165 struct ldb_request *req;
1166 PyObject *py_controls = Py_None;
1167 TALLOC_CTX *mem_ctx;
1168 struct ldb_control **parsed_controls;
1169 const char * const kwnames[] = { "dn", "controls", NULL };
1171 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1172 discard_const_p(char *, kwnames),
1173 &py_dn, &py_controls))
1174 return NULL;
1176 mem_ctx = talloc_new(NULL);
1177 if (mem_ctx == NULL) {
1178 PyErr_NoMemory();
1179 return NULL;
1181 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1183 if (py_controls == Py_None) {
1184 parsed_controls = NULL;
1185 } else {
1186 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1187 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1188 talloc_free(controls);
1191 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1192 talloc_free(mem_ctx);
1193 return NULL;
1196 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1197 NULL, ldb_op_default_callback, NULL);
1198 if (ret != LDB_SUCCESS) {
1199 PyErr_SetString(PyExc_TypeError, "failed to build request");
1200 talloc_free(mem_ctx);
1201 return NULL;
1204 /* do request and autostart a transaction */
1205 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1207 ret = ldb_transaction_start(ldb_ctx);
1208 if (ret != LDB_SUCCESS) {
1209 talloc_free(mem_ctx);
1210 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1213 ret = ldb_request(ldb_ctx, req);
1214 if (ret == LDB_SUCCESS) {
1215 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1218 if (ret == LDB_SUCCESS) {
1219 ret = ldb_transaction_commit(ldb_ctx);
1220 } else {
1221 ldb_transaction_cancel(ldb_ctx);
1224 talloc_free(mem_ctx);
1225 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1227 Py_RETURN_NONE;
1230 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1232 PyObject *py_dn1, *py_dn2;
1233 struct ldb_dn *dn1, *dn2;
1234 int ret;
1235 TALLOC_CTX *mem_ctx;
1236 PyObject *py_controls = Py_None;
1237 struct ldb_control **parsed_controls;
1238 struct ldb_context *ldb_ctx;
1239 struct ldb_request *req;
1240 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1242 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1244 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1245 discard_const_p(char *, kwnames),
1246 &py_dn1, &py_dn2, &py_controls))
1247 return NULL;
1250 mem_ctx = talloc_new(NULL);
1251 if (mem_ctx == NULL) {
1252 PyErr_NoMemory();
1253 return NULL;
1256 if (py_controls == Py_None) {
1257 parsed_controls = NULL;
1258 } else {
1259 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1260 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1261 talloc_free(controls);
1265 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1266 talloc_free(mem_ctx);
1267 return NULL;
1270 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1271 talloc_free(mem_ctx);
1272 return NULL;
1275 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1276 NULL, ldb_op_default_callback, NULL);
1277 if (ret != LDB_SUCCESS) {
1278 PyErr_SetString(PyExc_TypeError, "failed to build request");
1279 talloc_free(mem_ctx);
1280 return NULL;
1283 /* do request and autostart a transaction */
1284 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1286 ret = ldb_transaction_start(ldb_ctx);
1287 if (ret != LDB_SUCCESS) {
1288 talloc_free(mem_ctx);
1289 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1292 ret = ldb_request(ldb_ctx, req);
1293 if (ret == LDB_SUCCESS) {
1294 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1297 if (ret == LDB_SUCCESS) {
1298 ret = ldb_transaction_commit(ldb_ctx);
1299 } else {
1300 ldb_transaction_cancel(ldb_ctx);
1303 talloc_free(mem_ctx);
1304 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1306 Py_RETURN_NONE;
1309 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1311 char *name;
1312 if (!PyArg_ParseTuple(args, "s", &name))
1313 return NULL;
1315 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1317 Py_RETURN_NONE;
1320 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1322 char *attribute, *syntax;
1323 unsigned int flags;
1324 int ret;
1325 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1326 return NULL;
1328 ret = ldb_schema_attribute_add(pyldb_Ldb_AsLdbContext(self), attribute, flags, syntax);
1330 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, pyldb_Ldb_AsLdbContext(self));
1332 Py_RETURN_NONE;
1335 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1337 if (ldif == NULL) {
1338 Py_RETURN_NONE;
1339 } else {
1340 /* We don't want this attached to the 'ldb' any more */
1341 return Py_BuildValue(discard_const_p(char, "(iO)"),
1342 ldif->changetype,
1343 PyLdbMessage_FromMessage(ldif->msg));
1348 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1350 int changetype;
1351 PyObject *py_msg;
1352 struct ldb_ldif ldif;
1353 PyObject *ret;
1354 char *string;
1355 TALLOC_CTX *mem_ctx;
1357 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1358 return NULL;
1360 if (!PyLdbMessage_Check(py_msg)) {
1361 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1362 return NULL;
1365 ldif.msg = pyldb_Message_AsMessage(py_msg);
1366 ldif.changetype = changetype;
1368 mem_ctx = talloc_new(NULL);
1370 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1371 if (!string) {
1372 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1373 return NULL;
1376 ret = PyString_FromString(string);
1378 talloc_free(mem_ctx);
1380 return ret;
1383 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1385 PyObject *list;
1386 struct ldb_ldif *ldif;
1387 const char *s;
1389 TALLOC_CTX *mem_ctx;
1391 if (!PyArg_ParseTuple(args, "s", &s))
1392 return NULL;
1394 mem_ctx = talloc_new(NULL);
1395 if (!mem_ctx) {
1396 Py_RETURN_NONE;
1399 list = PyList_New(0);
1400 while (s && *s != '\0') {
1401 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1402 talloc_steal(mem_ctx, ldif);
1403 if (ldif) {
1404 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1405 } else {
1406 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1407 talloc_free(mem_ctx);
1408 return NULL;
1411 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1412 return PyObject_GetIter(list);
1415 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1417 int ldb_ret;
1418 PyObject *py_msg_old;
1419 PyObject *py_msg_new;
1420 struct ldb_message *diff;
1421 struct ldb_context *ldb;
1422 PyObject *py_ret;
1424 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1425 return NULL;
1427 if (!PyLdbMessage_Check(py_msg_old)) {
1428 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1429 return NULL;
1432 if (!PyLdbMessage_Check(py_msg_new)) {
1433 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1434 return NULL;
1437 ldb = pyldb_Ldb_AsLdbContext(self);
1438 ldb_ret = ldb_msg_difference(ldb, ldb,
1439 pyldb_Message_AsMessage(py_msg_old),
1440 pyldb_Message_AsMessage(py_msg_new),
1441 &diff);
1442 if (ldb_ret != LDB_SUCCESS) {
1443 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1444 return NULL;
1447 py_ret = PyLdbMessage_FromMessage(diff);
1449 talloc_unlink(ldb, diff);
1451 return py_ret;
1454 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1456 const struct ldb_schema_attribute *a;
1457 struct ldb_val old_val;
1458 struct ldb_val new_val;
1459 TALLOC_CTX *mem_ctx;
1460 PyObject *ret;
1461 char *element_name;
1462 PyObject *val;
1464 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1465 return NULL;
1467 mem_ctx = talloc_new(NULL);
1469 old_val.data = (uint8_t *)PyString_AsString(val);
1470 old_val.length = PyString_Size(val);
1472 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1474 if (a == NULL) {
1475 Py_RETURN_NONE;
1478 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1479 talloc_free(mem_ctx);
1480 Py_RETURN_NONE;
1483 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1485 talloc_free(mem_ctx);
1487 return ret;
1490 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1492 PyObject *py_base = Py_None;
1493 int scope = LDB_SCOPE_DEFAULT;
1494 char *expr = NULL;
1495 PyObject *py_attrs = Py_None;
1496 PyObject *py_controls = Py_None;
1497 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1498 int ret;
1499 struct ldb_result *res;
1500 struct ldb_request *req;
1501 const char **attrs;
1502 struct ldb_context *ldb_ctx;
1503 struct ldb_control **parsed_controls;
1504 struct ldb_dn *base;
1505 PyObject *py_ret;
1506 TALLOC_CTX *mem_ctx;
1508 /* type "int" rather than "enum" for "scope" is intentional */
1509 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1510 discard_const_p(char *, kwnames),
1511 &py_base, &scope, &expr, &py_attrs, &py_controls))
1512 return NULL;
1515 mem_ctx = talloc_new(NULL);
1516 if (mem_ctx == NULL) {
1517 PyErr_NoMemory();
1518 return NULL;
1520 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1522 if (py_attrs == Py_None) {
1523 attrs = NULL;
1524 } else {
1525 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1526 if (attrs == NULL) {
1527 talloc_free(mem_ctx);
1528 return NULL;
1532 if (py_base == Py_None) {
1533 base = ldb_get_default_basedn(ldb_ctx);
1534 } else {
1535 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1536 talloc_free(attrs);
1537 return NULL;
1541 if (py_controls == Py_None) {
1542 parsed_controls = NULL;
1543 } else {
1544 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1545 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1546 talloc_free(controls);
1549 res = talloc_zero(mem_ctx, struct ldb_result);
1550 if (res == NULL) {
1551 PyErr_NoMemory();
1552 talloc_free(mem_ctx);
1553 return NULL;
1556 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1557 base,
1558 scope,
1559 expr,
1560 attrs,
1561 parsed_controls,
1562 res,
1563 ldb_search_default_callback,
1564 NULL);
1566 if (ret != LDB_SUCCESS) {
1567 talloc_free(mem_ctx);
1568 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1569 return NULL;
1572 talloc_steal(req, attrs);
1574 ret = ldb_request(ldb_ctx, req);
1576 if (ret == LDB_SUCCESS) {
1577 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1580 if (ret != LDB_SUCCESS) {
1581 talloc_free(mem_ctx);
1582 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1583 return NULL;
1586 py_ret = PyLdbResult_FromResult(res);
1588 talloc_free(mem_ctx);
1590 return py_ret;
1593 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1595 char *name;
1596 void *data;
1598 if (!PyArg_ParseTuple(args, "s", &name))
1599 return NULL;
1601 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1603 if (data == NULL)
1604 Py_RETURN_NONE;
1606 /* FIXME: More interpretation */
1608 return Py_True;
1611 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1613 char *name;
1614 PyObject *data;
1616 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1617 return NULL;
1619 /* FIXME: More interpretation */
1621 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1623 Py_RETURN_NONE;
1626 static PyObject *py_ldb_modules(PyLdbObject *self)
1628 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1629 PyObject *ret = PyList_New(0);
1630 struct ldb_module *mod;
1632 for (mod = ldb->modules; mod; mod = mod->next) {
1633 PyList_Append(ret, PyLdbModule_FromModule(mod));
1636 return ret;
1639 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1641 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1642 int type, ret;
1643 uint64_t value;
1645 if (!PyArg_ParseTuple(args, "i", &type))
1646 return NULL;
1648 /* FIXME: More interpretation */
1650 ret = ldb_sequence_number(ldb, type, &value);
1652 if (ret != LDB_SUCCESS) {
1653 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1654 return NULL;
1656 return PyLong_FromLongLong(value);
1658 static PyMethodDef py_ldb_methods[] = {
1659 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1660 "S.set_debug(callback) -> None\n"
1661 "Set callback for LDB debug messages.\n"
1662 "The callback should accept a debug level and debug text." },
1663 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1664 "S.set_create_perms(mode) -> None\n"
1665 "Set mode to use when creating new LDB files." },
1666 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1667 "S.set_modules_dir(path) -> None\n"
1668 "Set path LDB should search for modules" },
1669 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1670 "S.transaction_start() -> None\n"
1671 "Start a new transaction." },
1672 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1673 "S.transaction_prepare_commit() -> None\n"
1674 "prepare to commit a new transaction (2-stage commit)." },
1675 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1676 "S.transaction_commit() -> None\n"
1677 "commit a new transaction." },
1678 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1679 "S.transaction_cancel() -> None\n"
1680 "cancel a new transaction." },
1681 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1682 NULL },
1683 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1684 NULL },
1685 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1686 NULL },
1687 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1688 NULL },
1689 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1690 NULL },
1691 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1692 "S.connect(url, flags=0, options=None) -> None\n"
1693 "Connect to a LDB URL." },
1694 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1695 "S.modify(message, controls=None, validate=False) -> None\n"
1696 "Modify an entry." },
1697 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1698 "S.add(message, controls=None) -> None\n"
1699 "Add an entry." },
1700 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1701 "S.delete(dn, controls=None) -> None\n"
1702 "Remove an entry." },
1703 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1704 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1705 "Rename an entry." },
1706 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1707 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1708 "Search in a database.\n"
1709 "\n"
1710 ":param base: Optional base DN to search\n"
1711 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1712 ":param expression: Optional search expression\n"
1713 ":param attrs: Attributes to return (defaults to all)\n"
1714 ":param controls: Optional list of controls\n"
1715 ":return: Iterator over Message objects\n"
1717 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1718 NULL },
1719 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1720 NULL },
1721 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1722 NULL },
1723 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1724 "S.parse_ldif(ldif) -> iter(messages)\n"
1725 "Parse a string formatted using LDIF." },
1726 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1727 "S.write_ldif(message, changetype) -> ldif\n"
1728 "Print the message as a string formatted using LDIF." },
1729 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1730 "S.msg_diff(Message) -> Message\n"
1731 "Return an LDB Message of the difference between two Message objects." },
1732 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1733 "S.get_opaque(name) -> value\n"
1734 "Get an opaque value set on this LDB connection. \n"
1735 ":note: The returned value may not be useful in Python."
1737 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1738 "S.set_opaque(name, value) -> None\n"
1739 "Set an opaque value on this LDB connection. \n"
1740 ":note: Passing incorrect values may cause crashes." },
1741 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1742 "S.modules() -> list\n"
1743 "Return the list of modules on this LDB connection " },
1744 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1745 "S.sequence_number(type) -> value\n"
1746 "Return the value of the sequence according to the requested type" },
1747 { NULL },
1750 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1752 PyLdbModuleObject *ret;
1754 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1755 if (ret == NULL) {
1756 PyErr_NoMemory();
1757 return NULL;
1759 ret->mem_ctx = talloc_new(NULL);
1760 ret->mod = talloc_reference(ret->mem_ctx, mod);
1761 return (PyObject *)ret;
1764 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1766 return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1769 static PyGetSetDef py_ldb_getset[] = {
1770 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1771 { NULL }
1774 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1776 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1777 struct ldb_dn *dn;
1778 struct ldb_result *result;
1779 unsigned int count;
1780 int ret;
1782 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1783 return -1;
1786 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1787 NULL);
1788 if (ret != LDB_SUCCESS) {
1789 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1790 return -1;
1793 count = result->count;
1795 talloc_free(result);
1797 if (count > 1) {
1798 PyErr_Format(PyExc_RuntimeError,
1799 "Searching for [%s] dn gave %u results!",
1800 ldb_dn_get_linearized(dn),
1801 count);
1802 return -1;
1805 return count;
1808 static PySequenceMethods py_ldb_seq = {
1809 .sq_contains = (objobjproc)py_ldb_contains,
1812 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1814 PyLdbObject *ret;
1816 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1817 if (ret == NULL) {
1818 PyErr_NoMemory();
1819 return NULL;
1821 ret->mem_ctx = talloc_new(NULL);
1822 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1823 return (PyObject *)ret;
1826 static void py_ldb_dealloc(PyLdbObject *self)
1828 talloc_free(self->mem_ctx);
1829 self->ob_type->tp_free(self);
1832 static PyTypeObject PyLdb = {
1833 .tp_name = "ldb.Ldb",
1834 .tp_methods = py_ldb_methods,
1835 .tp_repr = (reprfunc)py_ldb_repr,
1836 .tp_new = py_ldb_new,
1837 .tp_init = (initproc)py_ldb_init,
1838 .tp_dealloc = (destructor)py_ldb_dealloc,
1839 .tp_getset = py_ldb_getset,
1840 .tp_getattro = PyObject_GenericGetAttr,
1841 .tp_basicsize = sizeof(PyLdbObject),
1842 .tp_doc = "Connection to a LDB database.",
1843 .tp_as_sequence = &py_ldb_seq,
1844 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1847 static void py_ldb_result_dealloc(PyLdbResultObject *self)
1849 talloc_free(self->mem_ctx);
1850 Py_DECREF(self->msgs);
1851 Py_DECREF(self->referals);
1852 Py_DECREF(self->controls);
1853 self->ob_type->tp_free(self);
1856 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
1858 Py_INCREF(self->msgs);
1859 return self->msgs;
1862 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
1864 Py_INCREF(self->controls);
1865 return self->controls;
1868 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
1870 Py_INCREF(self->referals);
1871 return self->referals;
1874 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
1876 Py_ssize_t size;
1877 if (self->msgs == NULL) {
1878 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
1879 return NULL;
1881 size = PyList_Size(self->msgs);
1882 return PyInt_FromLong(size);
1885 static PyGetSetDef py_ldb_result_getset[] = {
1886 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
1887 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
1888 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
1889 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
1890 { NULL }
1893 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
1895 return PyObject_GetIter(self->msgs);
1898 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
1900 return PySequence_Size(self->msgs);
1903 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
1905 return PySequence_GetItem(self->msgs, idx);
1908 static PySequenceMethods py_ldb_result_seq = {
1909 .sq_length = (lenfunc)py_ldb_result_len,
1910 .sq_item = (ssizeargfunc)py_ldb_result_find,
1913 static PyObject *py_ldb_result_repr(PyLdbObject *self)
1915 return PyString_FromFormat("<ldb result>");
1919 static PyTypeObject PyLdbResult = {
1920 .tp_name = "ldb.Result",
1921 .tp_repr = (reprfunc)py_ldb_result_repr,
1922 .tp_dealloc = (destructor)py_ldb_result_dealloc,
1923 .tp_iter = (getiterfunc)py_ldb_result_iter,
1924 .tp_getset = py_ldb_result_getset,
1925 .tp_getattro = PyObject_GenericGetAttr,
1926 .tp_basicsize = sizeof(PyLdbResultObject),
1927 .tp_as_sequence = &py_ldb_result_seq,
1928 .tp_doc = "LDB result.",
1929 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1932 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1934 return PyString_FromFormat("<ldb module '%s'>",
1935 pyldb_Module_AsModule(self)->ops->name);
1938 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1940 return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
1943 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1945 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
1946 Py_RETURN_NONE;
1949 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1951 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
1952 Py_RETURN_NONE;
1955 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
1957 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
1958 Py_RETURN_NONE;
1961 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
1963 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
1964 int ret, scope;
1965 struct ldb_request *req;
1966 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
1967 struct ldb_module *mod;
1968 const char * const*attrs;
1970 /* type "int" rather than "enum" for "scope" is intentional */
1971 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
1972 discard_const_p(char *, kwnames),
1973 &py_base, &scope, &py_tree, &py_attrs))
1974 return NULL;
1976 mod = self->mod;
1978 if (py_attrs == Py_None) {
1979 attrs = NULL;
1980 } else {
1981 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
1982 if (attrs == NULL)
1983 return NULL;
1986 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
1987 scope, NULL /* expr */, attrs,
1988 NULL /* controls */, NULL, NULL, NULL);
1990 talloc_steal(req, attrs);
1992 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1994 req->op.search.res = NULL;
1996 ret = mod->ops->search(mod, req);
1998 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2000 py_ret = PyLdbResult_FromResult(req->op.search.res);
2002 talloc_free(req);
2004 return py_ret;
2008 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2010 struct ldb_request *req;
2011 PyObject *py_message;
2012 int ret;
2013 struct ldb_module *mod;
2015 if (!PyArg_ParseTuple(args, "O", &py_message))
2016 return NULL;
2018 req = talloc_zero(NULL, struct ldb_request);
2019 req->operation = LDB_ADD;
2020 req->op.add.message = pyldb_Message_AsMessage(py_message);
2022 mod = pyldb_Module_AsModule(self);
2023 ret = mod->ops->add(mod, req);
2025 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2027 Py_RETURN_NONE;
2030 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2032 int ret;
2033 struct ldb_request *req;
2034 PyObject *py_message;
2035 struct ldb_module *mod;
2037 if (!PyArg_ParseTuple(args, "O", &py_message))
2038 return NULL;
2040 req = talloc_zero(NULL, struct ldb_request);
2041 req->operation = LDB_MODIFY;
2042 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2044 mod = pyldb_Module_AsModule(self);
2045 ret = mod->ops->modify(mod, req);
2047 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2049 Py_RETURN_NONE;
2052 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2054 int ret;
2055 struct ldb_request *req;
2056 PyObject *py_dn;
2058 if (!PyArg_ParseTuple(args, "O", &py_dn))
2059 return NULL;
2061 req = talloc_zero(NULL, struct ldb_request);
2062 req->operation = LDB_DELETE;
2063 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2065 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2067 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2069 Py_RETURN_NONE;
2072 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2074 int ret;
2075 struct ldb_request *req;
2076 PyObject *py_dn1, *py_dn2;
2078 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
2079 return NULL;
2081 req = talloc_zero(NULL, struct ldb_request);
2083 req->operation = LDB_RENAME;
2084 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2085 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2087 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2089 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2091 Py_RETURN_NONE;
2094 static PyMethodDef py_ldb_module_methods[] = {
2095 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2096 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2097 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2098 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2099 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2100 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2101 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2102 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2103 { NULL },
2106 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2108 talloc_free(self->mem_ctx);
2109 PyObject_Del(self);
2112 static PyTypeObject PyLdbModule = {
2113 .tp_name = "ldb.LdbModule",
2114 .tp_methods = py_ldb_module_methods,
2115 .tp_repr = (reprfunc)py_ldb_module_repr,
2116 .tp_str = (reprfunc)py_ldb_module_str,
2117 .tp_basicsize = sizeof(PyLdbModuleObject),
2118 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2119 .tp_flags = Py_TPFLAGS_DEFAULT,
2124 * Create a ldb_message_element from a Python object.
2126 * This will accept any sequence objects that contains strings, or
2127 * a string object.
2129 * A reference to set_obj will be borrowed.
2131 * @param mem_ctx Memory context
2132 * @param set_obj Python object to convert
2133 * @param flags ldb_message_element flags to set
2134 * @param attr_name Name of the attribute
2135 * @return New ldb_message_element, allocated as child of mem_ctx
2137 static struct ldb_message_element *PyObject_AsMessageElement(
2138 TALLOC_CTX *mem_ctx,
2139 PyObject *set_obj,
2140 unsigned int flags,
2141 const char *attr_name)
2143 struct ldb_message_element *me;
2145 if (pyldb_MessageElement_Check(set_obj)) {
2146 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2147 /* We have to talloc_reference() the memory context, not the pointer
2148 * which may not actually be it's own context */
2149 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2150 return pyldb_MessageElement_AsMessageElement(set_obj);
2152 return NULL;
2155 me = talloc(mem_ctx, struct ldb_message_element);
2156 if (me == NULL) {
2157 PyErr_NoMemory();
2158 return NULL;
2161 me->name = talloc_strdup(me, attr_name);
2162 me->flags = flags;
2163 if (PyString_Check(set_obj)) {
2164 me->num_values = 1;
2165 me->values = talloc_array(me, struct ldb_val, me->num_values);
2166 me->values[0].length = PyString_Size(set_obj);
2167 me->values[0].data = talloc_memdup(me,
2168 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2169 } else if (PySequence_Check(set_obj)) {
2170 Py_ssize_t i;
2171 me->num_values = PySequence_Size(set_obj);
2172 me->values = talloc_array(me, struct ldb_val, me->num_values);
2173 for (i = 0; i < me->num_values; i++) {
2174 PyObject *obj = PySequence_GetItem(set_obj, i);
2175 if (!PyString_Check(obj)) {
2176 PyErr_Format(PyExc_TypeError,
2177 "Expected string as element %zd in list", i);
2178 talloc_free(me);
2179 return NULL;
2182 me->values[i].length = PyString_Size(obj);
2183 me->values[i].data = talloc_memdup(me,
2184 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2186 } else {
2187 talloc_free(me);
2188 me = NULL;
2191 return me;
2195 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2196 struct ldb_message_element *me)
2198 Py_ssize_t i;
2199 PyObject *result;
2201 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2202 result = PyList_New(me->num_values);
2204 for (i = 0; i < me->num_values; i++) {
2205 PyList_SetItem(result, i,
2206 PyObject_FromLdbValue(&me->values[i]));
2209 return result;
2212 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2214 unsigned int i;
2215 if (!PyArg_ParseTuple(args, "I", &i))
2216 return NULL;
2217 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2218 Py_RETURN_NONE;
2220 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2223 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2225 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2226 return PyInt_FromLong(el->flags);
2229 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2231 unsigned int flags;
2232 struct ldb_message_element *el;
2233 if (!PyArg_ParseTuple(args, "I", &flags))
2234 return NULL;
2236 el = pyldb_MessageElement_AsMessageElement(self);
2237 el->flags = flags;
2238 Py_RETURN_NONE;
2241 static PyMethodDef py_ldb_msg_element_methods[] = {
2242 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2243 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2244 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2245 { NULL },
2248 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2250 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2253 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2255 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2256 if (idx < 0 || idx >= el->num_values) {
2257 PyErr_SetString(PyExc_IndexError, "Out of range");
2258 return NULL;
2260 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2263 static PySequenceMethods py_ldb_msg_element_seq = {
2264 .sq_length = (lenfunc)py_ldb_msg_element_len,
2265 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2268 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2270 int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2271 pyldb_MessageElement_AsMessageElement(other));
2272 return SIGN(ret);
2275 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2277 PyObject *el = ldb_msg_element_to_set(NULL,
2278 pyldb_MessageElement_AsMessageElement(self));
2279 return PyObject_GetIter(el);
2282 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2284 PyLdbMessageElementObject *ret;
2285 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2286 if (ret == NULL) {
2287 PyErr_NoMemory();
2288 return NULL;
2290 ret->mem_ctx = talloc_new(NULL);
2291 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2292 PyErr_NoMemory();
2293 return NULL;
2295 ret->el = el;
2296 return (PyObject *)ret;
2299 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2301 PyObject *py_elements = NULL;
2302 struct ldb_message_element *el;
2303 unsigned int flags = 0;
2304 char *name = NULL;
2305 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2306 PyLdbMessageElementObject *ret;
2307 TALLOC_CTX *mem_ctx;
2309 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2310 discard_const_p(char *, kwnames),
2311 &py_elements, &flags, &name))
2312 return NULL;
2314 mem_ctx = talloc_new(NULL);
2315 if (mem_ctx == NULL) {
2316 PyErr_NoMemory();
2317 return NULL;
2320 el = talloc_zero(mem_ctx, struct ldb_message_element);
2321 if (el == NULL) {
2322 PyErr_NoMemory();
2323 talloc_free(mem_ctx);
2324 return NULL;
2327 if (py_elements != NULL) {
2328 Py_ssize_t i;
2329 if (PyString_Check(py_elements)) {
2330 el->num_values = 1;
2331 el->values = talloc_array(el, struct ldb_val, 1);
2332 if (el->values == NULL) {
2333 talloc_free(mem_ctx);
2334 PyErr_NoMemory();
2335 return NULL;
2337 el->values[0].length = PyString_Size(py_elements);
2338 el->values[0].data = talloc_memdup(el->values,
2339 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2340 } else if (PySequence_Check(py_elements)) {
2341 el->num_values = PySequence_Size(py_elements);
2342 el->values = talloc_array(el, struct ldb_val, el->num_values);
2343 if (el->values == NULL) {
2344 talloc_free(mem_ctx);
2345 PyErr_NoMemory();
2346 return NULL;
2348 for (i = 0; i < el->num_values; i++) {
2349 PyObject *item = PySequence_GetItem(py_elements, i);
2350 if (item == NULL) {
2351 talloc_free(mem_ctx);
2352 return NULL;
2354 if (!PyString_Check(item)) {
2355 PyErr_Format(PyExc_TypeError,
2356 "Expected string as element %zd in list", i);
2357 talloc_free(mem_ctx);
2358 return NULL;
2360 el->values[i].length = PyString_Size(item);
2361 el->values[i].data = talloc_memdup(el,
2362 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2364 } else {
2365 PyErr_SetString(PyExc_TypeError,
2366 "Expected string or list");
2367 talloc_free(mem_ctx);
2368 return NULL;
2372 el->flags = flags;
2373 el->name = talloc_strdup(el, name);
2375 ret = PyObject_New(PyLdbMessageElementObject, type);
2376 if (ret == NULL) {
2377 talloc_free(mem_ctx);
2378 return NULL;
2381 ret->mem_ctx = mem_ctx;
2382 ret->el = el;
2383 return (PyObject *)ret;
2386 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2388 char *element_str = NULL;
2389 Py_ssize_t i;
2390 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2391 PyObject *ret;
2393 for (i = 0; i < el->num_values; i++) {
2394 PyObject *o = py_ldb_msg_element_find(self, i);
2395 if (element_str == NULL)
2396 element_str = talloc_strdup(NULL, PyObject_REPR(o));
2397 else
2398 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2401 if (element_str != NULL) {
2402 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2403 talloc_free(element_str);
2404 } else {
2405 ret = PyString_FromString("MessageElement([])");
2408 return ret;
2411 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2413 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2415 if (el->num_values == 1)
2416 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2417 else
2418 Py_RETURN_NONE;
2421 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2423 talloc_free(self->mem_ctx);
2424 PyObject_Del(self);
2427 static PyTypeObject PyLdbMessageElement = {
2428 .tp_name = "ldb.MessageElement",
2429 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2430 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2431 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2432 .tp_str = (reprfunc)py_ldb_msg_element_str,
2433 .tp_methods = py_ldb_msg_element_methods,
2434 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2435 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2436 .tp_as_sequence = &py_ldb_msg_element_seq,
2437 .tp_new = py_ldb_msg_element_new,
2438 .tp_flags = Py_TPFLAGS_DEFAULT,
2442 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2444 PyObject *py_ldb;
2445 PyObject *py_dict;
2446 PyObject *py_ret;
2447 struct ldb_message *msg;
2448 struct ldb_context *ldb_ctx;
2449 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2451 if (!PyArg_ParseTuple(args, "O!O!|I",
2452 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2453 &mod_flags)) {
2454 return NULL;
2457 /* mask only flags we are going to use */
2458 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2459 if (!mod_flags) {
2460 PyErr_SetString(PyExc_ValueError,
2461 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2462 " expected as mod_flag value");
2463 return NULL;
2466 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2468 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2469 if (!msg) {
2470 return NULL;
2473 py_ret = PyLdbMessage_FromMessage(msg);
2475 talloc_unlink(ldb_ctx, msg);
2477 return py_ret;
2480 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2482 char *name;
2483 if (!PyArg_ParseTuple(args, "s", &name))
2484 return NULL;
2486 ldb_msg_remove_attr(self->msg, name);
2488 Py_RETURN_NONE;
2491 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2493 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2494 Py_ssize_t i, j = 0;
2495 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2496 if (msg->dn != NULL) {
2497 PyList_SetItem(obj, j, PyString_FromString("dn"));
2498 j++;
2500 for (i = 0; i < msg->num_elements; i++) {
2501 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2502 j++;
2504 return obj;
2507 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2509 struct ldb_message_element *el;
2510 char *name;
2511 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2512 if (!PyString_Check(py_name)) {
2513 PyErr_SetNone(PyExc_TypeError);
2514 return NULL;
2516 name = PyString_AsString(py_name);
2517 if (!strcmp(name, "dn"))
2518 return pyldb_Dn_FromDn(msg->dn);
2519 el = ldb_msg_find_element(msg, name);
2520 if (el == NULL) {
2521 return NULL;
2523 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2526 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2528 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2529 if (ret == NULL) {
2530 PyErr_SetString(PyExc_KeyError, "No such element");
2531 return NULL;
2533 return ret;
2536 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2538 PyObject *def = NULL;
2539 const char *kwnames[] = { "name", "default", "idx", NULL };
2540 const char *name = NULL;
2541 int idx = -1;
2542 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2543 struct ldb_message_element *el;
2545 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2546 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2547 return NULL;
2550 if (strcasecmp(name, "dn") == 0) {
2551 return pyldb_Dn_FromDn(msg->dn);
2554 el = ldb_msg_find_element(msg, name);
2556 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2557 if (def != NULL) {
2558 return def;
2560 Py_RETURN_NONE;
2563 if (idx == -1) {
2564 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2567 return PyObject_FromLdbValue(&el->values[idx]);
2570 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2572 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2573 Py_ssize_t i, j = 0;
2574 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2575 if (msg->dn != NULL) {
2576 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2577 j++;
2579 for (i = 0; i < msg->num_elements; i++, j++) {
2580 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2581 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2582 PyList_SetItem(l, j, value);
2584 return l;
2587 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2589 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2590 Py_ssize_t i = 0;
2591 PyObject *l = PyList_New(msg->num_elements);
2592 for (i = 0; i < msg->num_elements; i++) {
2593 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2595 return l;
2598 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2600 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2601 PyLdbMessageElementObject *py_element;
2602 int ret;
2603 struct ldb_message_element *el;
2605 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2606 return NULL;
2608 el = talloc_reference(msg, py_element->el);
2609 if (el == NULL) {
2610 PyErr_NoMemory();
2611 return NULL;
2614 ret = ldb_msg_add(msg, el, el->flags);
2615 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2617 Py_RETURN_NONE;
2620 static PyMethodDef py_ldb_msg_methods[] = {
2621 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2622 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2623 "Class method to create ldb.Message object from Dictionary.\n"
2624 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2625 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2626 "S.keys() -> list\n\n"
2627 "Return sequence of all attribute names." },
2628 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2629 "S.remove(name)\n\n"
2630 "Remove all entries for attributes with the specified name."},
2631 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2632 "msg.get(name,default=None,idx=None) -> string\n"
2633 "idx is the index into the values array\n"
2634 "if idx is None, then a list is returned\n"
2635 "if idx is not None, then the element with that index is returned\n"
2636 "if you pass the special name 'dn' then the DN object is returned\n"},
2637 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2638 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2639 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2640 "S.append(element)\n\n"
2641 "Add an element to this message." },
2642 { NULL },
2645 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2647 PyObject *list, *iter;
2649 list = py_ldb_msg_keys(self);
2650 iter = PyObject_GetIter(list);
2651 Py_DECREF(list);
2652 return iter;
2655 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2657 char *attr_name;
2659 if (!PyString_Check(name)) {
2660 PyErr_SetNone(PyExc_TypeError);
2661 return -1;
2664 attr_name = PyString_AsString(name);
2665 if (value == NULL) {
2666 /* delitem */
2667 ldb_msg_remove_attr(self->msg, attr_name);
2668 } else {
2669 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2670 value, 0, attr_name);
2671 if (el == NULL)
2672 return -1;
2673 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2674 ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2676 return 0;
2679 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2681 return pyldb_Message_AsMessage(self)->num_elements;
2684 static PyMappingMethods py_ldb_msg_mapping = {
2685 .mp_length = (lenfunc)py_ldb_msg_length,
2686 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2687 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2690 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2692 const char * const kwnames[] = { "dn", NULL };
2693 struct ldb_message *ret;
2694 TALLOC_CTX *mem_ctx;
2695 PyObject *pydn = NULL;
2696 PyLdbMessageObject *py_ret;
2698 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2699 discard_const_p(char *, kwnames),
2700 &pydn))
2701 return NULL;
2703 mem_ctx = talloc_new(NULL);
2704 if (mem_ctx == NULL) {
2705 PyErr_NoMemory();
2706 return NULL;
2709 ret = ldb_msg_new(mem_ctx);
2710 if (ret == NULL) {
2711 talloc_free(mem_ctx);
2712 PyErr_NoMemory();
2713 return NULL;
2716 if (pydn != NULL) {
2717 struct ldb_dn *dn;
2718 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2719 talloc_free(mem_ctx);
2720 return NULL;
2722 ret->dn = talloc_reference(ret, dn);
2725 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2726 if (py_ret == NULL) {
2727 PyErr_NoMemory();
2728 talloc_free(mem_ctx);
2729 return NULL;
2732 py_ret->mem_ctx = mem_ctx;
2733 py_ret->msg = ret;
2734 return (PyObject *)py_ret;
2737 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2739 PyLdbMessageObject *ret;
2741 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2742 if (ret == NULL) {
2743 PyErr_NoMemory();
2744 return NULL;
2746 ret->mem_ctx = talloc_new(NULL);
2747 ret->msg = talloc_reference(ret->mem_ctx, msg);
2748 return (PyObject *)ret;
2751 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2753 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2754 return pyldb_Dn_FromDn(msg->dn);
2757 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2759 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2760 if (!pyldb_Dn_Check(value)) {
2761 PyErr_SetNone(PyExc_TypeError);
2762 return -1;
2765 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2766 return 0;
2769 static PyGetSetDef py_ldb_msg_getset[] = {
2770 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2771 { NULL }
2774 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2776 PyObject *dict = PyDict_New(), *ret;
2777 if (PyDict_Update(dict, (PyObject *)self) != 0)
2778 return NULL;
2779 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2780 Py_DECREF(dict);
2781 return ret;
2784 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2786 talloc_free(self->mem_ctx);
2787 PyObject_Del(self);
2790 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2791 PyLdbMessageObject *py_msg2)
2793 struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
2794 *msg2 = pyldb_Message_AsMessage(py_msg2);
2795 unsigned int i;
2796 int ret;
2798 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2799 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2800 if (ret != 0) {
2801 return SIGN(ret);
2805 ret = msg1->num_elements - msg2->num_elements;
2806 if (ret != 0) {
2807 return SIGN(ret);
2810 for (i = 0; i < msg1->num_elements; i++) {
2811 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2812 &msg2->elements[i]);
2813 if (ret != 0) {
2814 return SIGN(ret);
2817 ret = ldb_msg_element_compare(&msg1->elements[i],
2818 &msg2->elements[i]);
2819 if (ret != 0) {
2820 return SIGN(ret);
2824 return 0;
2827 static PyTypeObject PyLdbMessage = {
2828 .tp_name = "ldb.Message",
2829 .tp_methods = py_ldb_msg_methods,
2830 .tp_getset = py_ldb_msg_getset,
2831 .tp_as_mapping = &py_ldb_msg_mapping,
2832 .tp_basicsize = sizeof(PyLdbMessageObject),
2833 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2834 .tp_new = py_ldb_msg_new,
2835 .tp_repr = (reprfunc)py_ldb_msg_repr,
2836 .tp_flags = Py_TPFLAGS_DEFAULT,
2837 .tp_iter = (getiterfunc)py_ldb_msg_iter,
2838 .tp_compare = (cmpfunc)py_ldb_msg_compare,
2841 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2843 PyLdbTreeObject *ret;
2845 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2846 if (ret == NULL) {
2847 PyErr_NoMemory();
2848 return NULL;
2851 ret->mem_ctx = talloc_new(NULL);
2852 ret->tree = talloc_reference(ret->mem_ctx, tree);
2853 return (PyObject *)ret;
2856 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2858 talloc_free(self->mem_ctx);
2859 PyObject_Del(self);
2862 static PyTypeObject PyLdbTree = {
2863 .tp_name = "ldb.Tree",
2864 .tp_basicsize = sizeof(PyLdbTreeObject),
2865 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2866 .tp_flags = Py_TPFLAGS_DEFAULT,
2869 /* Ldb_module */
2870 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2872 PyObject *py_ldb = (PyObject *)mod->private_data;
2873 PyObject *py_result, *py_base, *py_attrs, *py_tree;
2875 py_base = pyldb_Dn_FromDn(req->op.search.base);
2877 if (py_base == NULL)
2878 return LDB_ERR_OPERATIONS_ERROR;
2880 py_tree = PyLdbTree_FromTree(req->op.search.tree);
2882 if (py_tree == NULL)
2883 return LDB_ERR_OPERATIONS_ERROR;
2885 if (req->op.search.attrs == NULL) {
2886 py_attrs = Py_None;
2887 } else {
2888 int i, len;
2889 for (len = 0; req->op.search.attrs[len]; len++);
2890 py_attrs = PyList_New(len);
2891 for (i = 0; i < len; i++)
2892 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2895 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2896 discard_const_p(char, "OiOO"),
2897 py_base, req->op.search.scope, py_tree, py_attrs);
2899 Py_DECREF(py_attrs);
2900 Py_DECREF(py_tree);
2901 Py_DECREF(py_base);
2903 if (py_result == NULL) {
2904 return LDB_ERR_PYTHON_EXCEPTION;
2907 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2908 if (req->op.search.res == NULL) {
2909 return LDB_ERR_PYTHON_EXCEPTION;
2912 Py_DECREF(py_result);
2914 return LDB_SUCCESS;
2917 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2919 PyObject *py_ldb = (PyObject *)mod->private_data;
2920 PyObject *py_result, *py_msg;
2922 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2924 if (py_msg == NULL) {
2925 return LDB_ERR_OPERATIONS_ERROR;
2928 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2929 discard_const_p(char, "O"),
2930 py_msg);
2932 Py_DECREF(py_msg);
2934 if (py_result == NULL) {
2935 return LDB_ERR_PYTHON_EXCEPTION;
2938 Py_DECREF(py_result);
2940 return LDB_SUCCESS;
2943 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
2945 PyObject *py_ldb = (PyObject *)mod->private_data;
2946 PyObject *py_result, *py_msg;
2948 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
2950 if (py_msg == NULL) {
2951 return LDB_ERR_OPERATIONS_ERROR;
2954 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
2955 discard_const_p(char, "O"),
2956 py_msg);
2958 Py_DECREF(py_msg);
2960 if (py_result == NULL) {
2961 return LDB_ERR_PYTHON_EXCEPTION;
2964 Py_DECREF(py_result);
2966 return LDB_SUCCESS;
2969 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
2971 PyObject *py_ldb = (PyObject *)mod->private_data;
2972 PyObject *py_result, *py_dn;
2974 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
2976 if (py_dn == NULL)
2977 return LDB_ERR_OPERATIONS_ERROR;
2979 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
2980 discard_const_p(char, "O"),
2981 py_dn);
2983 if (py_result == NULL) {
2984 return LDB_ERR_PYTHON_EXCEPTION;
2987 Py_DECREF(py_result);
2989 return LDB_SUCCESS;
2992 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
2994 PyObject *py_ldb = (PyObject *)mod->private_data;
2995 PyObject *py_result, *py_olddn, *py_newdn;
2997 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
2999 if (py_olddn == NULL)
3000 return LDB_ERR_OPERATIONS_ERROR;
3002 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3004 if (py_newdn == NULL)
3005 return LDB_ERR_OPERATIONS_ERROR;
3007 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3008 discard_const_p(char, "OO"),
3009 py_olddn, py_newdn);
3011 Py_DECREF(py_olddn);
3012 Py_DECREF(py_newdn);
3014 if (py_result == NULL) {
3015 return LDB_ERR_PYTHON_EXCEPTION;
3018 Py_DECREF(py_result);
3020 return LDB_SUCCESS;
3023 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3025 PyObject *py_ldb = (PyObject *)mod->private_data;
3026 PyObject *py_result;
3028 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3029 discard_const_p(char, ""));
3031 return LDB_ERR_OPERATIONS_ERROR;
3034 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3036 PyObject *py_ldb = (PyObject *)mod->private_data;
3037 PyObject *py_result;
3039 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3040 discard_const_p(char, ""));
3042 return LDB_ERR_OPERATIONS_ERROR;
3045 static int py_module_start_transaction(struct ldb_module *mod)
3047 PyObject *py_ldb = (PyObject *)mod->private_data;
3048 PyObject *py_result;
3050 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3051 discard_const_p(char, ""));
3053 if (py_result == NULL) {
3054 return LDB_ERR_PYTHON_EXCEPTION;
3057 Py_DECREF(py_result);
3059 return LDB_SUCCESS;
3062 static int py_module_end_transaction(struct ldb_module *mod)
3064 PyObject *py_ldb = (PyObject *)mod->private_data;
3065 PyObject *py_result;
3067 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3068 discard_const_p(char, ""));
3070 if (py_result == NULL) {
3071 return LDB_ERR_PYTHON_EXCEPTION;
3074 Py_DECREF(py_result);
3076 return LDB_SUCCESS;
3079 static int py_module_del_transaction(struct ldb_module *mod)
3081 PyObject *py_ldb = (PyObject *)mod->private_data;
3082 PyObject *py_result;
3084 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3085 discard_const_p(char, ""));
3087 if (py_result == NULL) {
3088 return LDB_ERR_PYTHON_EXCEPTION;
3091 Py_DECREF(py_result);
3093 return LDB_SUCCESS;
3096 static int py_module_destructor(struct ldb_module *mod)
3098 Py_DECREF((PyObject *)mod->private_data);
3099 return 0;
3102 static int py_module_init(struct ldb_module *mod)
3104 PyObject *py_class = (PyObject *)mod->ops->private_data;
3105 PyObject *py_result, *py_next, *py_ldb;
3107 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3109 if (py_ldb == NULL)
3110 return LDB_ERR_OPERATIONS_ERROR;
3112 py_next = PyLdbModule_FromModule(mod->next);
3114 if (py_next == NULL)
3115 return LDB_ERR_OPERATIONS_ERROR;
3117 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3118 py_ldb, py_next);
3120 if (py_result == NULL) {
3121 return LDB_ERR_PYTHON_EXCEPTION;
3124 mod->private_data = py_result;
3126 talloc_set_destructor(mod, py_module_destructor);
3128 return ldb_next_init(mod);
3131 static PyObject *py_register_module(PyObject *module, PyObject *args)
3133 int ret;
3134 struct ldb_module_ops *ops;
3135 PyObject *input;
3137 if (!PyArg_ParseTuple(args, "O", &input))
3138 return NULL;
3140 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3141 if (ops == NULL) {
3142 PyErr_NoMemory();
3143 return NULL;
3146 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3148 Py_INCREF(input);
3149 ops->private_data = input;
3150 ops->init_context = py_module_init;
3151 ops->search = py_module_search;
3152 ops->add = py_module_add;
3153 ops->modify = py_module_modify;
3154 ops->del = py_module_del;
3155 ops->rename = py_module_rename;
3156 ops->request = py_module_request;
3157 ops->extended = py_module_extended;
3158 ops->start_transaction = py_module_start_transaction;
3159 ops->end_transaction = py_module_end_transaction;
3160 ops->del_transaction = py_module_del_transaction;
3162 ret = ldb_register_module(ops);
3164 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3166 Py_RETURN_NONE;
3169 static PyObject *py_timestring(PyObject *module, PyObject *args)
3171 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3172 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3173 long int t_val;
3174 char *tresult;
3175 PyObject *ret;
3176 if (!PyArg_ParseTuple(args, "l", &t_val))
3177 return NULL;
3178 tresult = ldb_timestring(NULL, (time_t) t_val);
3179 ret = PyString_FromString(tresult);
3180 talloc_free(tresult);
3181 return ret;
3184 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3186 char *str;
3187 if (!PyArg_ParseTuple(args, "s", &str))
3188 return NULL;
3190 return PyInt_FromLong(ldb_string_to_time(str));
3193 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3195 char *name;
3196 if (!PyArg_ParseTuple(args, "s", &name))
3197 return NULL;
3198 return PyBool_FromLong(ldb_valid_attr_name(name));
3202 encode a string using RFC2254 rules
3204 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3206 char *str, *encoded;
3207 int size = 0;
3208 struct ldb_val val;
3209 PyObject *ret;
3211 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3212 return NULL;
3213 val.data = (uint8_t *)str;
3214 val.length = size;
3216 encoded = ldb_binary_encode(NULL, val);
3217 if (encoded == NULL) {
3218 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3219 return NULL;
3221 ret = PyString_FromString(encoded);
3222 talloc_free(encoded);
3223 return ret;
3227 decode a string using RFC2254 rules
3229 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3231 char *str;
3232 struct ldb_val val;
3233 PyObject *ret;
3235 if (!PyArg_ParseTuple(args, "s", &str))
3236 return NULL;
3238 val = ldb_binary_decode(NULL, str);
3239 if (val.data == NULL) {
3240 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3241 return NULL;
3243 ret = Py_BuildValue("s#", val.data, val.length);
3244 talloc_free(val.data);
3245 return ret;
3248 static PyMethodDef py_ldb_global_methods[] = {
3249 { "register_module", py_register_module, METH_VARARGS,
3250 "S.register_module(module) -> None\n"
3251 "Register a LDB module."},
3252 { "timestring", py_timestring, METH_VARARGS,
3253 "S.timestring(int) -> string\n"
3254 "Generate a LDAP time string from a UNIX timestamp" },
3255 { "string_to_time", py_string_to_time, METH_VARARGS,
3256 "S.string_to_time(string) -> int\n"
3257 "Parse a LDAP time string into a UNIX timestamp." },
3258 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3259 "S.valid_attr_name(name) -> bool\n"
3260 "Check whether the supplied name is a valid attribute name." },
3261 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3262 NULL },
3263 { "binary_encode", py_binary_encode, METH_VARARGS,
3264 "S.binary_encode(string) -> string\n"
3265 "Perform a RFC2254 binary encoding on a string" },
3266 { "binary_decode", py_binary_decode, METH_VARARGS,
3267 "S.binary_decode(string) -> string\n"
3268 "Perform a RFC2254 binary decode on a string" },
3269 { NULL }
3272 void initldb(void)
3274 PyObject *m;
3276 if (PyType_Ready(&PyLdbDn) < 0)
3277 return;
3279 if (PyType_Ready(&PyLdbMessage) < 0)
3280 return;
3282 if (PyType_Ready(&PyLdbMessageElement) < 0)
3283 return;
3285 if (PyType_Ready(&PyLdb) < 0)
3286 return;
3288 if (PyType_Ready(&PyLdbModule) < 0)
3289 return;
3291 if (PyType_Ready(&PyLdbTree) < 0)
3292 return;
3294 if (PyType_Ready(&PyLdbResult) < 0)
3295 return;
3297 if (PyType_Ready(&PyLdbControl) < 0)
3298 return;
3300 m = Py_InitModule3("ldb", py_ldb_global_methods,
3301 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3302 if (m == NULL)
3303 return;
3305 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3306 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3307 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3308 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3309 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3310 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3311 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3313 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3314 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3315 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3316 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3318 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3319 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3320 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3322 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3323 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3324 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3325 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3326 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3327 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3328 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3329 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3330 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3331 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3332 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3333 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3334 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3335 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3336 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3337 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3338 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3339 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3340 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3341 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3342 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3343 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3344 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3345 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3346 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3347 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3348 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3349 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3350 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3351 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3352 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3353 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3354 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3355 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3356 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3357 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3358 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3359 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3360 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3362 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3363 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3364 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3365 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3367 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3369 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3370 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3372 Py_INCREF(&PyLdb);
3373 Py_INCREF(&PyLdbDn);
3374 Py_INCREF(&PyLdbModule);
3375 Py_INCREF(&PyLdbMessage);
3376 Py_INCREF(&PyLdbMessageElement);
3377 Py_INCREF(&PyLdbTree);
3378 Py_INCREF(&PyLdbResult);
3379 Py_INCREF(&PyLdbControl);
3381 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3382 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3383 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3384 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3385 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3386 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3387 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3389 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3391 #define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3393 ADD_LDB_STRING(SYNTAX_DN);
3394 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3395 ADD_LDB_STRING(SYNTAX_INTEGER);
3396 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3397 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3398 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3399 ADD_LDB_STRING(OID_COMPARATOR_AND);
3400 ADD_LDB_STRING(OID_COMPARATOR_OR);