s3:dbwrap fix return value of db_tdb_parse
[Samba/bb.git] / lib / ldb / pyldb.c
blobb2315e6751f70183e0e6abb7dc4f25079e8dd558
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,
2120 .tp_doc = "LDB module (extension)",
2125 * Create a ldb_message_element from a Python object.
2127 * This will accept any sequence objects that contains strings, or
2128 * a string object.
2130 * A reference to set_obj will be borrowed.
2132 * @param mem_ctx Memory context
2133 * @param set_obj Python object to convert
2134 * @param flags ldb_message_element flags to set
2135 * @param attr_name Name of the attribute
2136 * @return New ldb_message_element, allocated as child of mem_ctx
2138 static struct ldb_message_element *PyObject_AsMessageElement(
2139 TALLOC_CTX *mem_ctx,
2140 PyObject *set_obj,
2141 unsigned int flags,
2142 const char *attr_name)
2144 struct ldb_message_element *me;
2146 if (pyldb_MessageElement_Check(set_obj)) {
2147 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2148 /* We have to talloc_reference() the memory context, not the pointer
2149 * which may not actually be it's own context */
2150 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2151 return pyldb_MessageElement_AsMessageElement(set_obj);
2153 return NULL;
2156 me = talloc(mem_ctx, struct ldb_message_element);
2157 if (me == NULL) {
2158 PyErr_NoMemory();
2159 return NULL;
2162 me->name = talloc_strdup(me, attr_name);
2163 me->flags = flags;
2164 if (PyString_Check(set_obj)) {
2165 me->num_values = 1;
2166 me->values = talloc_array(me, struct ldb_val, me->num_values);
2167 me->values[0].length = PyString_Size(set_obj);
2168 me->values[0].data = talloc_memdup(me,
2169 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2170 } else if (PySequence_Check(set_obj)) {
2171 Py_ssize_t i;
2172 me->num_values = PySequence_Size(set_obj);
2173 me->values = talloc_array(me, struct ldb_val, me->num_values);
2174 for (i = 0; i < me->num_values; i++) {
2175 PyObject *obj = PySequence_GetItem(set_obj, i);
2176 if (!PyString_Check(obj)) {
2177 PyErr_Format(PyExc_TypeError,
2178 "Expected string as element %zd in list", i);
2179 talloc_free(me);
2180 return NULL;
2183 me->values[i].length = PyString_Size(obj);
2184 me->values[i].data = talloc_memdup(me,
2185 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2187 } else {
2188 talloc_free(me);
2189 me = NULL;
2192 return me;
2196 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2197 struct ldb_message_element *me)
2199 Py_ssize_t i;
2200 PyObject *result;
2202 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2203 result = PyList_New(me->num_values);
2205 for (i = 0; i < me->num_values; i++) {
2206 PyList_SetItem(result, i,
2207 PyObject_FromLdbValue(&me->values[i]));
2210 return result;
2213 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2215 unsigned int i;
2216 if (!PyArg_ParseTuple(args, "I", &i))
2217 return NULL;
2218 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2219 Py_RETURN_NONE;
2221 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2224 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2226 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2227 return PyInt_FromLong(el->flags);
2230 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2232 unsigned int flags;
2233 struct ldb_message_element *el;
2234 if (!PyArg_ParseTuple(args, "I", &flags))
2235 return NULL;
2237 el = pyldb_MessageElement_AsMessageElement(self);
2238 el->flags = flags;
2239 Py_RETURN_NONE;
2242 static PyMethodDef py_ldb_msg_element_methods[] = {
2243 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2244 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2245 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2246 { NULL },
2249 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2251 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2254 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2256 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2257 if (idx < 0 || idx >= el->num_values) {
2258 PyErr_SetString(PyExc_IndexError, "Out of range");
2259 return NULL;
2261 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2264 static PySequenceMethods py_ldb_msg_element_seq = {
2265 .sq_length = (lenfunc)py_ldb_msg_element_len,
2266 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2269 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2271 int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2272 pyldb_MessageElement_AsMessageElement(other));
2273 return SIGN(ret);
2276 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2278 PyObject *el = ldb_msg_element_to_set(NULL,
2279 pyldb_MessageElement_AsMessageElement(self));
2280 return PyObject_GetIter(el);
2283 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2285 PyLdbMessageElementObject *ret;
2286 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2287 if (ret == NULL) {
2288 PyErr_NoMemory();
2289 return NULL;
2291 ret->mem_ctx = talloc_new(NULL);
2292 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2293 PyErr_NoMemory();
2294 return NULL;
2296 ret->el = el;
2297 return (PyObject *)ret;
2300 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2302 PyObject *py_elements = NULL;
2303 struct ldb_message_element *el;
2304 unsigned int flags = 0;
2305 char *name = NULL;
2306 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2307 PyLdbMessageElementObject *ret;
2308 TALLOC_CTX *mem_ctx;
2310 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2311 discard_const_p(char *, kwnames),
2312 &py_elements, &flags, &name))
2313 return NULL;
2315 mem_ctx = talloc_new(NULL);
2316 if (mem_ctx == NULL) {
2317 PyErr_NoMemory();
2318 return NULL;
2321 el = talloc_zero(mem_ctx, struct ldb_message_element);
2322 if (el == NULL) {
2323 PyErr_NoMemory();
2324 talloc_free(mem_ctx);
2325 return NULL;
2328 if (py_elements != NULL) {
2329 Py_ssize_t i;
2330 if (PyString_Check(py_elements)) {
2331 el->num_values = 1;
2332 el->values = talloc_array(el, struct ldb_val, 1);
2333 if (el->values == NULL) {
2334 talloc_free(mem_ctx);
2335 PyErr_NoMemory();
2336 return NULL;
2338 el->values[0].length = PyString_Size(py_elements);
2339 el->values[0].data = talloc_memdup(el->values,
2340 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2341 } else if (PySequence_Check(py_elements)) {
2342 el->num_values = PySequence_Size(py_elements);
2343 el->values = talloc_array(el, struct ldb_val, el->num_values);
2344 if (el->values == NULL) {
2345 talloc_free(mem_ctx);
2346 PyErr_NoMemory();
2347 return NULL;
2349 for (i = 0; i < el->num_values; i++) {
2350 PyObject *item = PySequence_GetItem(py_elements, i);
2351 if (item == NULL) {
2352 talloc_free(mem_ctx);
2353 return NULL;
2355 if (!PyString_Check(item)) {
2356 PyErr_Format(PyExc_TypeError,
2357 "Expected string as element %zd in list", i);
2358 talloc_free(mem_ctx);
2359 return NULL;
2361 el->values[i].length = PyString_Size(item);
2362 el->values[i].data = talloc_memdup(el,
2363 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2365 } else {
2366 PyErr_SetString(PyExc_TypeError,
2367 "Expected string or list");
2368 talloc_free(mem_ctx);
2369 return NULL;
2373 el->flags = flags;
2374 el->name = talloc_strdup(el, name);
2376 ret = PyObject_New(PyLdbMessageElementObject, type);
2377 if (ret == NULL) {
2378 talloc_free(mem_ctx);
2379 return NULL;
2382 ret->mem_ctx = mem_ctx;
2383 ret->el = el;
2384 return (PyObject *)ret;
2387 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2389 char *element_str = NULL;
2390 Py_ssize_t i;
2391 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2392 PyObject *ret;
2394 for (i = 0; i < el->num_values; i++) {
2395 PyObject *o = py_ldb_msg_element_find(self, i);
2396 if (element_str == NULL)
2397 element_str = talloc_strdup(NULL, PyObject_REPR(o));
2398 else
2399 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2402 if (element_str != NULL) {
2403 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2404 talloc_free(element_str);
2405 } else {
2406 ret = PyString_FromString("MessageElement([])");
2409 return ret;
2412 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2414 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2416 if (el->num_values == 1)
2417 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2418 else
2419 Py_RETURN_NONE;
2422 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2424 talloc_free(self->mem_ctx);
2425 PyObject_Del(self);
2428 static PyTypeObject PyLdbMessageElement = {
2429 .tp_name = "ldb.MessageElement",
2430 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2431 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2432 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2433 .tp_str = (reprfunc)py_ldb_msg_element_str,
2434 .tp_methods = py_ldb_msg_element_methods,
2435 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2436 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2437 .tp_as_sequence = &py_ldb_msg_element_seq,
2438 .tp_new = py_ldb_msg_element_new,
2439 .tp_flags = Py_TPFLAGS_DEFAULT,
2440 .tp_doc = "An element of a Message",
2444 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2446 PyObject *py_ldb;
2447 PyObject *py_dict;
2448 PyObject *py_ret;
2449 struct ldb_message *msg;
2450 struct ldb_context *ldb_ctx;
2451 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2453 if (!PyArg_ParseTuple(args, "O!O!|I",
2454 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2455 &mod_flags)) {
2456 return NULL;
2459 /* mask only flags we are going to use */
2460 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2461 if (!mod_flags) {
2462 PyErr_SetString(PyExc_ValueError,
2463 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2464 " expected as mod_flag value");
2465 return NULL;
2468 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2470 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2471 if (!msg) {
2472 return NULL;
2475 py_ret = PyLdbMessage_FromMessage(msg);
2477 talloc_unlink(ldb_ctx, msg);
2479 return py_ret;
2482 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2484 char *name;
2485 if (!PyArg_ParseTuple(args, "s", &name))
2486 return NULL;
2488 ldb_msg_remove_attr(self->msg, name);
2490 Py_RETURN_NONE;
2493 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2495 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2496 Py_ssize_t i, j = 0;
2497 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2498 if (msg->dn != NULL) {
2499 PyList_SetItem(obj, j, PyString_FromString("dn"));
2500 j++;
2502 for (i = 0; i < msg->num_elements; i++) {
2503 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2504 j++;
2506 return obj;
2509 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2511 struct ldb_message_element *el;
2512 char *name;
2513 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2514 if (!PyString_Check(py_name)) {
2515 PyErr_SetNone(PyExc_TypeError);
2516 return NULL;
2518 name = PyString_AsString(py_name);
2519 if (!strcmp(name, "dn"))
2520 return pyldb_Dn_FromDn(msg->dn);
2521 el = ldb_msg_find_element(msg, name);
2522 if (el == NULL) {
2523 return NULL;
2525 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2528 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2530 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2531 if (ret == NULL) {
2532 PyErr_SetString(PyExc_KeyError, "No such element");
2533 return NULL;
2535 return ret;
2538 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2540 PyObject *def = NULL;
2541 const char *kwnames[] = { "name", "default", "idx", NULL };
2542 const char *name = NULL;
2543 int idx = -1;
2544 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2545 struct ldb_message_element *el;
2547 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2548 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2549 return NULL;
2552 if (strcasecmp(name, "dn") == 0) {
2553 return pyldb_Dn_FromDn(msg->dn);
2556 el = ldb_msg_find_element(msg, name);
2558 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2559 if (def != NULL) {
2560 return def;
2562 Py_RETURN_NONE;
2565 if (idx == -1) {
2566 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2569 return PyObject_FromLdbValue(&el->values[idx]);
2572 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2574 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2575 Py_ssize_t i, j = 0;
2576 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2577 if (msg->dn != NULL) {
2578 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2579 j++;
2581 for (i = 0; i < msg->num_elements; i++, j++) {
2582 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2583 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2584 PyList_SetItem(l, j, value);
2586 return l;
2589 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2591 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2592 Py_ssize_t i = 0;
2593 PyObject *l = PyList_New(msg->num_elements);
2594 for (i = 0; i < msg->num_elements; i++) {
2595 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2597 return l;
2600 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2602 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2603 PyLdbMessageElementObject *py_element;
2604 int ret;
2605 struct ldb_message_element *el;
2607 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2608 return NULL;
2610 el = talloc_reference(msg, py_element->el);
2611 if (el == NULL) {
2612 PyErr_NoMemory();
2613 return NULL;
2616 ret = ldb_msg_add(msg, el, el->flags);
2617 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2619 Py_RETURN_NONE;
2622 static PyMethodDef py_ldb_msg_methods[] = {
2623 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2624 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2625 "Class method to create ldb.Message object from Dictionary.\n"
2626 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2627 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2628 "S.keys() -> list\n\n"
2629 "Return sequence of all attribute names." },
2630 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2631 "S.remove(name)\n\n"
2632 "Remove all entries for attributes with the specified name."},
2633 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2634 "msg.get(name,default=None,idx=None) -> string\n"
2635 "idx is the index into the values array\n"
2636 "if idx is None, then a list is returned\n"
2637 "if idx is not None, then the element with that index is returned\n"
2638 "if you pass the special name 'dn' then the DN object is returned\n"},
2639 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2640 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2641 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2642 "S.append(element)\n\n"
2643 "Add an element to this message." },
2644 { NULL },
2647 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2649 PyObject *list, *iter;
2651 list = py_ldb_msg_keys(self);
2652 iter = PyObject_GetIter(list);
2653 Py_DECREF(list);
2654 return iter;
2657 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2659 char *attr_name;
2661 if (!PyString_Check(name)) {
2662 PyErr_SetNone(PyExc_TypeError);
2663 return -1;
2666 attr_name = PyString_AsString(name);
2667 if (value == NULL) {
2668 /* delitem */
2669 ldb_msg_remove_attr(self->msg, attr_name);
2670 } else {
2671 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2672 value, 0, attr_name);
2673 if (el == NULL)
2674 return -1;
2675 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2676 ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2678 return 0;
2681 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2683 return pyldb_Message_AsMessage(self)->num_elements;
2686 static PyMappingMethods py_ldb_msg_mapping = {
2687 .mp_length = (lenfunc)py_ldb_msg_length,
2688 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2689 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2692 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2694 const char * const kwnames[] = { "dn", NULL };
2695 struct ldb_message *ret;
2696 TALLOC_CTX *mem_ctx;
2697 PyObject *pydn = NULL;
2698 PyLdbMessageObject *py_ret;
2700 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2701 discard_const_p(char *, kwnames),
2702 &pydn))
2703 return NULL;
2705 mem_ctx = talloc_new(NULL);
2706 if (mem_ctx == NULL) {
2707 PyErr_NoMemory();
2708 return NULL;
2711 ret = ldb_msg_new(mem_ctx);
2712 if (ret == NULL) {
2713 talloc_free(mem_ctx);
2714 PyErr_NoMemory();
2715 return NULL;
2718 if (pydn != NULL) {
2719 struct ldb_dn *dn;
2720 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2721 talloc_free(mem_ctx);
2722 return NULL;
2724 ret->dn = talloc_reference(ret, dn);
2727 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2728 if (py_ret == NULL) {
2729 PyErr_NoMemory();
2730 talloc_free(mem_ctx);
2731 return NULL;
2734 py_ret->mem_ctx = mem_ctx;
2735 py_ret->msg = ret;
2736 return (PyObject *)py_ret;
2739 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2741 PyLdbMessageObject *ret;
2743 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2744 if (ret == NULL) {
2745 PyErr_NoMemory();
2746 return NULL;
2748 ret->mem_ctx = talloc_new(NULL);
2749 ret->msg = talloc_reference(ret->mem_ctx, msg);
2750 return (PyObject *)ret;
2753 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2755 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2756 return pyldb_Dn_FromDn(msg->dn);
2759 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2761 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2762 if (!pyldb_Dn_Check(value)) {
2763 PyErr_SetNone(PyExc_TypeError);
2764 return -1;
2767 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2768 return 0;
2771 static PyGetSetDef py_ldb_msg_getset[] = {
2772 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2773 { NULL }
2776 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2778 PyObject *dict = PyDict_New(), *ret;
2779 if (PyDict_Update(dict, (PyObject *)self) != 0)
2780 return NULL;
2781 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2782 Py_DECREF(dict);
2783 return ret;
2786 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2788 talloc_free(self->mem_ctx);
2789 PyObject_Del(self);
2792 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2793 PyLdbMessageObject *py_msg2)
2795 struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
2796 *msg2 = pyldb_Message_AsMessage(py_msg2);
2797 unsigned int i;
2798 int ret;
2800 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2801 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2802 if (ret != 0) {
2803 return SIGN(ret);
2807 ret = msg1->num_elements - msg2->num_elements;
2808 if (ret != 0) {
2809 return SIGN(ret);
2812 for (i = 0; i < msg1->num_elements; i++) {
2813 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2814 &msg2->elements[i]);
2815 if (ret != 0) {
2816 return SIGN(ret);
2819 ret = ldb_msg_element_compare(&msg1->elements[i],
2820 &msg2->elements[i]);
2821 if (ret != 0) {
2822 return SIGN(ret);
2826 return 0;
2829 static PyTypeObject PyLdbMessage = {
2830 .tp_name = "ldb.Message",
2831 .tp_methods = py_ldb_msg_methods,
2832 .tp_getset = py_ldb_msg_getset,
2833 .tp_as_mapping = &py_ldb_msg_mapping,
2834 .tp_basicsize = sizeof(PyLdbMessageObject),
2835 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2836 .tp_new = py_ldb_msg_new,
2837 .tp_repr = (reprfunc)py_ldb_msg_repr,
2838 .tp_flags = Py_TPFLAGS_DEFAULT,
2839 .tp_iter = (getiterfunc)py_ldb_msg_iter,
2840 .tp_compare = (cmpfunc)py_ldb_msg_compare,
2841 .tp_doc = "A LDB Message",
2844 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2846 PyLdbTreeObject *ret;
2848 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2849 if (ret == NULL) {
2850 PyErr_NoMemory();
2851 return NULL;
2854 ret->mem_ctx = talloc_new(NULL);
2855 ret->tree = talloc_reference(ret->mem_ctx, tree);
2856 return (PyObject *)ret;
2859 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2861 talloc_free(self->mem_ctx);
2862 PyObject_Del(self);
2865 static PyTypeObject PyLdbTree = {
2866 .tp_name = "ldb.Tree",
2867 .tp_basicsize = sizeof(PyLdbTreeObject),
2868 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2869 .tp_flags = Py_TPFLAGS_DEFAULT,
2870 .tp_doc = "A search tree",
2873 /* Ldb_module */
2874 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2876 PyObject *py_ldb = (PyObject *)mod->private_data;
2877 PyObject *py_result, *py_base, *py_attrs, *py_tree;
2879 py_base = pyldb_Dn_FromDn(req->op.search.base);
2881 if (py_base == NULL)
2882 return LDB_ERR_OPERATIONS_ERROR;
2884 py_tree = PyLdbTree_FromTree(req->op.search.tree);
2886 if (py_tree == NULL)
2887 return LDB_ERR_OPERATIONS_ERROR;
2889 if (req->op.search.attrs == NULL) {
2890 py_attrs = Py_None;
2891 } else {
2892 int i, len;
2893 for (len = 0; req->op.search.attrs[len]; len++);
2894 py_attrs = PyList_New(len);
2895 for (i = 0; i < len; i++)
2896 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2899 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2900 discard_const_p(char, "OiOO"),
2901 py_base, req->op.search.scope, py_tree, py_attrs);
2903 Py_DECREF(py_attrs);
2904 Py_DECREF(py_tree);
2905 Py_DECREF(py_base);
2907 if (py_result == NULL) {
2908 return LDB_ERR_PYTHON_EXCEPTION;
2911 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2912 if (req->op.search.res == NULL) {
2913 return LDB_ERR_PYTHON_EXCEPTION;
2916 Py_DECREF(py_result);
2918 return LDB_SUCCESS;
2921 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2923 PyObject *py_ldb = (PyObject *)mod->private_data;
2924 PyObject *py_result, *py_msg;
2926 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2928 if (py_msg == NULL) {
2929 return LDB_ERR_OPERATIONS_ERROR;
2932 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2933 discard_const_p(char, "O"),
2934 py_msg);
2936 Py_DECREF(py_msg);
2938 if (py_result == NULL) {
2939 return LDB_ERR_PYTHON_EXCEPTION;
2942 Py_DECREF(py_result);
2944 return LDB_SUCCESS;
2947 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
2949 PyObject *py_ldb = (PyObject *)mod->private_data;
2950 PyObject *py_result, *py_msg;
2952 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
2954 if (py_msg == NULL) {
2955 return LDB_ERR_OPERATIONS_ERROR;
2958 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
2959 discard_const_p(char, "O"),
2960 py_msg);
2962 Py_DECREF(py_msg);
2964 if (py_result == NULL) {
2965 return LDB_ERR_PYTHON_EXCEPTION;
2968 Py_DECREF(py_result);
2970 return LDB_SUCCESS;
2973 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
2975 PyObject *py_ldb = (PyObject *)mod->private_data;
2976 PyObject *py_result, *py_dn;
2978 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
2980 if (py_dn == NULL)
2981 return LDB_ERR_OPERATIONS_ERROR;
2983 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
2984 discard_const_p(char, "O"),
2985 py_dn);
2987 if (py_result == NULL) {
2988 return LDB_ERR_PYTHON_EXCEPTION;
2991 Py_DECREF(py_result);
2993 return LDB_SUCCESS;
2996 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
2998 PyObject *py_ldb = (PyObject *)mod->private_data;
2999 PyObject *py_result, *py_olddn, *py_newdn;
3001 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3003 if (py_olddn == NULL)
3004 return LDB_ERR_OPERATIONS_ERROR;
3006 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3008 if (py_newdn == NULL)
3009 return LDB_ERR_OPERATIONS_ERROR;
3011 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3012 discard_const_p(char, "OO"),
3013 py_olddn, py_newdn);
3015 Py_DECREF(py_olddn);
3016 Py_DECREF(py_newdn);
3018 if (py_result == NULL) {
3019 return LDB_ERR_PYTHON_EXCEPTION;
3022 Py_DECREF(py_result);
3024 return LDB_SUCCESS;
3027 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3029 PyObject *py_ldb = (PyObject *)mod->private_data;
3030 PyObject *py_result;
3032 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3033 discard_const_p(char, ""));
3035 return LDB_ERR_OPERATIONS_ERROR;
3038 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3040 PyObject *py_ldb = (PyObject *)mod->private_data;
3041 PyObject *py_result;
3043 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3044 discard_const_p(char, ""));
3046 return LDB_ERR_OPERATIONS_ERROR;
3049 static int py_module_start_transaction(struct ldb_module *mod)
3051 PyObject *py_ldb = (PyObject *)mod->private_data;
3052 PyObject *py_result;
3054 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3055 discard_const_p(char, ""));
3057 if (py_result == NULL) {
3058 return LDB_ERR_PYTHON_EXCEPTION;
3061 Py_DECREF(py_result);
3063 return LDB_SUCCESS;
3066 static int py_module_end_transaction(struct ldb_module *mod)
3068 PyObject *py_ldb = (PyObject *)mod->private_data;
3069 PyObject *py_result;
3071 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3072 discard_const_p(char, ""));
3074 if (py_result == NULL) {
3075 return LDB_ERR_PYTHON_EXCEPTION;
3078 Py_DECREF(py_result);
3080 return LDB_SUCCESS;
3083 static int py_module_del_transaction(struct ldb_module *mod)
3085 PyObject *py_ldb = (PyObject *)mod->private_data;
3086 PyObject *py_result;
3088 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3089 discard_const_p(char, ""));
3091 if (py_result == NULL) {
3092 return LDB_ERR_PYTHON_EXCEPTION;
3095 Py_DECREF(py_result);
3097 return LDB_SUCCESS;
3100 static int py_module_destructor(struct ldb_module *mod)
3102 Py_DECREF((PyObject *)mod->private_data);
3103 return 0;
3106 static int py_module_init(struct ldb_module *mod)
3108 PyObject *py_class = (PyObject *)mod->ops->private_data;
3109 PyObject *py_result, *py_next, *py_ldb;
3111 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3113 if (py_ldb == NULL)
3114 return LDB_ERR_OPERATIONS_ERROR;
3116 py_next = PyLdbModule_FromModule(mod->next);
3118 if (py_next == NULL)
3119 return LDB_ERR_OPERATIONS_ERROR;
3121 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3122 py_ldb, py_next);
3124 if (py_result == NULL) {
3125 return LDB_ERR_PYTHON_EXCEPTION;
3128 mod->private_data = py_result;
3130 talloc_set_destructor(mod, py_module_destructor);
3132 return ldb_next_init(mod);
3135 static PyObject *py_register_module(PyObject *module, PyObject *args)
3137 int ret;
3138 struct ldb_module_ops *ops;
3139 PyObject *input;
3141 if (!PyArg_ParseTuple(args, "O", &input))
3142 return NULL;
3144 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3145 if (ops == NULL) {
3146 PyErr_NoMemory();
3147 return NULL;
3150 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3152 Py_INCREF(input);
3153 ops->private_data = input;
3154 ops->init_context = py_module_init;
3155 ops->search = py_module_search;
3156 ops->add = py_module_add;
3157 ops->modify = py_module_modify;
3158 ops->del = py_module_del;
3159 ops->rename = py_module_rename;
3160 ops->request = py_module_request;
3161 ops->extended = py_module_extended;
3162 ops->start_transaction = py_module_start_transaction;
3163 ops->end_transaction = py_module_end_transaction;
3164 ops->del_transaction = py_module_del_transaction;
3166 ret = ldb_register_module(ops);
3168 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3170 Py_RETURN_NONE;
3173 static PyObject *py_timestring(PyObject *module, PyObject *args)
3175 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3176 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3177 long int t_val;
3178 char *tresult;
3179 PyObject *ret;
3180 if (!PyArg_ParseTuple(args, "l", &t_val))
3181 return NULL;
3182 tresult = ldb_timestring(NULL, (time_t) t_val);
3183 ret = PyString_FromString(tresult);
3184 talloc_free(tresult);
3185 return ret;
3188 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3190 char *str;
3191 if (!PyArg_ParseTuple(args, "s", &str))
3192 return NULL;
3194 return PyInt_FromLong(ldb_string_to_time(str));
3197 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3199 char *name;
3200 if (!PyArg_ParseTuple(args, "s", &name))
3201 return NULL;
3202 return PyBool_FromLong(ldb_valid_attr_name(name));
3206 encode a string using RFC2254 rules
3208 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3210 char *str, *encoded;
3211 int size = 0;
3212 struct ldb_val val;
3213 PyObject *ret;
3215 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3216 return NULL;
3217 val.data = (uint8_t *)str;
3218 val.length = size;
3220 encoded = ldb_binary_encode(NULL, val);
3221 if (encoded == NULL) {
3222 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3223 return NULL;
3225 ret = PyString_FromString(encoded);
3226 talloc_free(encoded);
3227 return ret;
3231 decode a string using RFC2254 rules
3233 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3235 char *str;
3236 struct ldb_val val;
3237 PyObject *ret;
3239 if (!PyArg_ParseTuple(args, "s", &str))
3240 return NULL;
3242 val = ldb_binary_decode(NULL, str);
3243 if (val.data == NULL) {
3244 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3245 return NULL;
3247 ret = Py_BuildValue("s#", val.data, val.length);
3248 talloc_free(val.data);
3249 return ret;
3252 static PyMethodDef py_ldb_global_methods[] = {
3253 { "register_module", py_register_module, METH_VARARGS,
3254 "S.register_module(module) -> None\n\n"
3255 "Register a LDB module."},
3256 { "timestring", py_timestring, METH_VARARGS,
3257 "S.timestring(int) -> string\n\n"
3258 "Generate a LDAP time string from a UNIX timestamp" },
3259 { "string_to_time", py_string_to_time, METH_VARARGS,
3260 "S.string_to_time(string) -> int\n\n"
3261 "Parse a LDAP time string into a UNIX timestamp." },
3262 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3263 "S.valid_attr_name(name) -> bool\n\nn"
3264 "Check whether the supplied name is a valid attribute name." },
3265 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3266 "S.open() -> Ldb\n\n"
3267 "Open a new LDB context." },
3268 { "binary_encode", py_binary_encode, METH_VARARGS,
3269 "S.binary_encode(string) -> string\n\n"
3270 "Perform a RFC2254 binary encoding on a string" },
3271 { "binary_decode", py_binary_decode, METH_VARARGS,
3272 "S.binary_decode(string) -> string\n\n"
3273 "Perform a RFC2254 binary decode on a string" },
3274 { NULL }
3277 void initldb(void)
3279 PyObject *m;
3281 if (PyType_Ready(&PyLdbDn) < 0)
3282 return;
3284 if (PyType_Ready(&PyLdbMessage) < 0)
3285 return;
3287 if (PyType_Ready(&PyLdbMessageElement) < 0)
3288 return;
3290 if (PyType_Ready(&PyLdb) < 0)
3291 return;
3293 if (PyType_Ready(&PyLdbModule) < 0)
3294 return;
3296 if (PyType_Ready(&PyLdbTree) < 0)
3297 return;
3299 if (PyType_Ready(&PyLdbResult) < 0)
3300 return;
3302 if (PyType_Ready(&PyLdbControl) < 0)
3303 return;
3305 m = Py_InitModule3("ldb", py_ldb_global_methods,
3306 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3307 if (m == NULL)
3308 return;
3310 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3311 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3312 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3313 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3314 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3315 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3316 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3318 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3319 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3320 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3321 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3323 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3324 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3325 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3327 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3328 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3329 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3330 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3331 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3332 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3333 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3334 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3335 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3336 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3337 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3338 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3339 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3340 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3341 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3342 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3343 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3344 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3345 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3346 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3347 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3348 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3349 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3350 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3351 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3352 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3353 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3354 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3355 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3356 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3357 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3358 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3359 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3360 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3361 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3362 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3363 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3364 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3365 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3367 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3368 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3369 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3370 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3372 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3374 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3375 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3377 Py_INCREF(&PyLdb);
3378 Py_INCREF(&PyLdbDn);
3379 Py_INCREF(&PyLdbModule);
3380 Py_INCREF(&PyLdbMessage);
3381 Py_INCREF(&PyLdbMessageElement);
3382 Py_INCREF(&PyLdbTree);
3383 Py_INCREF(&PyLdbResult);
3384 Py_INCREF(&PyLdbControl);
3386 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3387 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3388 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3389 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3390 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3391 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3392 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3394 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3396 #define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3398 ADD_LDB_STRING(SYNTAX_DN);
3399 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3400 ADD_LDB_STRING(SYNTAX_INTEGER);
3401 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3402 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3403 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3404 ADD_LDB_STRING(OID_COMPARATOR_AND);
3405 ADD_LDB_STRING(OID_COMPARATOR_OR);