s3:libsmb: remove unused 'inbuf' variable
[Samba/gebeck_regimport.git] / lib / ldb / pyldb.c
blobea7b695d6d7cfe6d409aac2f82ffd14617722f17
1 /*
2 Unix SMB/CIFS implementation.
4 Python interface to ldb.
6 Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7 Copyright (C) 2006 Simo Sorce <idra@samba.org>
8 Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9 Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10 Copyright (C) 2009-2011 Andrew Tridgell
11 Copyright (C) 2009-2011 Andrew Bartlett
13 ** NOTE! The following LGPL license applies to the ldb
14 ** library. This does NOT imply that all of Samba is released
15 ** under the LGPL
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public
19 License as published by the Free Software Foundation; either
20 version 3 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, see <http://www.gnu.org/licenses/>.
31 #include <Python.h>
32 #include "ldb_private.h"
33 #include "pyldb.h"
35 void initldb(void);
36 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
37 static PyObject *PyExc_LdbError;
39 staticforward PyTypeObject PyLdbControl;
40 staticforward PyTypeObject PyLdbResult;
41 staticforward PyTypeObject PyLdbMessage;
42 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
43 staticforward PyTypeObject PyLdbModule;
44 staticforward PyTypeObject PyLdbDn;
45 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
46 staticforward PyTypeObject PyLdb;
47 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
48 staticforward PyTypeObject PyLdbMessageElement;
49 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
51 staticforward PyTypeObject PyLdbTree;
52 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
53 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
54 static struct ldb_message_element *PyObject_AsMessageElement(
55 TALLOC_CTX *mem_ctx,
56 PyObject *set_obj,
57 unsigned int flags,
58 const char *attr_name);
60 /* There's no Py_ssize_t in 2.4, apparently */
61 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
62 typedef int Py_ssize_t;
63 typedef inquiry lenfunc;
64 typedef intargfunc ssizeargfunc;
65 #endif
67 #ifndef Py_RETURN_NONE
68 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
69 #endif
71 #define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
75 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
77 if (self->data != NULL) {
78 char* control = ldb_control_to_string(self->mem_ctx, self->data);
79 if (control == NULL) {
80 PyErr_NoMemory();
81 return NULL;
83 return PyString_FromString(control);
84 } else {
85 return PyString_FromFormat("ldb control");
89 static void py_ldb_control_dealloc(PyLdbControlObject *self)
91 if (self->mem_ctx != NULL) {
92 talloc_free(self->mem_ctx);
94 self->data = NULL;
95 self->ob_type->tp_free(self);
98 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
100 return PyString_FromString(self->data->oid);
103 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
105 return PyBool_FromLong(self->data->critical);
108 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
110 if (PyObject_IsTrue(value)) {
111 self->data->critical = true;
112 } else {
113 self->data->critical = false;
115 return 0;
118 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
120 char *data = NULL;
121 const char * const kwnames[] = { "ldb", "data", NULL };
122 struct ldb_control *parsed_controls;
123 PyLdbControlObject *ret;
124 PyObject *py_ldb;
125 TALLOC_CTX *mem_ctx;
126 struct ldb_context *ldb_ctx;
128 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
129 discard_const_p(char *, kwnames),
130 &py_ldb, &data))
131 return NULL;
133 mem_ctx = talloc_new(NULL);
134 if (mem_ctx == NULL) {
135 PyErr_NoMemory();
136 return NULL;
139 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
140 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
142 if (!parsed_controls) {
143 talloc_free(mem_ctx);
144 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
145 return NULL;
148 ret = PyObject_New(PyLdbControlObject, type);
149 if (ret == NULL) {
150 PyErr_NoMemory();
151 talloc_free(mem_ctx);
152 return NULL;
155 ret->mem_ctx = mem_ctx;
157 ret->data = talloc_move(mem_ctx, &parsed_controls);
158 if (ret->data == NULL) {
159 Py_DECREF(ret);
160 PyErr_NoMemory();
161 talloc_free(mem_ctx);
162 return NULL;
165 return (PyObject *)ret;
168 static PyGetSetDef py_ldb_control_getset[] = {
169 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
170 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
171 { NULL }
174 static PyTypeObject PyLdbControl = {
175 .tp_name = "ldb.control",
176 .tp_dealloc = (destructor)py_ldb_control_dealloc,
177 .tp_getattro = PyObject_GenericGetAttr,
178 .tp_basicsize = sizeof(PyLdbControlObject),
179 .tp_getset = py_ldb_control_getset,
180 .tp_doc = "LDB control.",
181 .tp_str = (reprfunc)py_ldb_control_str,
182 .tp_new = py_ldb_control_new,
183 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
186 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
188 if (ret == LDB_ERR_PYTHON_EXCEPTION)
189 return; /* Python exception should already be set, just keep that */
191 PyErr_SetObject(error,
192 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
193 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
196 static PyObject *PyObject_FromLdbValue(struct ldb_val *val)
198 return PyString_FromStringAndSize((const char *)val->data, val->length);
202 * Create a Python object from a ldb_result.
204 * @param result LDB result to convert
205 * @return Python object with converted result (a list object)
207 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
209 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
210 PyLdbControlObject *ctrl;
211 if (ctl_ctx == NULL) {
212 PyErr_NoMemory();
213 return NULL;
216 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
217 if (ctrl == NULL) {
218 talloc_free(ctl_ctx);
219 PyErr_NoMemory();
220 return NULL;
222 ctrl->mem_ctx = ctl_ctx;
223 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
224 if (ctrl->data == NULL) {
225 Py_DECREF(ctrl);
226 PyErr_NoMemory();
227 return NULL;
229 return (PyObject*) ctrl;
233 * Create a Python object from a ldb_result.
235 * @param result LDB result to convert
236 * @return Python object with converted result (a list object)
238 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
240 PyLdbResultObject *ret;
241 PyObject *list, *controls, *referals;
242 Py_ssize_t i;
244 if (result == NULL) {
245 Py_RETURN_NONE;
248 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
249 if (ret == NULL) {
250 PyErr_NoMemory();
251 return NULL;
254 list = PyList_New(result->count);
255 if (list == NULL) {
256 PyErr_NoMemory();
257 Py_DECREF(ret);
258 return NULL;
261 for (i = 0; i < result->count; i++) {
262 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
265 ret->mem_ctx = talloc_new(NULL);
266 if (ret->mem_ctx == NULL) {
267 Py_DECREF(list);
268 Py_DECREF(ret);
269 PyErr_NoMemory();
270 return NULL;
273 ret->msgs = list;
275 if (result->controls) {
276 controls = PyList_New(1);
277 if (controls == NULL) {
278 Py_DECREF(ret);
279 PyErr_NoMemory();
280 return NULL;
282 for (i=0; result->controls[i]; i++) {
283 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
284 if (ctrl == NULL) {
285 Py_DECREF(ret);
286 Py_DECREF(controls);
287 PyErr_NoMemory();
288 return NULL;
290 PyList_SetItem(controls, i, ctrl);
292 } else {
294 * No controls so we keep an empty list
296 controls = PyList_New(0);
297 if (controls == NULL) {
298 Py_DECREF(ret);
299 PyErr_NoMemory();
300 return NULL;
304 ret->controls = controls;
306 i = 0;
308 while (result->refs && result->refs[i]) {
309 i++;
312 referals = PyList_New(i);
313 if (referals == NULL) {
314 Py_DECREF(ret);
315 PyErr_NoMemory();
316 return NULL;
319 for (i = 0;result->refs && result->refs[i]; i++) {
320 PyList_SetItem(referals, i, PyString_FromString(result->refs[i]));
322 ret->referals = referals;
323 return (PyObject *)ret;
327 * Create a LDB Result from a Python object.
328 * If conversion fails, NULL will be returned and a Python exception set.
330 * Note: the result object only includes the messages at the moment; extended
331 * result, controls and referrals are ignored.
333 * @param mem_ctx Memory context in which to allocate the LDB Result
334 * @param obj Python object to convert
335 * @return a ldb_result, or NULL if the conversion failed
337 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
338 PyObject *obj)
340 struct ldb_result *res;
341 Py_ssize_t i;
343 if (obj == Py_None)
344 return NULL;
346 res = talloc_zero(mem_ctx, struct ldb_result);
347 res->count = PyList_Size(obj);
348 res->msgs = talloc_array(res, struct ldb_message *, res->count);
349 for (i = 0; i < res->count; i++) {
350 PyObject *item = PyList_GetItem(obj, i);
351 res->msgs[i] = pyldb_Message_AsMessage(item);
353 return res;
356 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
358 return PyBool_FromLong(ldb_dn_validate(self->dn));
361 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
363 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
366 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
368 return PyBool_FromLong(ldb_dn_is_special(self->dn));
371 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
373 return PyBool_FromLong(ldb_dn_is_null(self->dn));
376 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
378 return PyString_FromString(ldb_dn_get_casefold(self->dn));
381 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
383 return PyString_FromString(ldb_dn_get_linearized(self->dn));
386 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
388 return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
391 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
393 return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
396 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
398 const char * const kwnames[] = { "mode", NULL };
399 int mode = 1;
400 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
401 discard_const_p(char *, kwnames),
402 &mode))
403 return NULL;
404 return PyString_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
407 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
409 char *name;
410 const struct ldb_val *val;
412 if (!PyArg_ParseTuple(args, "s", &name))
413 return NULL;
414 val = ldb_dn_get_extended_component(self->dn, name);
415 if (val == NULL) {
416 Py_RETURN_NONE;
419 return PyString_FromStringAndSize((const char *)val->data, val->length);
422 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
424 char *name;
425 PyObject *value;
426 int err;
428 if (!PyArg_ParseTuple(args, "sO", &name, &value))
429 return NULL;
431 if (value == Py_None) {
432 err = ldb_dn_set_extended_component(self->dn, name, NULL);
433 } else {
434 struct ldb_val val;
435 if (!PyString_Check(value)) {
436 PyErr_SetString(PyExc_TypeError, "Expected a string argument");
437 return NULL;
439 val.data = (uint8_t *)PyString_AsString(value);
440 val.length = PyString_Size(value);
441 err = ldb_dn_set_extended_component(self->dn, name, &val);
444 if (err != LDB_SUCCESS) {
445 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
446 return NULL;
449 Py_RETURN_NONE;
452 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
454 return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
457 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
459 char *name;
461 if (!PyArg_ParseTuple(args, "s", &name))
462 return NULL;
464 return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
467 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
469 int ret;
470 ret = ldb_dn_compare(dn1->dn, dn2->dn);
471 if (ret < 0) ret = -1;
472 if (ret > 0) ret = 1;
473 return ret;
476 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
478 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
479 struct ldb_dn *parent;
480 PyLdbDnObject *py_ret;
481 TALLOC_CTX *mem_ctx = talloc_new(NULL);
483 parent = ldb_dn_get_parent(mem_ctx, dn);
484 if (parent == NULL) {
485 talloc_free(mem_ctx);
486 Py_RETURN_NONE;
489 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
490 if (py_ret == NULL) {
491 PyErr_NoMemory();
492 talloc_free(mem_ctx);
493 return NULL;
495 py_ret->mem_ctx = mem_ctx;
496 py_ret->dn = parent;
497 return (PyObject *)py_ret;
500 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
502 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
504 PyObject *py_other;
505 struct ldb_dn *dn, *other;
506 if (!PyArg_ParseTuple(args, "O", &py_other))
507 return NULL;
509 dn = pyldb_Dn_AsDn((PyObject *)self);
511 if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
512 return NULL;
514 return ldb_dn_add_child(dn, other)?Py_True:Py_False;
517 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
519 PyObject *py_other;
520 struct ldb_dn *other, *dn;
521 if (!PyArg_ParseTuple(args, "O", &py_other))
522 return NULL;
524 dn = pyldb_Dn_AsDn((PyObject *)self);
526 if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
527 return NULL;
529 return ldb_dn_add_base(dn, other)?Py_True:Py_False;
532 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
534 PyObject *py_base;
535 struct ldb_dn *dn, *base;
536 if (!PyArg_ParseTuple(args, "O", &py_base))
537 return NULL;
539 dn = pyldb_Dn_AsDn((PyObject *)self);
541 if (!pyldb_Object_AsDn(NULL, py_base, dn_ldb_ctx(dn), &base))
542 return NULL;
544 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
547 static PyMethodDef py_ldb_dn_methods[] = {
548 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
549 "S.validate() -> bool\n"
550 "Validate DN is correct." },
551 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
552 "S.is_valid() -> bool\n" },
553 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
554 "S.is_special() -> bool\n"
555 "Check whether this is a special LDB DN." },
556 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
557 "Check whether this is a null DN." },
558 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
559 NULL },
560 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
561 NULL },
562 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
563 "S.canonical_str() -> string\n"
564 "Canonical version of this DN (like a posix path)." },
565 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
566 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
567 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
568 "S.canonical_ex_str() -> string\n"
569 "Canonical version of this DN (like a posix path, with terminating newline)." },
570 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
571 "S.extended_str(mode=1) -> string\n"
572 "Extended version of this DN" },
573 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
574 "S.parent() -> dn\n"
575 "Get the parent for this DN." },
576 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
577 "S.add_child(dn) -> None\n"
578 "Add a child DN to this DN." },
579 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
580 "S.add_base(dn) -> None\n"
581 "Add a base DN to this DN." },
582 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
583 "S.check_special(name) -> bool\n\n"
584 "Check if name is a special DN name"},
585 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
586 "S.get_extended_component(name) -> string\n\n"
587 "returns a DN extended component as a binary string"},
588 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
589 "S.set_extended_component(name, value) -> string\n\n"
590 "set a DN extended component as a binary string"},
591 { NULL }
594 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
596 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
600 copy a DN as a python object
602 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
604 PyLdbDnObject *py_ret;
606 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
607 if (py_ret == NULL) {
608 PyErr_NoMemory();
609 return NULL;
611 py_ret->mem_ctx = talloc_new(NULL);
612 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
613 return (PyObject *)py_ret;
616 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
618 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
619 *other;
620 PyLdbDnObject *py_ret;
622 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
623 return NULL;
625 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
626 if (py_ret == NULL) {
627 PyErr_NoMemory();
628 return NULL;
630 py_ret->mem_ctx = talloc_new(NULL);
631 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
632 ldb_dn_add_child(py_ret->dn, other);
633 return (PyObject *)py_ret;
636 static PySequenceMethods py_ldb_dn_seq = {
637 .sq_length = (lenfunc)py_ldb_dn_len,
638 .sq_concat = (binaryfunc)py_ldb_dn_concat,
641 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
643 struct ldb_dn *ret;
644 char *str;
645 PyObject *py_ldb;
646 struct ldb_context *ldb_ctx;
647 TALLOC_CTX *mem_ctx;
648 PyLdbDnObject *py_ret;
649 const char * const kwnames[] = { "ldb", "dn", NULL };
651 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
652 discard_const_p(char *, kwnames),
653 &py_ldb, &str))
654 return NULL;
656 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
658 mem_ctx = talloc_new(NULL);
659 if (mem_ctx == NULL) {
660 PyErr_NoMemory();
661 return NULL;
664 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
665 if (!ldb_dn_validate(ret)) {
666 talloc_free(mem_ctx);
667 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
668 return NULL;
671 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
672 if (ret == NULL) {
673 talloc_free(mem_ctx);
674 PyErr_NoMemory();
675 return NULL;
677 py_ret->mem_ctx = mem_ctx;
678 py_ret->dn = ret;
679 return (PyObject *)py_ret;
682 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
684 talloc_free(self->mem_ctx);
685 PyObject_Del(self);
688 static PyTypeObject PyLdbDn = {
689 .tp_name = "ldb.Dn",
690 .tp_methods = py_ldb_dn_methods,
691 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
692 .tp_repr = (reprfunc)py_ldb_dn_repr,
693 .tp_compare = (cmpfunc)py_ldb_dn_compare,
694 .tp_as_sequence = &py_ldb_dn_seq,
695 .tp_doc = "A LDB distinguished name.",
696 .tp_new = py_ldb_dn_new,
697 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
698 .tp_basicsize = sizeof(PyLdbDnObject),
699 .tp_flags = Py_TPFLAGS_DEFAULT,
702 /* Debug */
703 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
704 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
706 PyObject *fn = (PyObject *)context;
707 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
710 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
712 PyObject *cb;
713 struct ldb_context *ldb_ctx;
715 if (!PyArg_ParseTuple(args, "O", &cb))
716 return NULL;
718 Py_INCREF(cb);
719 /* FIXME: Where do we DECREF cb ? */
720 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
721 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
722 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
723 ldb_ctx);
725 Py_RETURN_NONE;
728 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
730 unsigned int perms;
731 if (!PyArg_ParseTuple(args, "I", &perms))
732 return NULL;
734 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
736 Py_RETURN_NONE;
739 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
741 char *modules_dir;
742 if (!PyArg_ParseTuple(args, "s", &modules_dir))
743 return NULL;
745 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
747 Py_RETURN_NONE;
750 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
752 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
753 int ldb_err;
754 ldb_err = ldb_transaction_start(ldb_ctx);
755 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
756 Py_RETURN_NONE;
759 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
761 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
762 int ldb_err;
763 ldb_err = ldb_transaction_commit(ldb_ctx);
764 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
765 Py_RETURN_NONE;
768 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
770 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
771 int ldb_err;
772 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
773 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
774 Py_RETURN_NONE;
777 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
779 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
780 int ldb_err;
781 ldb_err = ldb_transaction_cancel(ldb_ctx);
782 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
783 Py_RETURN_NONE;
786 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
788 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
789 int ldb_err;
790 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
791 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
792 Py_RETURN_NONE;
795 static PyObject *py_ldb_repr(PyLdbObject *self)
797 return PyString_FromFormat("<ldb connection>");
800 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
802 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
803 if (dn == NULL)
804 Py_RETURN_NONE;
805 return py_ldb_dn_copy(dn);
809 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
811 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
812 if (dn == NULL)
813 Py_RETURN_NONE;
814 return py_ldb_dn_copy(dn);
817 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
819 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
820 if (dn == NULL)
821 Py_RETURN_NONE;
822 return py_ldb_dn_copy(dn);
825 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
827 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
828 if (dn == NULL)
829 Py_RETURN_NONE;
830 return py_ldb_dn_copy(dn);
833 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
834 const char *paramname)
836 const char **ret;
837 Py_ssize_t i;
838 if (!PyList_Check(list)) {
839 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
840 return NULL;
842 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
843 if (ret == NULL) {
844 PyErr_NoMemory();
845 return NULL;
848 for (i = 0; i < PyList_Size(list); i++) {
849 PyObject *item = PyList_GetItem(list, i);
850 if (!PyString_Check(item)) {
851 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
852 return NULL;
854 ret[i] = talloc_strndup(ret, PyString_AsString(item),
855 PyString_Size(item));
857 ret[i] = NULL;
858 return ret;
861 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
863 const char * const kwnames[] = { "url", "flags", "options", NULL };
864 char *url = NULL;
865 PyObject *py_options = Py_None;
866 const char **options;
867 unsigned int flags = 0;
868 int ret;
869 struct ldb_context *ldb;
871 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
872 discard_const_p(char *, kwnames),
873 &url, &flags, &py_options))
874 return -1;
876 ldb = pyldb_Ldb_AsLdbContext(self);
878 if (py_options == Py_None) {
879 options = NULL;
880 } else {
881 options = PyList_AsStringList(ldb, py_options, "options");
882 if (options == NULL)
883 return -1;
886 if (url != NULL) {
887 ret = ldb_connect(ldb, url, flags, options);
888 if (ret != LDB_SUCCESS) {
889 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
890 return -1;
894 talloc_free(options);
895 return 0;
898 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
900 PyLdbObject *ret;
901 struct ldb_context *ldb;
902 ret = (PyLdbObject *)type->tp_alloc(type, 0);
903 if (ret == NULL) {
904 PyErr_NoMemory();
905 return NULL;
907 ret->mem_ctx = talloc_new(NULL);
908 ldb = ldb_init(ret->mem_ctx, NULL);
910 if (ldb == NULL) {
911 PyErr_NoMemory();
912 return NULL;
915 ret->ldb_ctx = ldb;
916 return (PyObject *)ret;
919 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
921 char *url;
922 unsigned int flags = 0;
923 PyObject *py_options = Py_None;
924 int ret;
925 const char **options;
926 const char * const kwnames[] = { "url", "flags", "options", NULL };
927 struct ldb_context *ldb_ctx;
929 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
930 discard_const_p(char *, kwnames),
931 &url, &flags, &py_options))
932 return NULL;
934 if (py_options == Py_None) {
935 options = NULL;
936 } else {
937 options = PyList_AsStringList(NULL, py_options, "options");
938 if (options == NULL)
939 return NULL;
942 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
943 ret = ldb_connect(ldb_ctx, url, flags, options);
944 talloc_free(options);
946 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
948 Py_RETURN_NONE;
951 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
953 PyObject *py_msg;
954 PyObject *py_controls = Py_None;
955 struct ldb_context *ldb_ctx;
956 struct ldb_request *req;
957 struct ldb_control **parsed_controls;
958 struct ldb_message *msg;
959 int ret;
960 TALLOC_CTX *mem_ctx;
961 bool validate=true;
962 const char * const kwnames[] = { "message", "controls", "validate", NULL };
964 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
965 discard_const_p(char *, kwnames),
966 &py_msg, &py_controls, &validate))
967 return NULL;
969 mem_ctx = talloc_new(NULL);
970 if (mem_ctx == NULL) {
971 PyErr_NoMemory();
972 return NULL;
974 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
976 if (py_controls == Py_None) {
977 parsed_controls = NULL;
978 } else {
979 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
980 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
981 talloc_free(controls);
984 if (!PyLdbMessage_Check(py_msg)) {
985 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
986 talloc_free(mem_ctx);
987 return NULL;
989 msg = pyldb_Message_AsMessage(py_msg);
991 if (validate) {
992 ret = ldb_msg_sanity_check(ldb_ctx, msg);
993 if (ret != LDB_SUCCESS) {
994 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
995 talloc_free(mem_ctx);
996 return NULL;
1000 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1001 NULL, ldb_op_default_callback, NULL);
1002 if (ret != LDB_SUCCESS) {
1003 PyErr_SetString(PyExc_TypeError, "failed to build request");
1004 talloc_free(mem_ctx);
1005 return NULL;
1008 /* do request and autostart a transaction */
1009 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1011 ret = ldb_transaction_start(ldb_ctx);
1012 if (ret != LDB_SUCCESS) {
1013 talloc_free(mem_ctx);
1014 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1015 return NULL;
1018 ret = ldb_request(ldb_ctx, req);
1019 if (ret == LDB_SUCCESS) {
1020 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1023 if (ret == LDB_SUCCESS) {
1024 ret = ldb_transaction_commit(ldb_ctx);
1025 } else {
1026 ldb_transaction_cancel(ldb_ctx);
1029 talloc_free(mem_ctx);
1030 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1032 Py_RETURN_NONE;
1037 * Obtain a ldb message from a Python Dictionary object.
1039 * @param mem_ctx Memory context
1040 * @param py_obj Python Dictionary object
1041 * @param ldb_ctx LDB context
1042 * @param mod_flags Flags to be set on every message element
1043 * @return ldb_message on success or NULL on failure
1045 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1046 PyObject *py_obj,
1047 struct ldb_context *ldb_ctx,
1048 unsigned int mod_flags)
1050 struct ldb_message *msg;
1051 unsigned int msg_pos = 0;
1052 Py_ssize_t dict_pos = 0;
1053 PyObject *key, *value;
1054 struct ldb_message_element *msg_el;
1055 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1057 msg = ldb_msg_new(mem_ctx);
1058 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1060 if (dn_value) {
1061 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1062 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1063 return NULL;
1065 if (msg->dn == NULL) {
1066 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1067 return NULL;
1069 } else {
1070 PyErr_SetString(PyExc_TypeError, "no dn set");
1071 return NULL;
1074 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1075 char *key_str = PyString_AsString(key);
1076 if (ldb_attr_cmp(key_str, "dn") != 0) {
1077 msg_el = PyObject_AsMessageElement(msg->elements, value,
1078 mod_flags, key_str);
1079 if (msg_el == NULL) {
1080 PyErr_SetString(PyExc_TypeError, "unable to import element");
1081 return NULL;
1083 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1084 msg_pos++;
1088 msg->num_elements = msg_pos;
1090 return msg;
1093 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1095 PyObject *py_obj;
1096 int ret;
1097 struct ldb_context *ldb_ctx;
1098 struct ldb_request *req;
1099 struct ldb_message *msg = NULL;
1100 PyObject *py_controls = Py_None;
1101 TALLOC_CTX *mem_ctx;
1102 struct ldb_control **parsed_controls;
1103 const char * const kwnames[] = { "message", "controls", NULL };
1105 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1106 discard_const_p(char *, kwnames),
1107 &py_obj, &py_controls))
1108 return NULL;
1110 mem_ctx = talloc_new(NULL);
1111 if (mem_ctx == NULL) {
1112 PyErr_NoMemory();
1113 return NULL;
1115 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1117 if (py_controls == Py_None) {
1118 parsed_controls = NULL;
1119 } else {
1120 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1121 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1122 talloc_free(controls);
1125 if (PyLdbMessage_Check(py_obj)) {
1126 msg = pyldb_Message_AsMessage(py_obj);
1127 } else if (PyDict_Check(py_obj)) {
1128 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1129 } else {
1130 PyErr_SetString(PyExc_TypeError,
1131 "Dictionary or LdbMessage object expected!");
1134 if (!msg) {
1135 /* we should have a PyErr already set */
1136 talloc_free(mem_ctx);
1137 return NULL;
1140 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1141 if (ret != LDB_SUCCESS) {
1142 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1143 talloc_free(mem_ctx);
1144 return NULL;
1147 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1148 NULL, ldb_op_default_callback, NULL);
1149 if (ret != LDB_SUCCESS) {
1150 PyErr_SetString(PyExc_TypeError, "failed to build request");
1151 talloc_free(mem_ctx);
1152 return NULL;
1155 /* do request and autostart a transaction */
1156 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1158 ret = ldb_transaction_start(ldb_ctx);
1159 if (ret != LDB_SUCCESS) {
1160 talloc_free(mem_ctx);
1161 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1162 return NULL;
1165 ret = ldb_request(ldb_ctx, req);
1166 if (ret == LDB_SUCCESS) {
1167 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1170 if (ret == LDB_SUCCESS) {
1171 ret = ldb_transaction_commit(ldb_ctx);
1172 } else {
1173 ldb_transaction_cancel(ldb_ctx);
1176 talloc_free(mem_ctx);
1177 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1179 Py_RETURN_NONE;
1182 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1184 PyObject *py_dn;
1185 struct ldb_dn *dn;
1186 int ret;
1187 struct ldb_context *ldb_ctx;
1188 struct ldb_request *req;
1189 PyObject *py_controls = Py_None;
1190 TALLOC_CTX *mem_ctx;
1191 struct ldb_control **parsed_controls;
1192 const char * const kwnames[] = { "dn", "controls", NULL };
1194 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1195 discard_const_p(char *, kwnames),
1196 &py_dn, &py_controls))
1197 return NULL;
1199 mem_ctx = talloc_new(NULL);
1200 if (mem_ctx == NULL) {
1201 PyErr_NoMemory();
1202 return NULL;
1204 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1206 if (py_controls == Py_None) {
1207 parsed_controls = NULL;
1208 } else {
1209 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1210 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1211 talloc_free(controls);
1214 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1215 talloc_free(mem_ctx);
1216 return NULL;
1219 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1220 NULL, ldb_op_default_callback, NULL);
1221 if (ret != LDB_SUCCESS) {
1222 PyErr_SetString(PyExc_TypeError, "failed to build request");
1223 talloc_free(mem_ctx);
1224 return NULL;
1227 /* do request and autostart a transaction */
1228 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1230 ret = ldb_transaction_start(ldb_ctx);
1231 if (ret != LDB_SUCCESS) {
1232 talloc_free(mem_ctx);
1233 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1234 return NULL;
1237 ret = ldb_request(ldb_ctx, req);
1238 if (ret == LDB_SUCCESS) {
1239 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1242 if (ret == LDB_SUCCESS) {
1243 ret = ldb_transaction_commit(ldb_ctx);
1244 } else {
1245 ldb_transaction_cancel(ldb_ctx);
1248 talloc_free(mem_ctx);
1249 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1251 Py_RETURN_NONE;
1254 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1256 PyObject *py_dn1, *py_dn2;
1257 struct ldb_dn *dn1, *dn2;
1258 int ret;
1259 TALLOC_CTX *mem_ctx;
1260 PyObject *py_controls = Py_None;
1261 struct ldb_control **parsed_controls;
1262 struct ldb_context *ldb_ctx;
1263 struct ldb_request *req;
1264 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1266 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1268 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1269 discard_const_p(char *, kwnames),
1270 &py_dn1, &py_dn2, &py_controls))
1271 return NULL;
1274 mem_ctx = talloc_new(NULL);
1275 if (mem_ctx == NULL) {
1276 PyErr_NoMemory();
1277 return NULL;
1280 if (py_controls == Py_None) {
1281 parsed_controls = NULL;
1282 } else {
1283 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1284 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1285 talloc_free(controls);
1289 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1290 talloc_free(mem_ctx);
1291 return NULL;
1294 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1295 talloc_free(mem_ctx);
1296 return NULL;
1299 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1300 NULL, ldb_op_default_callback, NULL);
1301 if (ret != LDB_SUCCESS) {
1302 PyErr_SetString(PyExc_TypeError, "failed to build request");
1303 talloc_free(mem_ctx);
1304 return NULL;
1307 /* do request and autostart a transaction */
1308 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1310 ret = ldb_transaction_start(ldb_ctx);
1311 if (ret != LDB_SUCCESS) {
1312 talloc_free(mem_ctx);
1313 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1314 return NULL;
1317 ret = ldb_request(ldb_ctx, req);
1318 if (ret == LDB_SUCCESS) {
1319 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1322 if (ret == LDB_SUCCESS) {
1323 ret = ldb_transaction_commit(ldb_ctx);
1324 } else {
1325 ldb_transaction_cancel(ldb_ctx);
1328 talloc_free(mem_ctx);
1329 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1331 Py_RETURN_NONE;
1334 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1336 char *name;
1337 if (!PyArg_ParseTuple(args, "s", &name))
1338 return NULL;
1340 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1342 Py_RETURN_NONE;
1345 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1347 char *attribute, *syntax;
1348 unsigned int flags;
1349 int ret;
1350 struct ldb_context *ldb_ctx;
1352 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1353 return NULL;
1355 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1356 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1358 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1360 Py_RETURN_NONE;
1363 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1365 if (ldif == NULL) {
1366 Py_RETURN_NONE;
1367 } else {
1368 /* We don't want this attached to the 'ldb' any more */
1369 return Py_BuildValue(discard_const_p(char, "(iO)"),
1370 ldif->changetype,
1371 PyLdbMessage_FromMessage(ldif->msg));
1376 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1378 int changetype;
1379 PyObject *py_msg;
1380 struct ldb_ldif ldif;
1381 PyObject *ret;
1382 char *string;
1383 TALLOC_CTX *mem_ctx;
1385 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1386 return NULL;
1388 if (!PyLdbMessage_Check(py_msg)) {
1389 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1390 return NULL;
1393 ldif.msg = pyldb_Message_AsMessage(py_msg);
1394 ldif.changetype = changetype;
1396 mem_ctx = talloc_new(NULL);
1398 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1399 if (!string) {
1400 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1401 return NULL;
1404 ret = PyString_FromString(string);
1406 talloc_free(mem_ctx);
1408 return ret;
1411 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1413 PyObject *list;
1414 struct ldb_ldif *ldif;
1415 const char *s;
1417 TALLOC_CTX *mem_ctx;
1419 if (!PyArg_ParseTuple(args, "s", &s))
1420 return NULL;
1422 mem_ctx = talloc_new(NULL);
1423 if (!mem_ctx) {
1424 Py_RETURN_NONE;
1427 list = PyList_New(0);
1428 while (s && *s != '\0') {
1429 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1430 talloc_steal(mem_ctx, ldif);
1431 if (ldif) {
1432 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1433 } else {
1434 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1435 talloc_free(mem_ctx);
1436 return NULL;
1439 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1440 return PyObject_GetIter(list);
1443 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1445 int ldb_ret;
1446 PyObject *py_msg_old;
1447 PyObject *py_msg_new;
1448 struct ldb_message *diff;
1449 struct ldb_context *ldb;
1450 PyObject *py_ret;
1452 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1453 return NULL;
1455 if (!PyLdbMessage_Check(py_msg_old)) {
1456 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1457 return NULL;
1460 if (!PyLdbMessage_Check(py_msg_new)) {
1461 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1462 return NULL;
1465 ldb = pyldb_Ldb_AsLdbContext(self);
1466 ldb_ret = ldb_msg_difference(ldb, ldb,
1467 pyldb_Message_AsMessage(py_msg_old),
1468 pyldb_Message_AsMessage(py_msg_new),
1469 &diff);
1470 if (ldb_ret != LDB_SUCCESS) {
1471 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1472 return NULL;
1475 py_ret = PyLdbMessage_FromMessage(diff);
1477 talloc_unlink(ldb, diff);
1479 return py_ret;
1482 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1484 const struct ldb_schema_attribute *a;
1485 struct ldb_val old_val;
1486 struct ldb_val new_val;
1487 TALLOC_CTX *mem_ctx;
1488 PyObject *ret;
1489 char *element_name;
1490 PyObject *val;
1492 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1493 return NULL;
1495 mem_ctx = talloc_new(NULL);
1497 old_val.data = (uint8_t *)PyString_AsString(val);
1498 old_val.length = PyString_Size(val);
1500 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1502 if (a == NULL) {
1503 Py_RETURN_NONE;
1506 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1507 talloc_free(mem_ctx);
1508 Py_RETURN_NONE;
1511 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1513 talloc_free(mem_ctx);
1515 return ret;
1518 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1520 PyObject *py_base = Py_None;
1521 int scope = LDB_SCOPE_DEFAULT;
1522 char *expr = NULL;
1523 PyObject *py_attrs = Py_None;
1524 PyObject *py_controls = Py_None;
1525 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1526 int ret;
1527 struct ldb_result *res;
1528 struct ldb_request *req;
1529 const char **attrs;
1530 struct ldb_context *ldb_ctx;
1531 struct ldb_control **parsed_controls;
1532 struct ldb_dn *base;
1533 PyObject *py_ret;
1534 TALLOC_CTX *mem_ctx;
1536 /* type "int" rather than "enum" for "scope" is intentional */
1537 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1538 discard_const_p(char *, kwnames),
1539 &py_base, &scope, &expr, &py_attrs, &py_controls))
1540 return NULL;
1543 mem_ctx = talloc_new(NULL);
1544 if (mem_ctx == NULL) {
1545 PyErr_NoMemory();
1546 return NULL;
1548 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1550 if (py_attrs == Py_None) {
1551 attrs = NULL;
1552 } else {
1553 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1554 if (attrs == NULL) {
1555 talloc_free(mem_ctx);
1556 return NULL;
1560 if (py_base == Py_None) {
1561 base = ldb_get_default_basedn(ldb_ctx);
1562 } else {
1563 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1564 talloc_free(attrs);
1565 return NULL;
1569 if (py_controls == Py_None) {
1570 parsed_controls = NULL;
1571 } else {
1572 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1573 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1574 talloc_free(controls);
1577 res = talloc_zero(mem_ctx, struct ldb_result);
1578 if (res == NULL) {
1579 PyErr_NoMemory();
1580 talloc_free(mem_ctx);
1581 return NULL;
1584 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1585 base,
1586 scope,
1587 expr,
1588 attrs,
1589 parsed_controls,
1590 res,
1591 ldb_search_default_callback,
1592 NULL);
1594 if (ret != LDB_SUCCESS) {
1595 talloc_free(mem_ctx);
1596 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1597 return NULL;
1600 talloc_steal(req, attrs);
1602 ret = ldb_request(ldb_ctx, req);
1604 if (ret == LDB_SUCCESS) {
1605 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1608 if (ret != LDB_SUCCESS) {
1609 talloc_free(mem_ctx);
1610 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1611 return NULL;
1614 py_ret = PyLdbResult_FromResult(res);
1616 talloc_free(mem_ctx);
1618 return py_ret;
1621 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1623 char *name;
1624 void *data;
1626 if (!PyArg_ParseTuple(args, "s", &name))
1627 return NULL;
1629 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1631 if (data == NULL)
1632 Py_RETURN_NONE;
1634 /* FIXME: More interpretation */
1636 return Py_True;
1639 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1641 char *name;
1642 PyObject *data;
1644 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1645 return NULL;
1647 /* FIXME: More interpretation */
1649 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1651 Py_RETURN_NONE;
1654 static PyObject *py_ldb_modules(PyLdbObject *self)
1656 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1657 PyObject *ret = PyList_New(0);
1658 struct ldb_module *mod;
1660 for (mod = ldb->modules; mod; mod = mod->next) {
1661 PyList_Append(ret, PyLdbModule_FromModule(mod));
1664 return ret;
1667 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1669 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1670 int type, ret;
1671 uint64_t value;
1673 if (!PyArg_ParseTuple(args, "i", &type))
1674 return NULL;
1676 /* FIXME: More interpretation */
1678 ret = ldb_sequence_number(ldb, type, &value);
1680 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1682 return PyLong_FromLongLong(value);
1684 static PyMethodDef py_ldb_methods[] = {
1685 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1686 "S.set_debug(callback) -> None\n"
1687 "Set callback for LDB debug messages.\n"
1688 "The callback should accept a debug level and debug text." },
1689 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1690 "S.set_create_perms(mode) -> None\n"
1691 "Set mode to use when creating new LDB files." },
1692 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1693 "S.set_modules_dir(path) -> None\n"
1694 "Set path LDB should search for modules" },
1695 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1696 "S.transaction_start() -> None\n"
1697 "Start a new transaction." },
1698 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1699 "S.transaction_prepare_commit() -> None\n"
1700 "prepare to commit a new transaction (2-stage commit)." },
1701 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1702 "S.transaction_commit() -> None\n"
1703 "commit a new transaction." },
1704 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1705 "S.transaction_cancel() -> None\n"
1706 "cancel a new transaction." },
1707 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1708 NULL },
1709 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1710 NULL },
1711 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1712 NULL },
1713 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1714 NULL },
1715 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1716 NULL },
1717 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1718 "S.connect(url, flags=0, options=None) -> None\n"
1719 "Connect to a LDB URL." },
1720 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1721 "S.modify(message, controls=None, validate=False) -> None\n"
1722 "Modify an entry." },
1723 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1724 "S.add(message, controls=None) -> None\n"
1725 "Add an entry." },
1726 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1727 "S.delete(dn, controls=None) -> None\n"
1728 "Remove an entry." },
1729 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1730 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1731 "Rename an entry." },
1732 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1733 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1734 "Search in a database.\n"
1735 "\n"
1736 ":param base: Optional base DN to search\n"
1737 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1738 ":param expression: Optional search expression\n"
1739 ":param attrs: Attributes to return (defaults to all)\n"
1740 ":param controls: Optional list of controls\n"
1741 ":return: Iterator over Message objects\n"
1743 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1744 NULL },
1745 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1746 NULL },
1747 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1748 NULL },
1749 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1750 "S.parse_ldif(ldif) -> iter(messages)\n"
1751 "Parse a string formatted using LDIF." },
1752 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1753 "S.write_ldif(message, changetype) -> ldif\n"
1754 "Print the message as a string formatted using LDIF." },
1755 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1756 "S.msg_diff(Message) -> Message\n"
1757 "Return an LDB Message of the difference between two Message objects." },
1758 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1759 "S.get_opaque(name) -> value\n"
1760 "Get an opaque value set on this LDB connection. \n"
1761 ":note: The returned value may not be useful in Python."
1763 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1764 "S.set_opaque(name, value) -> None\n"
1765 "Set an opaque value on this LDB connection. \n"
1766 ":note: Passing incorrect values may cause crashes." },
1767 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1768 "S.modules() -> list\n"
1769 "Return the list of modules on this LDB connection " },
1770 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1771 "S.sequence_number(type) -> value\n"
1772 "Return the value of the sequence according to the requested type" },
1773 { NULL },
1776 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1778 PyLdbModuleObject *ret;
1780 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1781 if (ret == NULL) {
1782 PyErr_NoMemory();
1783 return NULL;
1785 ret->mem_ctx = talloc_new(NULL);
1786 ret->mod = talloc_reference(ret->mem_ctx, mod);
1787 return (PyObject *)ret;
1790 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1792 return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1795 static PyGetSetDef py_ldb_getset[] = {
1796 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1797 { NULL }
1800 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1802 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1803 struct ldb_dn *dn;
1804 struct ldb_result *result;
1805 unsigned int count;
1806 int ret;
1808 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1809 return -1;
1812 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1813 NULL);
1814 if (ret != LDB_SUCCESS) {
1815 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1816 return -1;
1819 count = result->count;
1821 talloc_free(result);
1823 if (count > 1) {
1824 PyErr_Format(PyExc_RuntimeError,
1825 "Searching for [%s] dn gave %u results!",
1826 ldb_dn_get_linearized(dn),
1827 count);
1828 return -1;
1831 return count;
1834 static PySequenceMethods py_ldb_seq = {
1835 .sq_contains = (objobjproc)py_ldb_contains,
1838 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1840 PyLdbObject *ret;
1842 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1843 if (ret == NULL) {
1844 PyErr_NoMemory();
1845 return NULL;
1847 ret->mem_ctx = talloc_new(NULL);
1848 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1849 return (PyObject *)ret;
1852 static void py_ldb_dealloc(PyLdbObject *self)
1854 talloc_free(self->mem_ctx);
1855 self->ob_type->tp_free(self);
1858 static PyTypeObject PyLdb = {
1859 .tp_name = "ldb.Ldb",
1860 .tp_methods = py_ldb_methods,
1861 .tp_repr = (reprfunc)py_ldb_repr,
1862 .tp_new = py_ldb_new,
1863 .tp_init = (initproc)py_ldb_init,
1864 .tp_dealloc = (destructor)py_ldb_dealloc,
1865 .tp_getset = py_ldb_getset,
1866 .tp_getattro = PyObject_GenericGetAttr,
1867 .tp_basicsize = sizeof(PyLdbObject),
1868 .tp_doc = "Connection to a LDB database.",
1869 .tp_as_sequence = &py_ldb_seq,
1870 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1873 static void py_ldb_result_dealloc(PyLdbResultObject *self)
1875 talloc_free(self->mem_ctx);
1876 Py_DECREF(self->msgs);
1877 Py_DECREF(self->referals);
1878 Py_DECREF(self->controls);
1879 self->ob_type->tp_free(self);
1882 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
1884 Py_INCREF(self->msgs);
1885 return self->msgs;
1888 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
1890 Py_INCREF(self->controls);
1891 return self->controls;
1894 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
1896 Py_INCREF(self->referals);
1897 return self->referals;
1900 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
1902 Py_ssize_t size;
1903 if (self->msgs == NULL) {
1904 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
1905 return NULL;
1907 size = PyList_Size(self->msgs);
1908 return PyInt_FromLong(size);
1911 static PyGetSetDef py_ldb_result_getset[] = {
1912 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
1913 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
1914 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
1915 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
1916 { NULL }
1919 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
1921 return PyObject_GetIter(self->msgs);
1924 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
1926 return PySequence_Size(self->msgs);
1929 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
1931 return PySequence_GetItem(self->msgs, idx);
1934 static PySequenceMethods py_ldb_result_seq = {
1935 .sq_length = (lenfunc)py_ldb_result_len,
1936 .sq_item = (ssizeargfunc)py_ldb_result_find,
1939 static PyObject *py_ldb_result_repr(PyLdbObject *self)
1941 return PyString_FromFormat("<ldb result>");
1945 static PyTypeObject PyLdbResult = {
1946 .tp_name = "ldb.Result",
1947 .tp_repr = (reprfunc)py_ldb_result_repr,
1948 .tp_dealloc = (destructor)py_ldb_result_dealloc,
1949 .tp_iter = (getiterfunc)py_ldb_result_iter,
1950 .tp_getset = py_ldb_result_getset,
1951 .tp_getattro = PyObject_GenericGetAttr,
1952 .tp_basicsize = sizeof(PyLdbResultObject),
1953 .tp_as_sequence = &py_ldb_result_seq,
1954 .tp_doc = "LDB result.",
1955 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1958 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1960 return PyString_FromFormat("<ldb module '%s'>",
1961 pyldb_Module_AsModule(self)->ops->name);
1964 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1966 return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
1969 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1971 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
1972 Py_RETURN_NONE;
1975 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1977 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
1978 Py_RETURN_NONE;
1981 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
1983 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
1984 Py_RETURN_NONE;
1987 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
1989 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
1990 int ret, scope;
1991 struct ldb_request *req;
1992 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
1993 struct ldb_module *mod;
1994 const char * const*attrs;
1996 /* type "int" rather than "enum" for "scope" is intentional */
1997 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
1998 discard_const_p(char *, kwnames),
1999 &py_base, &scope, &py_tree, &py_attrs))
2000 return NULL;
2002 mod = self->mod;
2004 if (py_attrs == Py_None) {
2005 attrs = NULL;
2006 } else {
2007 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
2008 if (attrs == NULL)
2009 return NULL;
2012 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2013 scope, NULL /* expr */, attrs,
2014 NULL /* controls */, NULL, NULL, NULL);
2016 talloc_steal(req, attrs);
2018 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2020 req->op.search.res = NULL;
2022 ret = mod->ops->search(mod, req);
2024 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2026 py_ret = PyLdbResult_FromResult(req->op.search.res);
2028 talloc_free(req);
2030 return py_ret;
2034 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2036 struct ldb_request *req;
2037 PyObject *py_message;
2038 int ret;
2039 struct ldb_module *mod;
2041 if (!PyArg_ParseTuple(args, "O", &py_message))
2042 return NULL;
2044 req = talloc_zero(NULL, struct ldb_request);
2045 req->operation = LDB_ADD;
2046 req->op.add.message = pyldb_Message_AsMessage(py_message);
2048 mod = pyldb_Module_AsModule(self);
2049 ret = mod->ops->add(mod, req);
2051 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2053 Py_RETURN_NONE;
2056 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2058 int ret;
2059 struct ldb_request *req;
2060 PyObject *py_message;
2061 struct ldb_module *mod;
2063 if (!PyArg_ParseTuple(args, "O", &py_message))
2064 return NULL;
2066 req = talloc_zero(NULL, struct ldb_request);
2067 req->operation = LDB_MODIFY;
2068 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2070 mod = pyldb_Module_AsModule(self);
2071 ret = mod->ops->modify(mod, req);
2073 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2075 Py_RETURN_NONE;
2078 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2080 int ret;
2081 struct ldb_request *req;
2082 PyObject *py_dn;
2084 if (!PyArg_ParseTuple(args, "O", &py_dn))
2085 return NULL;
2087 req = talloc_zero(NULL, struct ldb_request);
2088 req->operation = LDB_DELETE;
2089 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2091 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2093 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2095 Py_RETURN_NONE;
2098 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2100 int ret;
2101 struct ldb_request *req;
2102 PyObject *py_dn1, *py_dn2;
2104 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
2105 return NULL;
2107 req = talloc_zero(NULL, struct ldb_request);
2109 req->operation = LDB_RENAME;
2110 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2111 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2113 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2115 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2117 Py_RETURN_NONE;
2120 static PyMethodDef py_ldb_module_methods[] = {
2121 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2122 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2123 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2124 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2125 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2126 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2127 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2128 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2129 { NULL },
2132 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2134 talloc_free(self->mem_ctx);
2135 PyObject_Del(self);
2138 static PyTypeObject PyLdbModule = {
2139 .tp_name = "ldb.LdbModule",
2140 .tp_methods = py_ldb_module_methods,
2141 .tp_repr = (reprfunc)py_ldb_module_repr,
2142 .tp_str = (reprfunc)py_ldb_module_str,
2143 .tp_basicsize = sizeof(PyLdbModuleObject),
2144 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2145 .tp_flags = Py_TPFLAGS_DEFAULT,
2146 .tp_doc = "LDB module (extension)",
2151 * Create a ldb_message_element from a Python object.
2153 * This will accept any sequence objects that contains strings, or
2154 * a string object.
2156 * A reference to set_obj will be borrowed.
2158 * @param mem_ctx Memory context
2159 * @param set_obj Python object to convert
2160 * @param flags ldb_message_element flags to set
2161 * @param attr_name Name of the attribute
2162 * @return New ldb_message_element, allocated as child of mem_ctx
2164 static struct ldb_message_element *PyObject_AsMessageElement(
2165 TALLOC_CTX *mem_ctx,
2166 PyObject *set_obj,
2167 unsigned int flags,
2168 const char *attr_name)
2170 struct ldb_message_element *me;
2172 if (pyldb_MessageElement_Check(set_obj)) {
2173 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2174 /* We have to talloc_reference() the memory context, not the pointer
2175 * which may not actually be it's own context */
2176 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2177 return pyldb_MessageElement_AsMessageElement(set_obj);
2179 return NULL;
2182 me = talloc(mem_ctx, struct ldb_message_element);
2183 if (me == NULL) {
2184 PyErr_NoMemory();
2185 return NULL;
2188 me->name = talloc_strdup(me, attr_name);
2189 me->flags = flags;
2190 if (PyString_Check(set_obj)) {
2191 me->num_values = 1;
2192 me->values = talloc_array(me, struct ldb_val, me->num_values);
2193 me->values[0].length = PyString_Size(set_obj);
2194 me->values[0].data = talloc_memdup(me,
2195 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2196 } else if (PySequence_Check(set_obj)) {
2197 Py_ssize_t i;
2198 me->num_values = PySequence_Size(set_obj);
2199 me->values = talloc_array(me, struct ldb_val, me->num_values);
2200 for (i = 0; i < me->num_values; i++) {
2201 PyObject *obj = PySequence_GetItem(set_obj, i);
2202 if (!PyString_Check(obj)) {
2203 PyErr_Format(PyExc_TypeError,
2204 "Expected string as element %zd in list", i);
2205 talloc_free(me);
2206 return NULL;
2209 me->values[i].length = PyString_Size(obj);
2210 me->values[i].data = talloc_memdup(me,
2211 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2213 } else {
2214 talloc_free(me);
2215 me = NULL;
2218 return me;
2222 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2223 struct ldb_message_element *me)
2225 Py_ssize_t i;
2226 PyObject *result;
2228 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2229 result = PyList_New(me->num_values);
2231 for (i = 0; i < me->num_values; i++) {
2232 PyList_SetItem(result, i,
2233 PyObject_FromLdbValue(&me->values[i]));
2236 return result;
2239 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2241 unsigned int i;
2242 if (!PyArg_ParseTuple(args, "I", &i))
2243 return NULL;
2244 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2245 Py_RETURN_NONE;
2247 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2250 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2252 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2253 return PyInt_FromLong(el->flags);
2256 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2258 unsigned int flags;
2259 struct ldb_message_element *el;
2260 if (!PyArg_ParseTuple(args, "I", &flags))
2261 return NULL;
2263 el = pyldb_MessageElement_AsMessageElement(self);
2264 el->flags = flags;
2265 Py_RETURN_NONE;
2268 static PyMethodDef py_ldb_msg_element_methods[] = {
2269 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2270 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2271 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2272 { NULL },
2275 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2277 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2280 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2282 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2283 if (idx < 0 || idx >= el->num_values) {
2284 PyErr_SetString(PyExc_IndexError, "Out of range");
2285 return NULL;
2287 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2290 static PySequenceMethods py_ldb_msg_element_seq = {
2291 .sq_length = (lenfunc)py_ldb_msg_element_len,
2292 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2295 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2297 int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2298 pyldb_MessageElement_AsMessageElement(other));
2299 return SIGN(ret);
2302 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2304 PyObject *el = ldb_msg_element_to_set(NULL,
2305 pyldb_MessageElement_AsMessageElement(self));
2306 return PyObject_GetIter(el);
2309 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2311 PyLdbMessageElementObject *ret;
2312 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2313 if (ret == NULL) {
2314 PyErr_NoMemory();
2315 return NULL;
2317 ret->mem_ctx = talloc_new(NULL);
2318 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2319 PyErr_NoMemory();
2320 return NULL;
2322 ret->el = el;
2323 return (PyObject *)ret;
2326 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2328 PyObject *py_elements = NULL;
2329 struct ldb_message_element *el;
2330 unsigned int flags = 0;
2331 char *name = NULL;
2332 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2333 PyLdbMessageElementObject *ret;
2334 TALLOC_CTX *mem_ctx;
2336 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2337 discard_const_p(char *, kwnames),
2338 &py_elements, &flags, &name))
2339 return NULL;
2341 mem_ctx = talloc_new(NULL);
2342 if (mem_ctx == NULL) {
2343 PyErr_NoMemory();
2344 return NULL;
2347 el = talloc_zero(mem_ctx, struct ldb_message_element);
2348 if (el == NULL) {
2349 PyErr_NoMemory();
2350 talloc_free(mem_ctx);
2351 return NULL;
2354 if (py_elements != NULL) {
2355 Py_ssize_t i;
2356 if (PyString_Check(py_elements)) {
2357 el->num_values = 1;
2358 el->values = talloc_array(el, struct ldb_val, 1);
2359 if (el->values == NULL) {
2360 talloc_free(mem_ctx);
2361 PyErr_NoMemory();
2362 return NULL;
2364 el->values[0].length = PyString_Size(py_elements);
2365 el->values[0].data = talloc_memdup(el->values,
2366 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2367 } else if (PySequence_Check(py_elements)) {
2368 el->num_values = PySequence_Size(py_elements);
2369 el->values = talloc_array(el, struct ldb_val, el->num_values);
2370 if (el->values == NULL) {
2371 talloc_free(mem_ctx);
2372 PyErr_NoMemory();
2373 return NULL;
2375 for (i = 0; i < el->num_values; i++) {
2376 PyObject *item = PySequence_GetItem(py_elements, i);
2377 if (item == NULL) {
2378 talloc_free(mem_ctx);
2379 return NULL;
2381 if (!PyString_Check(item)) {
2382 PyErr_Format(PyExc_TypeError,
2383 "Expected string as element %zd in list", i);
2384 talloc_free(mem_ctx);
2385 return NULL;
2387 el->values[i].length = PyString_Size(item);
2388 el->values[i].data = talloc_memdup(el,
2389 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2391 } else {
2392 PyErr_SetString(PyExc_TypeError,
2393 "Expected string or list");
2394 talloc_free(mem_ctx);
2395 return NULL;
2399 el->flags = flags;
2400 el->name = talloc_strdup(el, name);
2402 ret = PyObject_New(PyLdbMessageElementObject, type);
2403 if (ret == NULL) {
2404 talloc_free(mem_ctx);
2405 return NULL;
2408 ret->mem_ctx = mem_ctx;
2409 ret->el = el;
2410 return (PyObject *)ret;
2413 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2415 char *element_str = NULL;
2416 Py_ssize_t i;
2417 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2418 PyObject *ret;
2420 for (i = 0; i < el->num_values; i++) {
2421 PyObject *o = py_ldb_msg_element_find(self, i);
2422 if (element_str == NULL)
2423 element_str = talloc_strdup(NULL, PyObject_REPR(o));
2424 else
2425 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2428 if (element_str != NULL) {
2429 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2430 talloc_free(element_str);
2431 } else {
2432 ret = PyString_FromString("MessageElement([])");
2435 return ret;
2438 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2440 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2442 if (el->num_values == 1)
2443 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2444 else
2445 Py_RETURN_NONE;
2448 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2450 talloc_free(self->mem_ctx);
2451 PyObject_Del(self);
2454 static PyTypeObject PyLdbMessageElement = {
2455 .tp_name = "ldb.MessageElement",
2456 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2457 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2458 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2459 .tp_str = (reprfunc)py_ldb_msg_element_str,
2460 .tp_methods = py_ldb_msg_element_methods,
2461 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2462 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2463 .tp_as_sequence = &py_ldb_msg_element_seq,
2464 .tp_new = py_ldb_msg_element_new,
2465 .tp_flags = Py_TPFLAGS_DEFAULT,
2466 .tp_doc = "An element of a Message",
2470 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2472 PyObject *py_ldb;
2473 PyObject *py_dict;
2474 PyObject *py_ret;
2475 struct ldb_message *msg;
2476 struct ldb_context *ldb_ctx;
2477 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2479 if (!PyArg_ParseTuple(args, "O!O!|I",
2480 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2481 &mod_flags)) {
2482 return NULL;
2485 /* mask only flags we are going to use */
2486 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2487 if (!mod_flags) {
2488 PyErr_SetString(PyExc_ValueError,
2489 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2490 " expected as mod_flag value");
2491 return NULL;
2494 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2496 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2497 if (!msg) {
2498 return NULL;
2501 py_ret = PyLdbMessage_FromMessage(msg);
2503 talloc_unlink(ldb_ctx, msg);
2505 return py_ret;
2508 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2510 char *name;
2511 if (!PyArg_ParseTuple(args, "s", &name))
2512 return NULL;
2514 ldb_msg_remove_attr(self->msg, name);
2516 Py_RETURN_NONE;
2519 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2521 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2522 Py_ssize_t i, j = 0;
2523 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2524 if (msg->dn != NULL) {
2525 PyList_SetItem(obj, j, PyString_FromString("dn"));
2526 j++;
2528 for (i = 0; i < msg->num_elements; i++) {
2529 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2530 j++;
2532 return obj;
2535 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2537 struct ldb_message_element *el;
2538 char *name;
2539 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2540 if (!PyString_Check(py_name)) {
2541 PyErr_SetNone(PyExc_TypeError);
2542 return NULL;
2544 name = PyString_AsString(py_name);
2545 if (!ldb_attr_cmp(name, "dn"))
2546 return pyldb_Dn_FromDn(msg->dn);
2547 el = ldb_msg_find_element(msg, name);
2548 if (el == NULL) {
2549 return NULL;
2551 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2554 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2556 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2557 if (ret == NULL) {
2558 PyErr_SetString(PyExc_KeyError, "No such element");
2559 return NULL;
2561 return ret;
2564 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2566 PyObject *def = NULL;
2567 const char *kwnames[] = { "name", "default", "idx", NULL };
2568 const char *name = NULL;
2569 int idx = -1;
2570 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2571 struct ldb_message_element *el;
2573 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2574 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2575 return NULL;
2578 if (strcasecmp(name, "dn") == 0) {
2579 return pyldb_Dn_FromDn(msg->dn);
2582 el = ldb_msg_find_element(msg, name);
2584 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2585 if (def != NULL) {
2586 return def;
2588 Py_RETURN_NONE;
2591 if (idx == -1) {
2592 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2595 return PyObject_FromLdbValue(&el->values[idx]);
2598 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2600 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2601 Py_ssize_t i, j = 0;
2602 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2603 if (msg->dn != NULL) {
2604 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2605 j++;
2607 for (i = 0; i < msg->num_elements; i++, j++) {
2608 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2609 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2610 PyList_SetItem(l, j, value);
2612 return l;
2615 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2617 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2618 Py_ssize_t i = 0;
2619 PyObject *l = PyList_New(msg->num_elements);
2620 for (i = 0; i < msg->num_elements; i++) {
2621 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2623 return l;
2626 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2628 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2629 PyLdbMessageElementObject *py_element;
2630 int ret;
2631 struct ldb_message_element *el;
2633 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2634 return NULL;
2636 el = talloc_reference(msg, py_element->el);
2637 if (el == NULL) {
2638 PyErr_NoMemory();
2639 return NULL;
2642 ret = ldb_msg_add(msg, el, el->flags);
2643 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2645 Py_RETURN_NONE;
2648 static PyMethodDef py_ldb_msg_methods[] = {
2649 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2650 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2651 "Class method to create ldb.Message object from Dictionary.\n"
2652 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2653 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2654 "S.keys() -> list\n\n"
2655 "Return sequence of all attribute names." },
2656 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2657 "S.remove(name)\n\n"
2658 "Remove all entries for attributes with the specified name."},
2659 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2660 "msg.get(name,default=None,idx=None) -> string\n"
2661 "idx is the index into the values array\n"
2662 "if idx is None, then a list is returned\n"
2663 "if idx is not None, then the element with that index is returned\n"
2664 "if you pass the special name 'dn' then the DN object is returned\n"},
2665 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2666 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2667 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2668 "S.append(element)\n\n"
2669 "Add an element to this message." },
2670 { NULL },
2673 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2675 PyObject *list, *iter;
2677 list = py_ldb_msg_keys(self);
2678 iter = PyObject_GetIter(list);
2679 Py_DECREF(list);
2680 return iter;
2683 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2685 char *attr_name;
2687 if (!PyString_Check(name)) {
2688 PyErr_SetNone(PyExc_TypeError);
2689 return -1;
2692 attr_name = PyString_AsString(name);
2693 if (value == NULL) {
2694 /* delitem */
2695 ldb_msg_remove_attr(self->msg, attr_name);
2696 } else {
2697 int ret;
2698 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2699 value, 0, attr_name);
2700 if (el == NULL)
2701 return -1;
2702 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2703 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2704 if (ret != LDB_SUCCESS) {
2705 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
2706 return -1;
2709 return 0;
2712 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2714 return pyldb_Message_AsMessage(self)->num_elements;
2717 static PyMappingMethods py_ldb_msg_mapping = {
2718 .mp_length = (lenfunc)py_ldb_msg_length,
2719 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2720 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2723 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2725 const char * const kwnames[] = { "dn", NULL };
2726 struct ldb_message *ret;
2727 TALLOC_CTX *mem_ctx;
2728 PyObject *pydn = NULL;
2729 PyLdbMessageObject *py_ret;
2731 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2732 discard_const_p(char *, kwnames),
2733 &pydn))
2734 return NULL;
2736 mem_ctx = talloc_new(NULL);
2737 if (mem_ctx == NULL) {
2738 PyErr_NoMemory();
2739 return NULL;
2742 ret = ldb_msg_new(mem_ctx);
2743 if (ret == NULL) {
2744 talloc_free(mem_ctx);
2745 PyErr_NoMemory();
2746 return NULL;
2749 if (pydn != NULL) {
2750 struct ldb_dn *dn;
2751 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2752 talloc_free(mem_ctx);
2753 return NULL;
2755 ret->dn = talloc_reference(ret, dn);
2758 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2759 if (py_ret == NULL) {
2760 PyErr_NoMemory();
2761 talloc_free(mem_ctx);
2762 return NULL;
2765 py_ret->mem_ctx = mem_ctx;
2766 py_ret->msg = ret;
2767 return (PyObject *)py_ret;
2770 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2772 PyLdbMessageObject *ret;
2774 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2775 if (ret == NULL) {
2776 PyErr_NoMemory();
2777 return NULL;
2779 ret->mem_ctx = talloc_new(NULL);
2780 ret->msg = talloc_reference(ret->mem_ctx, msg);
2781 return (PyObject *)ret;
2784 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2786 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2787 return pyldb_Dn_FromDn(msg->dn);
2790 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2792 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2793 if (!pyldb_Dn_Check(value)) {
2794 PyErr_SetNone(PyExc_TypeError);
2795 return -1;
2798 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2799 return 0;
2802 static PyGetSetDef py_ldb_msg_getset[] = {
2803 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2804 { NULL }
2807 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2809 PyObject *dict = PyDict_New(), *ret;
2810 if (PyDict_Update(dict, (PyObject *)self) != 0)
2811 return NULL;
2812 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2813 Py_DECREF(dict);
2814 return ret;
2817 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2819 talloc_free(self->mem_ctx);
2820 PyObject_Del(self);
2823 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2824 PyLdbMessageObject *py_msg2)
2826 struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
2827 *msg2 = pyldb_Message_AsMessage(py_msg2);
2828 unsigned int i;
2829 int ret;
2831 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2832 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2833 if (ret != 0) {
2834 return SIGN(ret);
2838 ret = msg1->num_elements - msg2->num_elements;
2839 if (ret != 0) {
2840 return SIGN(ret);
2843 for (i = 0; i < msg1->num_elements; i++) {
2844 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2845 &msg2->elements[i]);
2846 if (ret != 0) {
2847 return SIGN(ret);
2850 ret = ldb_msg_element_compare(&msg1->elements[i],
2851 &msg2->elements[i]);
2852 if (ret != 0) {
2853 return SIGN(ret);
2857 return 0;
2860 static PyTypeObject PyLdbMessage = {
2861 .tp_name = "ldb.Message",
2862 .tp_methods = py_ldb_msg_methods,
2863 .tp_getset = py_ldb_msg_getset,
2864 .tp_as_mapping = &py_ldb_msg_mapping,
2865 .tp_basicsize = sizeof(PyLdbMessageObject),
2866 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2867 .tp_new = py_ldb_msg_new,
2868 .tp_repr = (reprfunc)py_ldb_msg_repr,
2869 .tp_flags = Py_TPFLAGS_DEFAULT,
2870 .tp_iter = (getiterfunc)py_ldb_msg_iter,
2871 .tp_compare = (cmpfunc)py_ldb_msg_compare,
2872 .tp_doc = "A LDB Message",
2875 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2877 PyLdbTreeObject *ret;
2879 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2880 if (ret == NULL) {
2881 PyErr_NoMemory();
2882 return NULL;
2885 ret->mem_ctx = talloc_new(NULL);
2886 ret->tree = talloc_reference(ret->mem_ctx, tree);
2887 return (PyObject *)ret;
2890 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2892 talloc_free(self->mem_ctx);
2893 PyObject_Del(self);
2896 static PyTypeObject PyLdbTree = {
2897 .tp_name = "ldb.Tree",
2898 .tp_basicsize = sizeof(PyLdbTreeObject),
2899 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2900 .tp_flags = Py_TPFLAGS_DEFAULT,
2901 .tp_doc = "A search tree",
2904 /* Ldb_module */
2905 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2907 PyObject *py_ldb = (PyObject *)mod->private_data;
2908 PyObject *py_result, *py_base, *py_attrs, *py_tree;
2910 py_base = pyldb_Dn_FromDn(req->op.search.base);
2912 if (py_base == NULL)
2913 return LDB_ERR_OPERATIONS_ERROR;
2915 py_tree = PyLdbTree_FromTree(req->op.search.tree);
2917 if (py_tree == NULL)
2918 return LDB_ERR_OPERATIONS_ERROR;
2920 if (req->op.search.attrs == NULL) {
2921 py_attrs = Py_None;
2922 } else {
2923 int i, len;
2924 for (len = 0; req->op.search.attrs[len]; len++);
2925 py_attrs = PyList_New(len);
2926 for (i = 0; i < len; i++)
2927 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2930 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2931 discard_const_p(char, "OiOO"),
2932 py_base, req->op.search.scope, py_tree, py_attrs);
2934 Py_DECREF(py_attrs);
2935 Py_DECREF(py_tree);
2936 Py_DECREF(py_base);
2938 if (py_result == NULL) {
2939 return LDB_ERR_PYTHON_EXCEPTION;
2942 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2943 if (req->op.search.res == NULL) {
2944 return LDB_ERR_PYTHON_EXCEPTION;
2947 Py_DECREF(py_result);
2949 return LDB_SUCCESS;
2952 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2954 PyObject *py_ldb = (PyObject *)mod->private_data;
2955 PyObject *py_result, *py_msg;
2957 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2959 if (py_msg == NULL) {
2960 return LDB_ERR_OPERATIONS_ERROR;
2963 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2964 discard_const_p(char, "O"),
2965 py_msg);
2967 Py_DECREF(py_msg);
2969 if (py_result == NULL) {
2970 return LDB_ERR_PYTHON_EXCEPTION;
2973 Py_DECREF(py_result);
2975 return LDB_SUCCESS;
2978 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
2980 PyObject *py_ldb = (PyObject *)mod->private_data;
2981 PyObject *py_result, *py_msg;
2983 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
2985 if (py_msg == NULL) {
2986 return LDB_ERR_OPERATIONS_ERROR;
2989 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
2990 discard_const_p(char, "O"),
2991 py_msg);
2993 Py_DECREF(py_msg);
2995 if (py_result == NULL) {
2996 return LDB_ERR_PYTHON_EXCEPTION;
2999 Py_DECREF(py_result);
3001 return LDB_SUCCESS;
3004 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3006 PyObject *py_ldb = (PyObject *)mod->private_data;
3007 PyObject *py_result, *py_dn;
3009 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3011 if (py_dn == NULL)
3012 return LDB_ERR_OPERATIONS_ERROR;
3014 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3015 discard_const_p(char, "O"),
3016 py_dn);
3018 if (py_result == NULL) {
3019 return LDB_ERR_PYTHON_EXCEPTION;
3022 Py_DECREF(py_result);
3024 return LDB_SUCCESS;
3027 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3029 PyObject *py_ldb = (PyObject *)mod->private_data;
3030 PyObject *py_result, *py_olddn, *py_newdn;
3032 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3034 if (py_olddn == NULL)
3035 return LDB_ERR_OPERATIONS_ERROR;
3037 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3039 if (py_newdn == NULL)
3040 return LDB_ERR_OPERATIONS_ERROR;
3042 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3043 discard_const_p(char, "OO"),
3044 py_olddn, py_newdn);
3046 Py_DECREF(py_olddn);
3047 Py_DECREF(py_newdn);
3049 if (py_result == NULL) {
3050 return LDB_ERR_PYTHON_EXCEPTION;
3053 Py_DECREF(py_result);
3055 return LDB_SUCCESS;
3058 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3060 PyObject *py_ldb = (PyObject *)mod->private_data;
3061 PyObject *py_result;
3063 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3064 discard_const_p(char, ""));
3066 return LDB_ERR_OPERATIONS_ERROR;
3069 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3071 PyObject *py_ldb = (PyObject *)mod->private_data;
3072 PyObject *py_result;
3074 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3075 discard_const_p(char, ""));
3077 return LDB_ERR_OPERATIONS_ERROR;
3080 static int py_module_start_transaction(struct ldb_module *mod)
3082 PyObject *py_ldb = (PyObject *)mod->private_data;
3083 PyObject *py_result;
3085 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3086 discard_const_p(char, ""));
3088 if (py_result == NULL) {
3089 return LDB_ERR_PYTHON_EXCEPTION;
3092 Py_DECREF(py_result);
3094 return LDB_SUCCESS;
3097 static int py_module_end_transaction(struct ldb_module *mod)
3099 PyObject *py_ldb = (PyObject *)mod->private_data;
3100 PyObject *py_result;
3102 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3103 discard_const_p(char, ""));
3105 if (py_result == NULL) {
3106 return LDB_ERR_PYTHON_EXCEPTION;
3109 Py_DECREF(py_result);
3111 return LDB_SUCCESS;
3114 static int py_module_del_transaction(struct ldb_module *mod)
3116 PyObject *py_ldb = (PyObject *)mod->private_data;
3117 PyObject *py_result;
3119 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3120 discard_const_p(char, ""));
3122 if (py_result == NULL) {
3123 return LDB_ERR_PYTHON_EXCEPTION;
3126 Py_DECREF(py_result);
3128 return LDB_SUCCESS;
3131 static int py_module_destructor(struct ldb_module *mod)
3133 Py_DECREF((PyObject *)mod->private_data);
3134 return 0;
3137 static int py_module_init(struct ldb_module *mod)
3139 PyObject *py_class = (PyObject *)mod->ops->private_data;
3140 PyObject *py_result, *py_next, *py_ldb;
3142 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3144 if (py_ldb == NULL)
3145 return LDB_ERR_OPERATIONS_ERROR;
3147 py_next = PyLdbModule_FromModule(mod->next);
3149 if (py_next == NULL)
3150 return LDB_ERR_OPERATIONS_ERROR;
3152 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3153 py_ldb, py_next);
3155 if (py_result == NULL) {
3156 return LDB_ERR_PYTHON_EXCEPTION;
3159 mod->private_data = py_result;
3161 talloc_set_destructor(mod, py_module_destructor);
3163 return ldb_next_init(mod);
3166 static PyObject *py_register_module(PyObject *module, PyObject *args)
3168 int ret;
3169 struct ldb_module_ops *ops;
3170 PyObject *input;
3172 if (!PyArg_ParseTuple(args, "O", &input))
3173 return NULL;
3175 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3176 if (ops == NULL) {
3177 PyErr_NoMemory();
3178 return NULL;
3181 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3183 Py_INCREF(input);
3184 ops->private_data = input;
3185 ops->init_context = py_module_init;
3186 ops->search = py_module_search;
3187 ops->add = py_module_add;
3188 ops->modify = py_module_modify;
3189 ops->del = py_module_del;
3190 ops->rename = py_module_rename;
3191 ops->request = py_module_request;
3192 ops->extended = py_module_extended;
3193 ops->start_transaction = py_module_start_transaction;
3194 ops->end_transaction = py_module_end_transaction;
3195 ops->del_transaction = py_module_del_transaction;
3197 ret = ldb_register_module(ops);
3199 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3201 Py_RETURN_NONE;
3204 static PyObject *py_timestring(PyObject *module, PyObject *args)
3206 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3207 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3208 long int t_val;
3209 char *tresult;
3210 PyObject *ret;
3211 if (!PyArg_ParseTuple(args, "l", &t_val))
3212 return NULL;
3213 tresult = ldb_timestring(NULL, (time_t) t_val);
3214 ret = PyString_FromString(tresult);
3215 talloc_free(tresult);
3216 return ret;
3219 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3221 char *str;
3222 if (!PyArg_ParseTuple(args, "s", &str))
3223 return NULL;
3225 return PyInt_FromLong(ldb_string_to_time(str));
3228 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3230 char *name;
3231 if (!PyArg_ParseTuple(args, "s", &name))
3232 return NULL;
3233 return PyBool_FromLong(ldb_valid_attr_name(name));
3237 encode a string using RFC2254 rules
3239 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3241 char *str, *encoded;
3242 int size = 0;
3243 struct ldb_val val;
3244 PyObject *ret;
3246 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3247 return NULL;
3248 val.data = (uint8_t *)str;
3249 val.length = size;
3251 encoded = ldb_binary_encode(NULL, val);
3252 if (encoded == NULL) {
3253 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3254 return NULL;
3256 ret = PyString_FromString(encoded);
3257 talloc_free(encoded);
3258 return ret;
3262 decode a string using RFC2254 rules
3264 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3266 char *str;
3267 struct ldb_val val;
3268 PyObject *ret;
3270 if (!PyArg_ParseTuple(args, "s", &str))
3271 return NULL;
3273 val = ldb_binary_decode(NULL, str);
3274 if (val.data == NULL) {
3275 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3276 return NULL;
3278 ret = Py_BuildValue("s#", val.data, val.length);
3279 talloc_free(val.data);
3280 return ret;
3283 static PyMethodDef py_ldb_global_methods[] = {
3284 { "register_module", py_register_module, METH_VARARGS,
3285 "S.register_module(module) -> None\n\n"
3286 "Register a LDB module."},
3287 { "timestring", py_timestring, METH_VARARGS,
3288 "S.timestring(int) -> string\n\n"
3289 "Generate a LDAP time string from a UNIX timestamp" },
3290 { "string_to_time", py_string_to_time, METH_VARARGS,
3291 "S.string_to_time(string) -> int\n\n"
3292 "Parse a LDAP time string into a UNIX timestamp." },
3293 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3294 "S.valid_attr_name(name) -> bool\n\nn"
3295 "Check whether the supplied name is a valid attribute name." },
3296 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3297 "S.open() -> Ldb\n\n"
3298 "Open a new LDB context." },
3299 { "binary_encode", py_binary_encode, METH_VARARGS,
3300 "S.binary_encode(string) -> string\n\n"
3301 "Perform a RFC2254 binary encoding on a string" },
3302 { "binary_decode", py_binary_decode, METH_VARARGS,
3303 "S.binary_decode(string) -> string\n\n"
3304 "Perform a RFC2254 binary decode on a string" },
3305 { NULL }
3308 void initldb(void)
3310 PyObject *m;
3312 if (PyType_Ready(&PyLdbDn) < 0)
3313 return;
3315 if (PyType_Ready(&PyLdbMessage) < 0)
3316 return;
3318 if (PyType_Ready(&PyLdbMessageElement) < 0)
3319 return;
3321 if (PyType_Ready(&PyLdb) < 0)
3322 return;
3324 if (PyType_Ready(&PyLdbModule) < 0)
3325 return;
3327 if (PyType_Ready(&PyLdbTree) < 0)
3328 return;
3330 if (PyType_Ready(&PyLdbResult) < 0)
3331 return;
3333 if (PyType_Ready(&PyLdbControl) < 0)
3334 return;
3336 m = Py_InitModule3("ldb", py_ldb_global_methods,
3337 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3338 if (m == NULL)
3339 return;
3341 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3342 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3343 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3344 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3345 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3346 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3347 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3349 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3350 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3351 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3352 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3354 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3355 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3356 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3358 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3359 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3360 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3361 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3362 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3363 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3364 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3365 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3366 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3367 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3368 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3369 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3370 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3371 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3372 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3373 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3374 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3375 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3376 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3377 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3378 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3379 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3380 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3381 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3382 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3383 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3384 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3385 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3386 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3387 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3388 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3389 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3390 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3391 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3392 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3393 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3394 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3395 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3396 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3398 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3399 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3400 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3401 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3403 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3405 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3406 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3408 Py_INCREF(&PyLdb);
3409 Py_INCREF(&PyLdbDn);
3410 Py_INCREF(&PyLdbModule);
3411 Py_INCREF(&PyLdbMessage);
3412 Py_INCREF(&PyLdbMessageElement);
3413 Py_INCREF(&PyLdbTree);
3414 Py_INCREF(&PyLdbResult);
3415 Py_INCREF(&PyLdbControl);
3417 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3418 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3419 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3420 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3421 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3422 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3423 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3425 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3427 #define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3429 ADD_LDB_STRING(SYNTAX_DN);
3430 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3431 ADD_LDB_STRING(SYNTAX_INTEGER);
3432 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3433 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3434 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3435 ADD_LDB_STRING(OID_COMPARATOR_AND);
3436 ADD_LDB_STRING(OID_COMPARATOR_OR);