wintest: add option to select the dns backend
[Samba/gebeck_regimport.git] / lib / ldb / pyldb.c
blob4554886e8da0a9eccdf6e436c5b80502e9359395
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 if (!PyLdb_Check(py_ldb)) {
657 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
658 return NULL;
661 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
663 mem_ctx = talloc_new(NULL);
664 if (mem_ctx == NULL) {
665 PyErr_NoMemory();
666 return NULL;
669 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
670 if (!ldb_dn_validate(ret)) {
671 talloc_free(mem_ctx);
672 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
673 return NULL;
676 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
677 if (ret == NULL) {
678 talloc_free(mem_ctx);
679 PyErr_NoMemory();
680 return NULL;
682 py_ret->mem_ctx = mem_ctx;
683 py_ret->dn = ret;
684 return (PyObject *)py_ret;
687 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
689 talloc_free(self->mem_ctx);
690 PyObject_Del(self);
693 static PyTypeObject PyLdbDn = {
694 .tp_name = "ldb.Dn",
695 .tp_methods = py_ldb_dn_methods,
696 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
697 .tp_repr = (reprfunc)py_ldb_dn_repr,
698 .tp_compare = (cmpfunc)py_ldb_dn_compare,
699 .tp_as_sequence = &py_ldb_dn_seq,
700 .tp_doc = "A LDB distinguished name.",
701 .tp_new = py_ldb_dn_new,
702 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
703 .tp_basicsize = sizeof(PyLdbDnObject),
704 .tp_flags = Py_TPFLAGS_DEFAULT,
707 /* Debug */
708 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
709 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
711 PyObject *fn = (PyObject *)context;
712 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
715 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
717 PyObject *cb;
718 struct ldb_context *ldb_ctx;
720 if (!PyArg_ParseTuple(args, "O", &cb))
721 return NULL;
723 Py_INCREF(cb);
724 /* FIXME: Where do we DECREF cb ? */
725 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
726 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
727 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
728 ldb_ctx);
730 Py_RETURN_NONE;
733 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
735 unsigned int perms;
736 if (!PyArg_ParseTuple(args, "I", &perms))
737 return NULL;
739 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
741 Py_RETURN_NONE;
744 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
746 char *modules_dir;
747 if (!PyArg_ParseTuple(args, "s", &modules_dir))
748 return NULL;
750 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
752 Py_RETURN_NONE;
755 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
757 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
758 int ldb_err;
759 ldb_err = ldb_transaction_start(ldb_ctx);
760 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
761 Py_RETURN_NONE;
764 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
766 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
767 int ldb_err;
768 ldb_err = ldb_transaction_commit(ldb_ctx);
769 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
770 Py_RETURN_NONE;
773 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
775 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
776 int ldb_err;
777 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
778 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
779 Py_RETURN_NONE;
782 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
784 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
785 int ldb_err;
786 ldb_err = ldb_transaction_cancel(ldb_ctx);
787 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
788 Py_RETURN_NONE;
791 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
793 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
794 int ldb_err;
795 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
796 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
797 Py_RETURN_NONE;
800 static PyObject *py_ldb_repr(PyLdbObject *self)
802 return PyString_FromFormat("<ldb connection>");
805 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
807 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
808 if (dn == NULL)
809 Py_RETURN_NONE;
810 return py_ldb_dn_copy(dn);
814 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
816 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
817 if (dn == NULL)
818 Py_RETURN_NONE;
819 return py_ldb_dn_copy(dn);
822 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
824 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
825 if (dn == NULL)
826 Py_RETURN_NONE;
827 return py_ldb_dn_copy(dn);
830 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
832 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
833 if (dn == NULL)
834 Py_RETURN_NONE;
835 return py_ldb_dn_copy(dn);
838 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
839 const char *paramname)
841 const char **ret;
842 Py_ssize_t i;
843 if (!PyList_Check(list)) {
844 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
845 return NULL;
847 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
848 if (ret == NULL) {
849 PyErr_NoMemory();
850 return NULL;
853 for (i = 0; i < PyList_Size(list); i++) {
854 PyObject *item = PyList_GetItem(list, i);
855 if (!PyString_Check(item)) {
856 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
857 return NULL;
859 ret[i] = talloc_strndup(ret, PyString_AsString(item),
860 PyString_Size(item));
862 ret[i] = NULL;
863 return ret;
866 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
868 const char * const kwnames[] = { "url", "flags", "options", NULL };
869 char *url = NULL;
870 PyObject *py_options = Py_None;
871 const char **options;
872 unsigned int flags = 0;
873 int ret;
874 struct ldb_context *ldb;
876 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
877 discard_const_p(char *, kwnames),
878 &url, &flags, &py_options))
879 return -1;
881 ldb = pyldb_Ldb_AsLdbContext(self);
883 if (py_options == Py_None) {
884 options = NULL;
885 } else {
886 options = PyList_AsStringList(ldb, py_options, "options");
887 if (options == NULL)
888 return -1;
891 if (url != NULL) {
892 ret = ldb_connect(ldb, url, flags, options);
893 if (ret != LDB_SUCCESS) {
894 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
895 return -1;
899 talloc_free(options);
900 return 0;
903 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
905 PyLdbObject *ret;
906 struct ldb_context *ldb;
907 ret = (PyLdbObject *)type->tp_alloc(type, 0);
908 if (ret == NULL) {
909 PyErr_NoMemory();
910 return NULL;
912 ret->mem_ctx = talloc_new(NULL);
913 ldb = ldb_init(ret->mem_ctx, NULL);
915 if (ldb == NULL) {
916 PyErr_NoMemory();
917 return NULL;
920 ret->ldb_ctx = ldb;
921 return (PyObject *)ret;
924 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
926 char *url;
927 unsigned int flags = 0;
928 PyObject *py_options = Py_None;
929 int ret;
930 const char **options;
931 const char * const kwnames[] = { "url", "flags", "options", NULL };
932 struct ldb_context *ldb_ctx;
934 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
935 discard_const_p(char *, kwnames),
936 &url, &flags, &py_options))
937 return NULL;
939 if (py_options == Py_None) {
940 options = NULL;
941 } else {
942 options = PyList_AsStringList(NULL, py_options, "options");
943 if (options == NULL)
944 return NULL;
947 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
948 ret = ldb_connect(ldb_ctx, url, flags, options);
949 talloc_free(options);
951 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
953 Py_RETURN_NONE;
956 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
958 PyObject *py_msg;
959 PyObject *py_controls = Py_None;
960 struct ldb_context *ldb_ctx;
961 struct ldb_request *req;
962 struct ldb_control **parsed_controls;
963 struct ldb_message *msg;
964 int ret;
965 TALLOC_CTX *mem_ctx;
966 bool validate=true;
967 const char * const kwnames[] = { "message", "controls", "validate", NULL };
969 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
970 discard_const_p(char *, kwnames),
971 &py_msg, &py_controls, &validate))
972 return NULL;
974 mem_ctx = talloc_new(NULL);
975 if (mem_ctx == NULL) {
976 PyErr_NoMemory();
977 return NULL;
979 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
981 if (py_controls == Py_None) {
982 parsed_controls = NULL;
983 } else {
984 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
985 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
986 talloc_free(controls);
989 if (!PyLdbMessage_Check(py_msg)) {
990 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
991 talloc_free(mem_ctx);
992 return NULL;
994 msg = pyldb_Message_AsMessage(py_msg);
996 if (validate) {
997 ret = ldb_msg_sanity_check(ldb_ctx, msg);
998 if (ret != LDB_SUCCESS) {
999 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1000 talloc_free(mem_ctx);
1001 return NULL;
1005 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1006 NULL, ldb_op_default_callback, NULL);
1007 if (ret != LDB_SUCCESS) {
1008 PyErr_SetString(PyExc_TypeError, "failed to build request");
1009 talloc_free(mem_ctx);
1010 return NULL;
1013 /* do request and autostart a transaction */
1014 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1016 ret = ldb_transaction_start(ldb_ctx);
1017 if (ret != LDB_SUCCESS) {
1018 talloc_free(mem_ctx);
1019 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1020 return NULL;
1023 ret = ldb_request(ldb_ctx, req);
1024 if (ret == LDB_SUCCESS) {
1025 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1028 if (ret == LDB_SUCCESS) {
1029 ret = ldb_transaction_commit(ldb_ctx);
1030 } else {
1031 ldb_transaction_cancel(ldb_ctx);
1034 talloc_free(mem_ctx);
1035 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1037 Py_RETURN_NONE;
1042 * Obtain a ldb message from a Python Dictionary object.
1044 * @param mem_ctx Memory context
1045 * @param py_obj Python Dictionary object
1046 * @param ldb_ctx LDB context
1047 * @param mod_flags Flags to be set on every message element
1048 * @return ldb_message on success or NULL on failure
1050 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1051 PyObject *py_obj,
1052 struct ldb_context *ldb_ctx,
1053 unsigned int mod_flags)
1055 struct ldb_message *msg;
1056 unsigned int msg_pos = 0;
1057 Py_ssize_t dict_pos = 0;
1058 PyObject *key, *value;
1059 struct ldb_message_element *msg_el;
1060 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1062 msg = ldb_msg_new(mem_ctx);
1063 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1065 if (dn_value) {
1066 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1067 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1068 return NULL;
1070 if (msg->dn == NULL) {
1071 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1072 return NULL;
1074 } else {
1075 PyErr_SetString(PyExc_TypeError, "no dn set");
1076 return NULL;
1079 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1080 char *key_str = PyString_AsString(key);
1081 if (ldb_attr_cmp(key_str, "dn") != 0) {
1082 msg_el = PyObject_AsMessageElement(msg->elements, value,
1083 mod_flags, key_str);
1084 if (msg_el == NULL) {
1085 PyErr_SetString(PyExc_TypeError, "unable to import element");
1086 return NULL;
1088 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1089 msg_pos++;
1093 msg->num_elements = msg_pos;
1095 return msg;
1098 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1100 PyObject *py_obj;
1101 int ret;
1102 struct ldb_context *ldb_ctx;
1103 struct ldb_request *req;
1104 struct ldb_message *msg = NULL;
1105 PyObject *py_controls = Py_None;
1106 TALLOC_CTX *mem_ctx;
1107 struct ldb_control **parsed_controls;
1108 const char * const kwnames[] = { "message", "controls", NULL };
1110 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1111 discard_const_p(char *, kwnames),
1112 &py_obj, &py_controls))
1113 return NULL;
1115 mem_ctx = talloc_new(NULL);
1116 if (mem_ctx == NULL) {
1117 PyErr_NoMemory();
1118 return NULL;
1120 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1122 if (py_controls == Py_None) {
1123 parsed_controls = NULL;
1124 } else {
1125 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1126 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1127 talloc_free(controls);
1130 if (PyLdbMessage_Check(py_obj)) {
1131 msg = pyldb_Message_AsMessage(py_obj);
1132 } else if (PyDict_Check(py_obj)) {
1133 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1134 } else {
1135 PyErr_SetString(PyExc_TypeError,
1136 "Dictionary or LdbMessage object expected!");
1139 if (!msg) {
1140 /* we should have a PyErr already set */
1141 talloc_free(mem_ctx);
1142 return NULL;
1145 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1146 if (ret != LDB_SUCCESS) {
1147 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1148 talloc_free(mem_ctx);
1149 return NULL;
1152 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1153 NULL, ldb_op_default_callback, NULL);
1154 if (ret != LDB_SUCCESS) {
1155 PyErr_SetString(PyExc_TypeError, "failed to build request");
1156 talloc_free(mem_ctx);
1157 return NULL;
1160 /* do request and autostart a transaction */
1161 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1163 ret = ldb_transaction_start(ldb_ctx);
1164 if (ret != LDB_SUCCESS) {
1165 talloc_free(mem_ctx);
1166 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1167 return NULL;
1170 ret = ldb_request(ldb_ctx, req);
1171 if (ret == LDB_SUCCESS) {
1172 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1175 if (ret == LDB_SUCCESS) {
1176 ret = ldb_transaction_commit(ldb_ctx);
1177 } else {
1178 ldb_transaction_cancel(ldb_ctx);
1181 talloc_free(mem_ctx);
1182 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1184 Py_RETURN_NONE;
1187 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1189 PyObject *py_dn;
1190 struct ldb_dn *dn;
1191 int ret;
1192 struct ldb_context *ldb_ctx;
1193 struct ldb_request *req;
1194 PyObject *py_controls = Py_None;
1195 TALLOC_CTX *mem_ctx;
1196 struct ldb_control **parsed_controls;
1197 const char * const kwnames[] = { "dn", "controls", NULL };
1199 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1200 discard_const_p(char *, kwnames),
1201 &py_dn, &py_controls))
1202 return NULL;
1204 mem_ctx = talloc_new(NULL);
1205 if (mem_ctx == NULL) {
1206 PyErr_NoMemory();
1207 return NULL;
1209 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1211 if (py_controls == Py_None) {
1212 parsed_controls = NULL;
1213 } else {
1214 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1215 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1216 talloc_free(controls);
1219 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1220 talloc_free(mem_ctx);
1221 return NULL;
1224 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1225 NULL, ldb_op_default_callback, NULL);
1226 if (ret != LDB_SUCCESS) {
1227 PyErr_SetString(PyExc_TypeError, "failed to build request");
1228 talloc_free(mem_ctx);
1229 return NULL;
1232 /* do request and autostart a transaction */
1233 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1235 ret = ldb_transaction_start(ldb_ctx);
1236 if (ret != LDB_SUCCESS) {
1237 talloc_free(mem_ctx);
1238 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1239 return NULL;
1242 ret = ldb_request(ldb_ctx, req);
1243 if (ret == LDB_SUCCESS) {
1244 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1247 if (ret == LDB_SUCCESS) {
1248 ret = ldb_transaction_commit(ldb_ctx);
1249 } else {
1250 ldb_transaction_cancel(ldb_ctx);
1253 talloc_free(mem_ctx);
1254 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1256 Py_RETURN_NONE;
1259 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1261 PyObject *py_dn1, *py_dn2;
1262 struct ldb_dn *dn1, *dn2;
1263 int ret;
1264 TALLOC_CTX *mem_ctx;
1265 PyObject *py_controls = Py_None;
1266 struct ldb_control **parsed_controls;
1267 struct ldb_context *ldb_ctx;
1268 struct ldb_request *req;
1269 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1271 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1273 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1274 discard_const_p(char *, kwnames),
1275 &py_dn1, &py_dn2, &py_controls))
1276 return NULL;
1279 mem_ctx = talloc_new(NULL);
1280 if (mem_ctx == NULL) {
1281 PyErr_NoMemory();
1282 return NULL;
1285 if (py_controls == Py_None) {
1286 parsed_controls = NULL;
1287 } else {
1288 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1289 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1290 talloc_free(controls);
1294 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1295 talloc_free(mem_ctx);
1296 return NULL;
1299 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1300 talloc_free(mem_ctx);
1301 return NULL;
1304 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1305 NULL, ldb_op_default_callback, NULL);
1306 if (ret != LDB_SUCCESS) {
1307 PyErr_SetString(PyExc_TypeError, "failed to build request");
1308 talloc_free(mem_ctx);
1309 return NULL;
1312 /* do request and autostart a transaction */
1313 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1315 ret = ldb_transaction_start(ldb_ctx);
1316 if (ret != LDB_SUCCESS) {
1317 talloc_free(mem_ctx);
1318 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1319 return NULL;
1322 ret = ldb_request(ldb_ctx, req);
1323 if (ret == LDB_SUCCESS) {
1324 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1327 if (ret == LDB_SUCCESS) {
1328 ret = ldb_transaction_commit(ldb_ctx);
1329 } else {
1330 ldb_transaction_cancel(ldb_ctx);
1333 talloc_free(mem_ctx);
1334 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1336 Py_RETURN_NONE;
1339 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1341 char *name;
1342 if (!PyArg_ParseTuple(args, "s", &name))
1343 return NULL;
1345 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1347 Py_RETURN_NONE;
1350 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1352 char *attribute, *syntax;
1353 unsigned int flags;
1354 int ret;
1355 struct ldb_context *ldb_ctx;
1357 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1358 return NULL;
1360 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1361 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1363 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1365 Py_RETURN_NONE;
1368 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1370 if (ldif == NULL) {
1371 Py_RETURN_NONE;
1372 } else {
1373 /* We don't want this attached to the 'ldb' any more */
1374 return Py_BuildValue(discard_const_p(char, "(iO)"),
1375 ldif->changetype,
1376 PyLdbMessage_FromMessage(ldif->msg));
1381 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1383 int changetype;
1384 PyObject *py_msg;
1385 struct ldb_ldif ldif;
1386 PyObject *ret;
1387 char *string;
1388 TALLOC_CTX *mem_ctx;
1390 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1391 return NULL;
1393 if (!PyLdbMessage_Check(py_msg)) {
1394 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1395 return NULL;
1398 ldif.msg = pyldb_Message_AsMessage(py_msg);
1399 ldif.changetype = changetype;
1401 mem_ctx = talloc_new(NULL);
1403 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1404 if (!string) {
1405 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1406 return NULL;
1409 ret = PyString_FromString(string);
1411 talloc_free(mem_ctx);
1413 return ret;
1416 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1418 PyObject *list;
1419 struct ldb_ldif *ldif;
1420 const char *s;
1422 TALLOC_CTX *mem_ctx;
1424 if (!PyArg_ParseTuple(args, "s", &s))
1425 return NULL;
1427 mem_ctx = talloc_new(NULL);
1428 if (!mem_ctx) {
1429 Py_RETURN_NONE;
1432 list = PyList_New(0);
1433 while (s && *s != '\0') {
1434 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1435 talloc_steal(mem_ctx, ldif);
1436 if (ldif) {
1437 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1438 } else {
1439 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1440 talloc_free(mem_ctx);
1441 return NULL;
1444 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1445 return PyObject_GetIter(list);
1448 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1450 int ldb_ret;
1451 PyObject *py_msg_old;
1452 PyObject *py_msg_new;
1453 struct ldb_message *diff;
1454 struct ldb_context *ldb;
1455 PyObject *py_ret;
1457 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1458 return NULL;
1460 if (!PyLdbMessage_Check(py_msg_old)) {
1461 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1462 return NULL;
1465 if (!PyLdbMessage_Check(py_msg_new)) {
1466 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1467 return NULL;
1470 ldb = pyldb_Ldb_AsLdbContext(self);
1471 ldb_ret = ldb_msg_difference(ldb, ldb,
1472 pyldb_Message_AsMessage(py_msg_old),
1473 pyldb_Message_AsMessage(py_msg_new),
1474 &diff);
1475 if (ldb_ret != LDB_SUCCESS) {
1476 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1477 return NULL;
1480 py_ret = PyLdbMessage_FromMessage(diff);
1482 talloc_unlink(ldb, diff);
1484 return py_ret;
1487 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1489 const struct ldb_schema_attribute *a;
1490 struct ldb_val old_val;
1491 struct ldb_val new_val;
1492 TALLOC_CTX *mem_ctx;
1493 PyObject *ret;
1494 char *element_name;
1495 PyObject *val;
1497 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1498 return NULL;
1500 mem_ctx = talloc_new(NULL);
1502 old_val.data = (uint8_t *)PyString_AsString(val);
1503 old_val.length = PyString_Size(val);
1505 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1507 if (a == NULL) {
1508 Py_RETURN_NONE;
1511 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1512 talloc_free(mem_ctx);
1513 Py_RETURN_NONE;
1516 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1518 talloc_free(mem_ctx);
1520 return ret;
1523 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1525 PyObject *py_base = Py_None;
1526 int scope = LDB_SCOPE_DEFAULT;
1527 char *expr = NULL;
1528 PyObject *py_attrs = Py_None;
1529 PyObject *py_controls = Py_None;
1530 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1531 int ret;
1532 struct ldb_result *res;
1533 struct ldb_request *req;
1534 const char **attrs;
1535 struct ldb_context *ldb_ctx;
1536 struct ldb_control **parsed_controls;
1537 struct ldb_dn *base;
1538 PyObject *py_ret;
1539 TALLOC_CTX *mem_ctx;
1541 /* type "int" rather than "enum" for "scope" is intentional */
1542 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1543 discard_const_p(char *, kwnames),
1544 &py_base, &scope, &expr, &py_attrs, &py_controls))
1545 return NULL;
1548 mem_ctx = talloc_new(NULL);
1549 if (mem_ctx == NULL) {
1550 PyErr_NoMemory();
1551 return NULL;
1553 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1555 if (py_attrs == Py_None) {
1556 attrs = NULL;
1557 } else {
1558 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1559 if (attrs == NULL) {
1560 talloc_free(mem_ctx);
1561 return NULL;
1565 if (py_base == Py_None) {
1566 base = ldb_get_default_basedn(ldb_ctx);
1567 } else {
1568 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1569 talloc_free(attrs);
1570 return NULL;
1574 if (py_controls == Py_None) {
1575 parsed_controls = NULL;
1576 } else {
1577 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1578 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1579 talloc_free(controls);
1582 res = talloc_zero(mem_ctx, struct ldb_result);
1583 if (res == NULL) {
1584 PyErr_NoMemory();
1585 talloc_free(mem_ctx);
1586 return NULL;
1589 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1590 base,
1591 scope,
1592 expr,
1593 attrs,
1594 parsed_controls,
1595 res,
1596 ldb_search_default_callback,
1597 NULL);
1599 if (ret != LDB_SUCCESS) {
1600 talloc_free(mem_ctx);
1601 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1602 return NULL;
1605 talloc_steal(req, attrs);
1607 ret = ldb_request(ldb_ctx, req);
1609 if (ret == LDB_SUCCESS) {
1610 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1613 if (ret != LDB_SUCCESS) {
1614 talloc_free(mem_ctx);
1615 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1616 return NULL;
1619 py_ret = PyLdbResult_FromResult(res);
1621 talloc_free(mem_ctx);
1623 return py_ret;
1626 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1628 char *name;
1629 void *data;
1631 if (!PyArg_ParseTuple(args, "s", &name))
1632 return NULL;
1634 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1636 if (data == NULL)
1637 Py_RETURN_NONE;
1639 /* FIXME: More interpretation */
1641 return Py_True;
1644 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1646 char *name;
1647 PyObject *data;
1649 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1650 return NULL;
1652 /* FIXME: More interpretation */
1654 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1656 Py_RETURN_NONE;
1659 static PyObject *py_ldb_modules(PyLdbObject *self)
1661 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1662 PyObject *ret = PyList_New(0);
1663 struct ldb_module *mod;
1665 for (mod = ldb->modules; mod; mod = mod->next) {
1666 PyList_Append(ret, PyLdbModule_FromModule(mod));
1669 return ret;
1672 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1674 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1675 int type, ret;
1676 uint64_t value;
1678 if (!PyArg_ParseTuple(args, "i", &type))
1679 return NULL;
1681 /* FIXME: More interpretation */
1683 ret = ldb_sequence_number(ldb, type, &value);
1685 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1687 return PyLong_FromLongLong(value);
1689 static PyMethodDef py_ldb_methods[] = {
1690 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1691 "S.set_debug(callback) -> None\n"
1692 "Set callback for LDB debug messages.\n"
1693 "The callback should accept a debug level and debug text." },
1694 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1695 "S.set_create_perms(mode) -> None\n"
1696 "Set mode to use when creating new LDB files." },
1697 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1698 "S.set_modules_dir(path) -> None\n"
1699 "Set path LDB should search for modules" },
1700 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1701 "S.transaction_start() -> None\n"
1702 "Start a new transaction." },
1703 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1704 "S.transaction_prepare_commit() -> None\n"
1705 "prepare to commit a new transaction (2-stage commit)." },
1706 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1707 "S.transaction_commit() -> None\n"
1708 "commit a new transaction." },
1709 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1710 "S.transaction_cancel() -> None\n"
1711 "cancel a new transaction." },
1712 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1713 NULL },
1714 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1715 NULL },
1716 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1717 NULL },
1718 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1719 NULL },
1720 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1721 NULL },
1722 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1723 "S.connect(url, flags=0, options=None) -> None\n"
1724 "Connect to a LDB URL." },
1725 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1726 "S.modify(message, controls=None, validate=False) -> None\n"
1727 "Modify an entry." },
1728 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1729 "S.add(message, controls=None) -> None\n"
1730 "Add an entry." },
1731 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1732 "S.delete(dn, controls=None) -> None\n"
1733 "Remove an entry." },
1734 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1735 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1736 "Rename an entry." },
1737 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1738 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1739 "Search in a database.\n"
1740 "\n"
1741 ":param base: Optional base DN to search\n"
1742 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1743 ":param expression: Optional search expression\n"
1744 ":param attrs: Attributes to return (defaults to all)\n"
1745 ":param controls: Optional list of controls\n"
1746 ":return: Iterator over Message objects\n"
1748 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1749 NULL },
1750 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1751 NULL },
1752 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1753 NULL },
1754 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1755 "S.parse_ldif(ldif) -> iter(messages)\n"
1756 "Parse a string formatted using LDIF." },
1757 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1758 "S.write_ldif(message, changetype) -> ldif\n"
1759 "Print the message as a string formatted using LDIF." },
1760 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1761 "S.msg_diff(Message) -> Message\n"
1762 "Return an LDB Message of the difference between two Message objects." },
1763 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1764 "S.get_opaque(name) -> value\n"
1765 "Get an opaque value set on this LDB connection. \n"
1766 ":note: The returned value may not be useful in Python."
1768 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1769 "S.set_opaque(name, value) -> None\n"
1770 "Set an opaque value on this LDB connection. \n"
1771 ":note: Passing incorrect values may cause crashes." },
1772 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1773 "S.modules() -> list\n"
1774 "Return the list of modules on this LDB connection " },
1775 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1776 "S.sequence_number(type) -> value\n"
1777 "Return the value of the sequence according to the requested type" },
1778 { NULL },
1781 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1783 PyLdbModuleObject *ret;
1785 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1786 if (ret == NULL) {
1787 PyErr_NoMemory();
1788 return NULL;
1790 ret->mem_ctx = talloc_new(NULL);
1791 ret->mod = talloc_reference(ret->mem_ctx, mod);
1792 return (PyObject *)ret;
1795 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1797 return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1800 static PyGetSetDef py_ldb_getset[] = {
1801 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1802 { NULL }
1805 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1807 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1808 struct ldb_dn *dn;
1809 struct ldb_result *result;
1810 unsigned int count;
1811 int ret;
1813 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1814 return -1;
1817 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1818 NULL);
1819 if (ret != LDB_SUCCESS) {
1820 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1821 return -1;
1824 count = result->count;
1826 talloc_free(result);
1828 if (count > 1) {
1829 PyErr_Format(PyExc_RuntimeError,
1830 "Searching for [%s] dn gave %u results!",
1831 ldb_dn_get_linearized(dn),
1832 count);
1833 return -1;
1836 return count;
1839 static PySequenceMethods py_ldb_seq = {
1840 .sq_contains = (objobjproc)py_ldb_contains,
1843 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1845 PyLdbObject *ret;
1847 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1848 if (ret == NULL) {
1849 PyErr_NoMemory();
1850 return NULL;
1852 ret->mem_ctx = talloc_new(NULL);
1853 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1854 return (PyObject *)ret;
1857 static void py_ldb_dealloc(PyLdbObject *self)
1859 talloc_free(self->mem_ctx);
1860 self->ob_type->tp_free(self);
1863 static PyTypeObject PyLdb = {
1864 .tp_name = "ldb.Ldb",
1865 .tp_methods = py_ldb_methods,
1866 .tp_repr = (reprfunc)py_ldb_repr,
1867 .tp_new = py_ldb_new,
1868 .tp_init = (initproc)py_ldb_init,
1869 .tp_dealloc = (destructor)py_ldb_dealloc,
1870 .tp_getset = py_ldb_getset,
1871 .tp_getattro = PyObject_GenericGetAttr,
1872 .tp_basicsize = sizeof(PyLdbObject),
1873 .tp_doc = "Connection to a LDB database.",
1874 .tp_as_sequence = &py_ldb_seq,
1875 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1878 static void py_ldb_result_dealloc(PyLdbResultObject *self)
1880 talloc_free(self->mem_ctx);
1881 Py_DECREF(self->msgs);
1882 Py_DECREF(self->referals);
1883 Py_DECREF(self->controls);
1884 self->ob_type->tp_free(self);
1887 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
1889 Py_INCREF(self->msgs);
1890 return self->msgs;
1893 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
1895 Py_INCREF(self->controls);
1896 return self->controls;
1899 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
1901 Py_INCREF(self->referals);
1902 return self->referals;
1905 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
1907 Py_ssize_t size;
1908 if (self->msgs == NULL) {
1909 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
1910 return NULL;
1912 size = PyList_Size(self->msgs);
1913 return PyInt_FromLong(size);
1916 static PyGetSetDef py_ldb_result_getset[] = {
1917 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
1918 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
1919 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
1920 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
1921 { NULL }
1924 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
1926 return PyObject_GetIter(self->msgs);
1929 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
1931 return PySequence_Size(self->msgs);
1934 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
1936 return PySequence_GetItem(self->msgs, idx);
1939 static PySequenceMethods py_ldb_result_seq = {
1940 .sq_length = (lenfunc)py_ldb_result_len,
1941 .sq_item = (ssizeargfunc)py_ldb_result_find,
1944 static PyObject *py_ldb_result_repr(PyLdbObject *self)
1946 return PyString_FromFormat("<ldb result>");
1950 static PyTypeObject PyLdbResult = {
1951 .tp_name = "ldb.Result",
1952 .tp_repr = (reprfunc)py_ldb_result_repr,
1953 .tp_dealloc = (destructor)py_ldb_result_dealloc,
1954 .tp_iter = (getiterfunc)py_ldb_result_iter,
1955 .tp_getset = py_ldb_result_getset,
1956 .tp_getattro = PyObject_GenericGetAttr,
1957 .tp_basicsize = sizeof(PyLdbResultObject),
1958 .tp_as_sequence = &py_ldb_result_seq,
1959 .tp_doc = "LDB result.",
1960 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1963 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1965 return PyString_FromFormat("<ldb module '%s'>",
1966 pyldb_Module_AsModule(self)->ops->name);
1969 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1971 return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
1974 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1976 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
1977 Py_RETURN_NONE;
1980 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1982 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
1983 Py_RETURN_NONE;
1986 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
1988 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
1989 Py_RETURN_NONE;
1992 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
1994 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
1995 int ret, scope;
1996 struct ldb_request *req;
1997 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
1998 struct ldb_module *mod;
1999 const char * const*attrs;
2001 /* type "int" rather than "enum" for "scope" is intentional */
2002 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
2003 discard_const_p(char *, kwnames),
2004 &py_base, &scope, &py_tree, &py_attrs))
2005 return NULL;
2007 mod = self->mod;
2009 if (py_attrs == Py_None) {
2010 attrs = NULL;
2011 } else {
2012 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
2013 if (attrs == NULL)
2014 return NULL;
2017 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2018 scope, NULL /* expr */, attrs,
2019 NULL /* controls */, NULL, NULL, NULL);
2021 talloc_steal(req, attrs);
2023 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2025 req->op.search.res = NULL;
2027 ret = mod->ops->search(mod, req);
2029 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2031 py_ret = PyLdbResult_FromResult(req->op.search.res);
2033 talloc_free(req);
2035 return py_ret;
2039 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2041 struct ldb_request *req;
2042 PyObject *py_message;
2043 int ret;
2044 struct ldb_module *mod;
2046 if (!PyArg_ParseTuple(args, "O", &py_message))
2047 return NULL;
2049 req = talloc_zero(NULL, struct ldb_request);
2050 req->operation = LDB_ADD;
2051 req->op.add.message = pyldb_Message_AsMessage(py_message);
2053 mod = pyldb_Module_AsModule(self);
2054 ret = mod->ops->add(mod, req);
2056 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2058 Py_RETURN_NONE;
2061 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2063 int ret;
2064 struct ldb_request *req;
2065 PyObject *py_message;
2066 struct ldb_module *mod;
2068 if (!PyArg_ParseTuple(args, "O", &py_message))
2069 return NULL;
2071 req = talloc_zero(NULL, struct ldb_request);
2072 req->operation = LDB_MODIFY;
2073 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2075 mod = pyldb_Module_AsModule(self);
2076 ret = mod->ops->modify(mod, req);
2078 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2080 Py_RETURN_NONE;
2083 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2085 int ret;
2086 struct ldb_request *req;
2087 PyObject *py_dn;
2089 if (!PyArg_ParseTuple(args, "O", &py_dn))
2090 return NULL;
2092 req = talloc_zero(NULL, struct ldb_request);
2093 req->operation = LDB_DELETE;
2094 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2096 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2098 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2100 Py_RETURN_NONE;
2103 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2105 int ret;
2106 struct ldb_request *req;
2107 PyObject *py_dn1, *py_dn2;
2109 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
2110 return NULL;
2112 req = talloc_zero(NULL, struct ldb_request);
2114 req->operation = LDB_RENAME;
2115 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2116 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2118 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2120 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2122 Py_RETURN_NONE;
2125 static PyMethodDef py_ldb_module_methods[] = {
2126 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2127 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2128 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2129 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2130 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2131 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2132 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2133 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2134 { NULL },
2137 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2139 talloc_free(self->mem_ctx);
2140 PyObject_Del(self);
2143 static PyTypeObject PyLdbModule = {
2144 .tp_name = "ldb.LdbModule",
2145 .tp_methods = py_ldb_module_methods,
2146 .tp_repr = (reprfunc)py_ldb_module_repr,
2147 .tp_str = (reprfunc)py_ldb_module_str,
2148 .tp_basicsize = sizeof(PyLdbModuleObject),
2149 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2150 .tp_flags = Py_TPFLAGS_DEFAULT,
2151 .tp_doc = "LDB module (extension)",
2156 * Create a ldb_message_element from a Python object.
2158 * This will accept any sequence objects that contains strings, or
2159 * a string object.
2161 * A reference to set_obj will be borrowed.
2163 * @param mem_ctx Memory context
2164 * @param set_obj Python object to convert
2165 * @param flags ldb_message_element flags to set
2166 * @param attr_name Name of the attribute
2167 * @return New ldb_message_element, allocated as child of mem_ctx
2169 static struct ldb_message_element *PyObject_AsMessageElement(
2170 TALLOC_CTX *mem_ctx,
2171 PyObject *set_obj,
2172 unsigned int flags,
2173 const char *attr_name)
2175 struct ldb_message_element *me;
2177 if (pyldb_MessageElement_Check(set_obj)) {
2178 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2179 /* We have to talloc_reference() the memory context, not the pointer
2180 * which may not actually be it's own context */
2181 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2182 return pyldb_MessageElement_AsMessageElement(set_obj);
2184 return NULL;
2187 me = talloc(mem_ctx, struct ldb_message_element);
2188 if (me == NULL) {
2189 PyErr_NoMemory();
2190 return NULL;
2193 me->name = talloc_strdup(me, attr_name);
2194 me->flags = flags;
2195 if (PyString_Check(set_obj)) {
2196 me->num_values = 1;
2197 me->values = talloc_array(me, struct ldb_val, me->num_values);
2198 me->values[0].length = PyString_Size(set_obj);
2199 me->values[0].data = talloc_memdup(me,
2200 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2201 } else if (PySequence_Check(set_obj)) {
2202 Py_ssize_t i;
2203 me->num_values = PySequence_Size(set_obj);
2204 me->values = talloc_array(me, struct ldb_val, me->num_values);
2205 for (i = 0; i < me->num_values; i++) {
2206 PyObject *obj = PySequence_GetItem(set_obj, i);
2207 if (!PyString_Check(obj)) {
2208 PyErr_Format(PyExc_TypeError,
2209 "Expected string as element %zd in list", i);
2210 talloc_free(me);
2211 return NULL;
2214 me->values[i].length = PyString_Size(obj);
2215 me->values[i].data = talloc_memdup(me,
2216 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2218 } else {
2219 talloc_free(me);
2220 me = NULL;
2223 return me;
2227 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2228 struct ldb_message_element *me)
2230 Py_ssize_t i;
2231 PyObject *result;
2233 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2234 result = PyList_New(me->num_values);
2236 for (i = 0; i < me->num_values; i++) {
2237 PyList_SetItem(result, i,
2238 PyObject_FromLdbValue(&me->values[i]));
2241 return result;
2244 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2246 unsigned int i;
2247 if (!PyArg_ParseTuple(args, "I", &i))
2248 return NULL;
2249 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2250 Py_RETURN_NONE;
2252 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2255 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2257 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2258 return PyInt_FromLong(el->flags);
2261 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2263 unsigned int flags;
2264 struct ldb_message_element *el;
2265 if (!PyArg_ParseTuple(args, "I", &flags))
2266 return NULL;
2268 el = pyldb_MessageElement_AsMessageElement(self);
2269 el->flags = flags;
2270 Py_RETURN_NONE;
2273 static PyMethodDef py_ldb_msg_element_methods[] = {
2274 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2275 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2276 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2277 { NULL },
2280 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2282 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2285 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2287 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2288 if (idx < 0 || idx >= el->num_values) {
2289 PyErr_SetString(PyExc_IndexError, "Out of range");
2290 return NULL;
2292 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2295 static PySequenceMethods py_ldb_msg_element_seq = {
2296 .sq_length = (lenfunc)py_ldb_msg_element_len,
2297 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2300 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2302 int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2303 pyldb_MessageElement_AsMessageElement(other));
2304 return SIGN(ret);
2307 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2309 PyObject *el = ldb_msg_element_to_set(NULL,
2310 pyldb_MessageElement_AsMessageElement(self));
2311 return PyObject_GetIter(el);
2314 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2316 PyLdbMessageElementObject *ret;
2317 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2318 if (ret == NULL) {
2319 PyErr_NoMemory();
2320 return NULL;
2322 ret->mem_ctx = talloc_new(NULL);
2323 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2324 PyErr_NoMemory();
2325 return NULL;
2327 ret->el = el;
2328 return (PyObject *)ret;
2331 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2333 PyObject *py_elements = NULL;
2334 struct ldb_message_element *el;
2335 unsigned int flags = 0;
2336 char *name = NULL;
2337 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2338 PyLdbMessageElementObject *ret;
2339 TALLOC_CTX *mem_ctx;
2341 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2342 discard_const_p(char *, kwnames),
2343 &py_elements, &flags, &name))
2344 return NULL;
2346 mem_ctx = talloc_new(NULL);
2347 if (mem_ctx == NULL) {
2348 PyErr_NoMemory();
2349 return NULL;
2352 el = talloc_zero(mem_ctx, struct ldb_message_element);
2353 if (el == NULL) {
2354 PyErr_NoMemory();
2355 talloc_free(mem_ctx);
2356 return NULL;
2359 if (py_elements != NULL) {
2360 Py_ssize_t i;
2361 if (PyString_Check(py_elements)) {
2362 el->num_values = 1;
2363 el->values = talloc_array(el, struct ldb_val, 1);
2364 if (el->values == NULL) {
2365 talloc_free(mem_ctx);
2366 PyErr_NoMemory();
2367 return NULL;
2369 el->values[0].length = PyString_Size(py_elements);
2370 el->values[0].data = talloc_memdup(el->values,
2371 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2372 } else if (PySequence_Check(py_elements)) {
2373 el->num_values = PySequence_Size(py_elements);
2374 el->values = talloc_array(el, struct ldb_val, el->num_values);
2375 if (el->values == NULL) {
2376 talloc_free(mem_ctx);
2377 PyErr_NoMemory();
2378 return NULL;
2380 for (i = 0; i < el->num_values; i++) {
2381 PyObject *item = PySequence_GetItem(py_elements, i);
2382 if (item == NULL) {
2383 talloc_free(mem_ctx);
2384 return NULL;
2386 if (!PyString_Check(item)) {
2387 PyErr_Format(PyExc_TypeError,
2388 "Expected string as element %zd in list", i);
2389 talloc_free(mem_ctx);
2390 return NULL;
2392 el->values[i].length = PyString_Size(item);
2393 el->values[i].data = talloc_memdup(el,
2394 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2396 } else {
2397 PyErr_SetString(PyExc_TypeError,
2398 "Expected string or list");
2399 talloc_free(mem_ctx);
2400 return NULL;
2404 el->flags = flags;
2405 el->name = talloc_strdup(el, name);
2407 ret = PyObject_New(PyLdbMessageElementObject, type);
2408 if (ret == NULL) {
2409 talloc_free(mem_ctx);
2410 return NULL;
2413 ret->mem_ctx = mem_ctx;
2414 ret->el = el;
2415 return (PyObject *)ret;
2418 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2420 char *element_str = NULL;
2421 Py_ssize_t i;
2422 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2423 PyObject *ret;
2425 for (i = 0; i < el->num_values; i++) {
2426 PyObject *o = py_ldb_msg_element_find(self, i);
2427 if (element_str == NULL)
2428 element_str = talloc_strdup(NULL, PyObject_REPR(o));
2429 else
2430 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2433 if (element_str != NULL) {
2434 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2435 talloc_free(element_str);
2436 } else {
2437 ret = PyString_FromString("MessageElement([])");
2440 return ret;
2443 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2445 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2447 if (el->num_values == 1)
2448 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2449 else
2450 Py_RETURN_NONE;
2453 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2455 talloc_free(self->mem_ctx);
2456 PyObject_Del(self);
2459 static PyTypeObject PyLdbMessageElement = {
2460 .tp_name = "ldb.MessageElement",
2461 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2462 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2463 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2464 .tp_str = (reprfunc)py_ldb_msg_element_str,
2465 .tp_methods = py_ldb_msg_element_methods,
2466 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2467 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2468 .tp_as_sequence = &py_ldb_msg_element_seq,
2469 .tp_new = py_ldb_msg_element_new,
2470 .tp_flags = Py_TPFLAGS_DEFAULT,
2471 .tp_doc = "An element of a Message",
2475 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2477 PyObject *py_ldb;
2478 PyObject *py_dict;
2479 PyObject *py_ret;
2480 struct ldb_message *msg;
2481 struct ldb_context *ldb_ctx;
2482 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2484 if (!PyArg_ParseTuple(args, "O!O!|I",
2485 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2486 &mod_flags)) {
2487 return NULL;
2490 if (!PyLdb_Check(py_ldb)) {
2491 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
2492 return NULL;
2495 /* mask only flags we are going to use */
2496 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2497 if (!mod_flags) {
2498 PyErr_SetString(PyExc_ValueError,
2499 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2500 " expected as mod_flag value");
2501 return NULL;
2504 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2506 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2507 if (!msg) {
2508 return NULL;
2511 py_ret = PyLdbMessage_FromMessage(msg);
2513 talloc_unlink(ldb_ctx, msg);
2515 return py_ret;
2518 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2520 char *name;
2521 if (!PyArg_ParseTuple(args, "s", &name))
2522 return NULL;
2524 ldb_msg_remove_attr(self->msg, name);
2526 Py_RETURN_NONE;
2529 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2531 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2532 Py_ssize_t i, j = 0;
2533 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2534 if (msg->dn != NULL) {
2535 PyList_SetItem(obj, j, PyString_FromString("dn"));
2536 j++;
2538 for (i = 0; i < msg->num_elements; i++) {
2539 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2540 j++;
2542 return obj;
2545 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2547 struct ldb_message_element *el;
2548 char *name;
2549 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2550 if (!PyString_Check(py_name)) {
2551 PyErr_SetNone(PyExc_TypeError);
2552 return NULL;
2554 name = PyString_AsString(py_name);
2555 if (!ldb_attr_cmp(name, "dn"))
2556 return pyldb_Dn_FromDn(msg->dn);
2557 el = ldb_msg_find_element(msg, name);
2558 if (el == NULL) {
2559 return NULL;
2561 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2564 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2566 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2567 if (ret == NULL) {
2568 PyErr_SetString(PyExc_KeyError, "No such element");
2569 return NULL;
2571 return ret;
2574 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2576 PyObject *def = NULL;
2577 const char *kwnames[] = { "name", "default", "idx", NULL };
2578 const char *name = NULL;
2579 int idx = -1;
2580 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2581 struct ldb_message_element *el;
2583 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2584 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2585 return NULL;
2588 if (strcasecmp(name, "dn") == 0) {
2589 return pyldb_Dn_FromDn(msg->dn);
2592 el = ldb_msg_find_element(msg, name);
2594 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2595 if (def != NULL) {
2596 return def;
2598 Py_RETURN_NONE;
2601 if (idx == -1) {
2602 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2605 return PyObject_FromLdbValue(&el->values[idx]);
2608 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2610 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2611 Py_ssize_t i, j = 0;
2612 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2613 if (msg->dn != NULL) {
2614 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2615 j++;
2617 for (i = 0; i < msg->num_elements; i++, j++) {
2618 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2619 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2620 PyList_SetItem(l, j, value);
2622 return l;
2625 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2627 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2628 Py_ssize_t i = 0;
2629 PyObject *l = PyList_New(msg->num_elements);
2630 for (i = 0; i < msg->num_elements; i++) {
2631 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2633 return l;
2636 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2638 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2639 PyLdbMessageElementObject *py_element;
2640 int ret;
2641 struct ldb_message_element *el;
2643 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2644 return NULL;
2646 el = talloc_reference(msg, py_element->el);
2647 if (el == NULL) {
2648 PyErr_NoMemory();
2649 return NULL;
2652 ret = ldb_msg_add(msg, el, el->flags);
2653 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2655 Py_RETURN_NONE;
2658 static PyMethodDef py_ldb_msg_methods[] = {
2659 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2660 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2661 "Class method to create ldb.Message object from Dictionary.\n"
2662 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2663 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2664 "S.keys() -> list\n\n"
2665 "Return sequence of all attribute names." },
2666 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2667 "S.remove(name)\n\n"
2668 "Remove all entries for attributes with the specified name."},
2669 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2670 "msg.get(name,default=None,idx=None) -> string\n"
2671 "idx is the index into the values array\n"
2672 "if idx is None, then a list is returned\n"
2673 "if idx is not None, then the element with that index is returned\n"
2674 "if you pass the special name 'dn' then the DN object is returned\n"},
2675 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2676 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2677 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2678 "S.append(element)\n\n"
2679 "Add an element to this message." },
2680 { NULL },
2683 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2685 PyObject *list, *iter;
2687 list = py_ldb_msg_keys(self);
2688 iter = PyObject_GetIter(list);
2689 Py_DECREF(list);
2690 return iter;
2693 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2695 char *attr_name;
2697 if (!PyString_Check(name)) {
2698 PyErr_SetNone(PyExc_TypeError);
2699 return -1;
2702 attr_name = PyString_AsString(name);
2703 if (value == NULL) {
2704 /* delitem */
2705 ldb_msg_remove_attr(self->msg, attr_name);
2706 } else {
2707 int ret;
2708 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2709 value, 0, attr_name);
2710 if (el == NULL)
2711 return -1;
2712 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2713 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2714 if (ret != LDB_SUCCESS) {
2715 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
2716 return -1;
2719 return 0;
2722 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2724 return pyldb_Message_AsMessage(self)->num_elements;
2727 static PyMappingMethods py_ldb_msg_mapping = {
2728 .mp_length = (lenfunc)py_ldb_msg_length,
2729 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2730 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2733 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2735 const char * const kwnames[] = { "dn", NULL };
2736 struct ldb_message *ret;
2737 TALLOC_CTX *mem_ctx;
2738 PyObject *pydn = NULL;
2739 PyLdbMessageObject *py_ret;
2741 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2742 discard_const_p(char *, kwnames),
2743 &pydn))
2744 return NULL;
2746 mem_ctx = talloc_new(NULL);
2747 if (mem_ctx == NULL) {
2748 PyErr_NoMemory();
2749 return NULL;
2752 ret = ldb_msg_new(mem_ctx);
2753 if (ret == NULL) {
2754 talloc_free(mem_ctx);
2755 PyErr_NoMemory();
2756 return NULL;
2759 if (pydn != NULL) {
2760 struct ldb_dn *dn;
2761 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2762 talloc_free(mem_ctx);
2763 return NULL;
2765 ret->dn = talloc_reference(ret, dn);
2768 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2769 if (py_ret == NULL) {
2770 PyErr_NoMemory();
2771 talloc_free(mem_ctx);
2772 return NULL;
2775 py_ret->mem_ctx = mem_ctx;
2776 py_ret->msg = ret;
2777 return (PyObject *)py_ret;
2780 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2782 PyLdbMessageObject *ret;
2784 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2785 if (ret == NULL) {
2786 PyErr_NoMemory();
2787 return NULL;
2789 ret->mem_ctx = talloc_new(NULL);
2790 ret->msg = talloc_reference(ret->mem_ctx, msg);
2791 return (PyObject *)ret;
2794 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2796 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2797 return pyldb_Dn_FromDn(msg->dn);
2800 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2802 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2803 if (!pyldb_Dn_Check(value)) {
2804 PyErr_SetNone(PyExc_TypeError);
2805 return -1;
2808 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2809 return 0;
2812 static PyGetSetDef py_ldb_msg_getset[] = {
2813 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2814 { NULL }
2817 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2819 PyObject *dict = PyDict_New(), *ret;
2820 if (PyDict_Update(dict, (PyObject *)self) != 0)
2821 return NULL;
2822 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2823 Py_DECREF(dict);
2824 return ret;
2827 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2829 talloc_free(self->mem_ctx);
2830 PyObject_Del(self);
2833 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2834 PyLdbMessageObject *py_msg2)
2836 struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
2837 *msg2 = pyldb_Message_AsMessage(py_msg2);
2838 unsigned int i;
2839 int ret;
2841 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2842 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2843 if (ret != 0) {
2844 return SIGN(ret);
2848 ret = msg1->num_elements - msg2->num_elements;
2849 if (ret != 0) {
2850 return SIGN(ret);
2853 for (i = 0; i < msg1->num_elements; i++) {
2854 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2855 &msg2->elements[i]);
2856 if (ret != 0) {
2857 return SIGN(ret);
2860 ret = ldb_msg_element_compare(&msg1->elements[i],
2861 &msg2->elements[i]);
2862 if (ret != 0) {
2863 return SIGN(ret);
2867 return 0;
2870 static PyTypeObject PyLdbMessage = {
2871 .tp_name = "ldb.Message",
2872 .tp_methods = py_ldb_msg_methods,
2873 .tp_getset = py_ldb_msg_getset,
2874 .tp_as_mapping = &py_ldb_msg_mapping,
2875 .tp_basicsize = sizeof(PyLdbMessageObject),
2876 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2877 .tp_new = py_ldb_msg_new,
2878 .tp_repr = (reprfunc)py_ldb_msg_repr,
2879 .tp_flags = Py_TPFLAGS_DEFAULT,
2880 .tp_iter = (getiterfunc)py_ldb_msg_iter,
2881 .tp_compare = (cmpfunc)py_ldb_msg_compare,
2882 .tp_doc = "A LDB Message",
2885 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2887 PyLdbTreeObject *ret;
2889 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2890 if (ret == NULL) {
2891 PyErr_NoMemory();
2892 return NULL;
2895 ret->mem_ctx = talloc_new(NULL);
2896 ret->tree = talloc_reference(ret->mem_ctx, tree);
2897 return (PyObject *)ret;
2900 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2902 talloc_free(self->mem_ctx);
2903 PyObject_Del(self);
2906 static PyTypeObject PyLdbTree = {
2907 .tp_name = "ldb.Tree",
2908 .tp_basicsize = sizeof(PyLdbTreeObject),
2909 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2910 .tp_flags = Py_TPFLAGS_DEFAULT,
2911 .tp_doc = "A search tree",
2914 /* Ldb_module */
2915 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2917 PyObject *py_ldb = (PyObject *)mod->private_data;
2918 PyObject *py_result, *py_base, *py_attrs, *py_tree;
2920 py_base = pyldb_Dn_FromDn(req->op.search.base);
2922 if (py_base == NULL)
2923 return LDB_ERR_OPERATIONS_ERROR;
2925 py_tree = PyLdbTree_FromTree(req->op.search.tree);
2927 if (py_tree == NULL)
2928 return LDB_ERR_OPERATIONS_ERROR;
2930 if (req->op.search.attrs == NULL) {
2931 py_attrs = Py_None;
2932 } else {
2933 int i, len;
2934 for (len = 0; req->op.search.attrs[len]; len++);
2935 py_attrs = PyList_New(len);
2936 for (i = 0; i < len; i++)
2937 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2940 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2941 discard_const_p(char, "OiOO"),
2942 py_base, req->op.search.scope, py_tree, py_attrs);
2944 Py_DECREF(py_attrs);
2945 Py_DECREF(py_tree);
2946 Py_DECREF(py_base);
2948 if (py_result == NULL) {
2949 return LDB_ERR_PYTHON_EXCEPTION;
2952 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2953 if (req->op.search.res == NULL) {
2954 return LDB_ERR_PYTHON_EXCEPTION;
2957 Py_DECREF(py_result);
2959 return LDB_SUCCESS;
2962 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2964 PyObject *py_ldb = (PyObject *)mod->private_data;
2965 PyObject *py_result, *py_msg;
2967 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2969 if (py_msg == NULL) {
2970 return LDB_ERR_OPERATIONS_ERROR;
2973 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2974 discard_const_p(char, "O"),
2975 py_msg);
2977 Py_DECREF(py_msg);
2979 if (py_result == NULL) {
2980 return LDB_ERR_PYTHON_EXCEPTION;
2983 Py_DECREF(py_result);
2985 return LDB_SUCCESS;
2988 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
2990 PyObject *py_ldb = (PyObject *)mod->private_data;
2991 PyObject *py_result, *py_msg;
2993 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
2995 if (py_msg == NULL) {
2996 return LDB_ERR_OPERATIONS_ERROR;
2999 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3000 discard_const_p(char, "O"),
3001 py_msg);
3003 Py_DECREF(py_msg);
3005 if (py_result == NULL) {
3006 return LDB_ERR_PYTHON_EXCEPTION;
3009 Py_DECREF(py_result);
3011 return LDB_SUCCESS;
3014 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3016 PyObject *py_ldb = (PyObject *)mod->private_data;
3017 PyObject *py_result, *py_dn;
3019 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3021 if (py_dn == NULL)
3022 return LDB_ERR_OPERATIONS_ERROR;
3024 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3025 discard_const_p(char, "O"),
3026 py_dn);
3028 if (py_result == NULL) {
3029 return LDB_ERR_PYTHON_EXCEPTION;
3032 Py_DECREF(py_result);
3034 return LDB_SUCCESS;
3037 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3039 PyObject *py_ldb = (PyObject *)mod->private_data;
3040 PyObject *py_result, *py_olddn, *py_newdn;
3042 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3044 if (py_olddn == NULL)
3045 return LDB_ERR_OPERATIONS_ERROR;
3047 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3049 if (py_newdn == NULL)
3050 return LDB_ERR_OPERATIONS_ERROR;
3052 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3053 discard_const_p(char, "OO"),
3054 py_olddn, py_newdn);
3056 Py_DECREF(py_olddn);
3057 Py_DECREF(py_newdn);
3059 if (py_result == NULL) {
3060 return LDB_ERR_PYTHON_EXCEPTION;
3063 Py_DECREF(py_result);
3065 return LDB_SUCCESS;
3068 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3070 PyObject *py_ldb = (PyObject *)mod->private_data;
3071 PyObject *py_result;
3073 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3074 discard_const_p(char, ""));
3076 return LDB_ERR_OPERATIONS_ERROR;
3079 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3081 PyObject *py_ldb = (PyObject *)mod->private_data;
3082 PyObject *py_result;
3084 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3085 discard_const_p(char, ""));
3087 return LDB_ERR_OPERATIONS_ERROR;
3090 static int py_module_start_transaction(struct ldb_module *mod)
3092 PyObject *py_ldb = (PyObject *)mod->private_data;
3093 PyObject *py_result;
3095 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3096 discard_const_p(char, ""));
3098 if (py_result == NULL) {
3099 return LDB_ERR_PYTHON_EXCEPTION;
3102 Py_DECREF(py_result);
3104 return LDB_SUCCESS;
3107 static int py_module_end_transaction(struct ldb_module *mod)
3109 PyObject *py_ldb = (PyObject *)mod->private_data;
3110 PyObject *py_result;
3112 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3113 discard_const_p(char, ""));
3115 if (py_result == NULL) {
3116 return LDB_ERR_PYTHON_EXCEPTION;
3119 Py_DECREF(py_result);
3121 return LDB_SUCCESS;
3124 static int py_module_del_transaction(struct ldb_module *mod)
3126 PyObject *py_ldb = (PyObject *)mod->private_data;
3127 PyObject *py_result;
3129 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3130 discard_const_p(char, ""));
3132 if (py_result == NULL) {
3133 return LDB_ERR_PYTHON_EXCEPTION;
3136 Py_DECREF(py_result);
3138 return LDB_SUCCESS;
3141 static int py_module_destructor(struct ldb_module *mod)
3143 Py_DECREF((PyObject *)mod->private_data);
3144 return 0;
3147 static int py_module_init(struct ldb_module *mod)
3149 PyObject *py_class = (PyObject *)mod->ops->private_data;
3150 PyObject *py_result, *py_next, *py_ldb;
3152 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3154 if (py_ldb == NULL)
3155 return LDB_ERR_OPERATIONS_ERROR;
3157 py_next = PyLdbModule_FromModule(mod->next);
3159 if (py_next == NULL)
3160 return LDB_ERR_OPERATIONS_ERROR;
3162 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3163 py_ldb, py_next);
3165 if (py_result == NULL) {
3166 return LDB_ERR_PYTHON_EXCEPTION;
3169 mod->private_data = py_result;
3171 talloc_set_destructor(mod, py_module_destructor);
3173 return ldb_next_init(mod);
3176 static PyObject *py_register_module(PyObject *module, PyObject *args)
3178 int ret;
3179 struct ldb_module_ops *ops;
3180 PyObject *input;
3182 if (!PyArg_ParseTuple(args, "O", &input))
3183 return NULL;
3185 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3186 if (ops == NULL) {
3187 PyErr_NoMemory();
3188 return NULL;
3191 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3193 Py_INCREF(input);
3194 ops->private_data = input;
3195 ops->init_context = py_module_init;
3196 ops->search = py_module_search;
3197 ops->add = py_module_add;
3198 ops->modify = py_module_modify;
3199 ops->del = py_module_del;
3200 ops->rename = py_module_rename;
3201 ops->request = py_module_request;
3202 ops->extended = py_module_extended;
3203 ops->start_transaction = py_module_start_transaction;
3204 ops->end_transaction = py_module_end_transaction;
3205 ops->del_transaction = py_module_del_transaction;
3207 ret = ldb_register_module(ops);
3209 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3211 Py_RETURN_NONE;
3214 static PyObject *py_timestring(PyObject *module, PyObject *args)
3216 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3217 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3218 long int t_val;
3219 char *tresult;
3220 PyObject *ret;
3221 if (!PyArg_ParseTuple(args, "l", &t_val))
3222 return NULL;
3223 tresult = ldb_timestring(NULL, (time_t) t_val);
3224 ret = PyString_FromString(tresult);
3225 talloc_free(tresult);
3226 return ret;
3229 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3231 char *str;
3232 if (!PyArg_ParseTuple(args, "s", &str))
3233 return NULL;
3235 return PyInt_FromLong(ldb_string_to_time(str));
3238 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3240 char *name;
3241 if (!PyArg_ParseTuple(args, "s", &name))
3242 return NULL;
3243 return PyBool_FromLong(ldb_valid_attr_name(name));
3247 encode a string using RFC2254 rules
3249 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3251 char *str, *encoded;
3252 int size = 0;
3253 struct ldb_val val;
3254 PyObject *ret;
3256 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3257 return NULL;
3258 val.data = (uint8_t *)str;
3259 val.length = size;
3261 encoded = ldb_binary_encode(NULL, val);
3262 if (encoded == NULL) {
3263 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3264 return NULL;
3266 ret = PyString_FromString(encoded);
3267 talloc_free(encoded);
3268 return ret;
3272 decode a string using RFC2254 rules
3274 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3276 char *str;
3277 struct ldb_val val;
3278 PyObject *ret;
3280 if (!PyArg_ParseTuple(args, "s", &str))
3281 return NULL;
3283 val = ldb_binary_decode(NULL, str);
3284 if (val.data == NULL) {
3285 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3286 return NULL;
3288 ret = Py_BuildValue("s#", val.data, val.length);
3289 talloc_free(val.data);
3290 return ret;
3293 static PyMethodDef py_ldb_global_methods[] = {
3294 { "register_module", py_register_module, METH_VARARGS,
3295 "S.register_module(module) -> None\n\n"
3296 "Register a LDB module."},
3297 { "timestring", py_timestring, METH_VARARGS,
3298 "S.timestring(int) -> string\n\n"
3299 "Generate a LDAP time string from a UNIX timestamp" },
3300 { "string_to_time", py_string_to_time, METH_VARARGS,
3301 "S.string_to_time(string) -> int\n\n"
3302 "Parse a LDAP time string into a UNIX timestamp." },
3303 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3304 "S.valid_attr_name(name) -> bool\n\nn"
3305 "Check whether the supplied name is a valid attribute name." },
3306 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3307 "S.open() -> Ldb\n\n"
3308 "Open a new LDB context." },
3309 { "binary_encode", py_binary_encode, METH_VARARGS,
3310 "S.binary_encode(string) -> string\n\n"
3311 "Perform a RFC2254 binary encoding on a string" },
3312 { "binary_decode", py_binary_decode, METH_VARARGS,
3313 "S.binary_decode(string) -> string\n\n"
3314 "Perform a RFC2254 binary decode on a string" },
3315 { NULL }
3318 void initldb(void)
3320 PyObject *m;
3322 if (PyType_Ready(&PyLdbDn) < 0)
3323 return;
3325 if (PyType_Ready(&PyLdbMessage) < 0)
3326 return;
3328 if (PyType_Ready(&PyLdbMessageElement) < 0)
3329 return;
3331 if (PyType_Ready(&PyLdb) < 0)
3332 return;
3334 if (PyType_Ready(&PyLdbModule) < 0)
3335 return;
3337 if (PyType_Ready(&PyLdbTree) < 0)
3338 return;
3340 if (PyType_Ready(&PyLdbResult) < 0)
3341 return;
3343 if (PyType_Ready(&PyLdbControl) < 0)
3344 return;
3346 m = Py_InitModule3("ldb", py_ldb_global_methods,
3347 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3348 if (m == NULL)
3349 return;
3351 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3352 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3353 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3354 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3355 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3356 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3357 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3359 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3360 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3361 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3362 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3364 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3365 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3366 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3368 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3369 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3370 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3371 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3372 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3373 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3374 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3375 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3376 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3377 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3378 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3379 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3380 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3381 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3382 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3383 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3384 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3385 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3386 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3387 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3388 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3389 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3390 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3391 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3392 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3393 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3394 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3395 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3396 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3397 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3398 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3399 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3400 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3401 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3402 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3403 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3404 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3405 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3406 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3408 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3409 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3410 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3411 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3413 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3415 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3416 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3418 Py_INCREF(&PyLdb);
3419 Py_INCREF(&PyLdbDn);
3420 Py_INCREF(&PyLdbModule);
3421 Py_INCREF(&PyLdbMessage);
3422 Py_INCREF(&PyLdbMessageElement);
3423 Py_INCREF(&PyLdbTree);
3424 Py_INCREF(&PyLdbResult);
3425 Py_INCREF(&PyLdbControl);
3427 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3428 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3429 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3430 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3431 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3432 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3433 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3435 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3437 #define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3439 ADD_LDB_STRING(SYNTAX_DN);
3440 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3441 ADD_LDB_STRING(SYNTAX_INTEGER);
3442 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3443 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3444 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3445 ADD_LDB_STRING(OID_COMPARATOR_AND);
3446 ADD_LDB_STRING(OID_COMPARATOR_OR);