pyldb: DECREF old debug function when resetting it
[Samba.git] / lib / ldb / pyldb.c
blob5010f80c7a448dfca2c3c2ccbdf06cdce35d2f02
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 static PyTypeObject PyLdbControl;
40 static PyTypeObject PyLdbResult;
41 static PyTypeObject PyLdbMessage;
42 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
43 static PyTypeObject PyLdbModule;
44 static PyTypeObject PyLdbDn;
45 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
46 static PyTypeObject PyLdb;
47 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
48 static PyTypeObject PyLdbMessageElement;
49 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
51 static 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 #define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
71 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
73 if (self->data != NULL) {
74 char* control = ldb_control_to_string(self->mem_ctx, self->data);
75 if (control == NULL) {
76 PyErr_NoMemory();
77 return NULL;
79 return PyString_FromString(control);
80 } else {
81 return PyString_FromFormat("ldb control");
85 static void py_ldb_control_dealloc(PyLdbControlObject *self)
87 if (self->mem_ctx != NULL) {
88 talloc_free(self->mem_ctx);
90 self->data = NULL;
91 Py_TYPE(self)->tp_free(self);
94 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
96 return PyString_FromString(self->data->oid);
99 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
101 return PyBool_FromLong(self->data->critical);
104 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
106 if (PyObject_IsTrue(value)) {
107 self->data->critical = true;
108 } else {
109 self->data->critical = false;
111 return 0;
114 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
116 char *data = NULL;
117 const char * const kwnames[] = { "ldb", "data", NULL };
118 struct ldb_control *parsed_controls;
119 PyLdbControlObject *ret;
120 PyObject *py_ldb;
121 TALLOC_CTX *mem_ctx;
122 struct ldb_context *ldb_ctx;
124 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
125 discard_const_p(char *, kwnames),
126 &PyLdb, &py_ldb, &data))
127 return NULL;
129 mem_ctx = talloc_new(NULL);
130 if (mem_ctx == NULL) {
131 PyErr_NoMemory();
132 return NULL;
135 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
136 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
138 if (!parsed_controls) {
139 talloc_free(mem_ctx);
140 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
141 return NULL;
144 ret = PyObject_New(PyLdbControlObject, type);
145 if (ret == NULL) {
146 PyErr_NoMemory();
147 talloc_free(mem_ctx);
148 return NULL;
151 ret->mem_ctx = mem_ctx;
153 ret->data = talloc_move(mem_ctx, &parsed_controls);
154 if (ret->data == NULL) {
155 Py_DECREF(ret);
156 PyErr_NoMemory();
157 talloc_free(mem_ctx);
158 return NULL;
161 return (PyObject *)ret;
164 static PyGetSetDef py_ldb_control_getset[] = {
165 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
166 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
167 { NULL }
170 static PyTypeObject PyLdbControl = {
171 .tp_name = "ldb.control",
172 .tp_dealloc = (destructor)py_ldb_control_dealloc,
173 .tp_getattro = PyObject_GenericGetAttr,
174 .tp_basicsize = sizeof(PyLdbControlObject),
175 .tp_getset = py_ldb_control_getset,
176 .tp_doc = "LDB control.",
177 .tp_str = (reprfunc)py_ldb_control_str,
178 .tp_new = py_ldb_control_new,
179 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
182 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
184 if (ret == LDB_ERR_PYTHON_EXCEPTION)
185 return; /* Python exception should already be set, just keep that */
187 PyErr_SetObject(error,
188 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
189 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
192 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
194 return PyString_FromStringAndSize((const char *)val->data, val->length);
198 * Create a Python object from a ldb_result.
200 * @param result LDB result to convert
201 * @return Python object with converted result (a list object)
203 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
205 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
206 PyLdbControlObject *ctrl;
207 if (ctl_ctx == NULL) {
208 PyErr_NoMemory();
209 return NULL;
212 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
213 if (ctrl == NULL) {
214 talloc_free(ctl_ctx);
215 PyErr_NoMemory();
216 return NULL;
218 ctrl->mem_ctx = ctl_ctx;
219 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
220 if (ctrl->data == NULL) {
221 Py_DECREF(ctrl);
222 PyErr_NoMemory();
223 return NULL;
225 return (PyObject*) ctrl;
229 * Create a Python object from a ldb_result.
231 * @param result LDB result to convert
232 * @return Python object with converted result (a list object)
234 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
236 PyLdbResultObject *ret;
237 PyObject *list, *controls, *referals;
238 Py_ssize_t i;
240 if (result == NULL) {
241 Py_RETURN_NONE;
244 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
245 if (ret == NULL) {
246 PyErr_NoMemory();
247 return NULL;
250 list = PyList_New(result->count);
251 if (list == NULL) {
252 PyErr_NoMemory();
253 Py_DECREF(ret);
254 return NULL;
257 for (i = 0; i < result->count; i++) {
258 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
261 ret->mem_ctx = talloc_new(NULL);
262 if (ret->mem_ctx == NULL) {
263 Py_DECREF(list);
264 Py_DECREF(ret);
265 PyErr_NoMemory();
266 return NULL;
269 ret->msgs = list;
271 if (result->controls) {
272 i = 0;
273 while (result->controls[i]) {
274 i++;
276 controls = PyList_New(i);
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 PyBool_FromLong(ldb_dn_check_special(self->dn, name));
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 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
502 PyObject *py_other;
503 struct ldb_dn *dn, *other;
504 if (!PyArg_ParseTuple(args, "O", &py_other))
505 return NULL;
507 dn = pyldb_Dn_AsDn((PyObject *)self);
509 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
510 return NULL;
512 return PyBool_FromLong(ldb_dn_add_child(dn, other));
515 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
517 PyObject *py_other;
518 struct ldb_dn *other, *dn;
519 if (!PyArg_ParseTuple(args, "O", &py_other))
520 return NULL;
522 dn = pyldb_Dn_AsDn((PyObject *)self);
524 if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
525 return NULL;
527 return PyBool_FromLong(ldb_dn_add_base(dn, other));
530 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
532 struct ldb_dn *dn;
533 int i;
534 if (!PyArg_ParseTuple(args, "i", &i))
535 return NULL;
537 dn = pyldb_Dn_AsDn((PyObject *)self);
539 return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
542 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
544 PyObject *py_base;
545 struct ldb_dn *dn, *base;
546 if (!PyArg_ParseTuple(args, "O", &py_base))
547 return NULL;
549 dn = pyldb_Dn_AsDn((PyObject *)self);
551 if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
552 return NULL;
554 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
557 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
559 struct ldb_dn *dn;
560 const char *name;
561 unsigned int num = 0;
563 if (!PyArg_ParseTuple(args, "I", &num))
564 return NULL;
566 dn = pyldb_Dn_AsDn((PyObject *)self);
568 name = ldb_dn_get_component_name(dn, num);
569 if (name == NULL) {
570 Py_RETURN_NONE;
573 return PyString_FromString(name);
576 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
578 struct ldb_dn *dn;
579 const struct ldb_val *val;
580 unsigned int num = 0;
582 if (!PyArg_ParseTuple(args, "I", &num))
583 return NULL;
585 dn = pyldb_Dn_AsDn((PyObject *)self);
587 val = ldb_dn_get_component_val(dn, num);
588 if (val == NULL) {
589 Py_RETURN_NONE;
592 return PyObject_FromLdbValue(val);
595 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
597 unsigned int num = 0;
598 char *name = NULL;
599 PyObject *value = Py_None;
600 struct ldb_val val = { NULL, };
601 int err;
603 if (!PyArg_ParseTuple(args, "IsO", &num, &name, &value))
604 return NULL;
606 if (value != Py_None) {
607 if (!PyString_Check(value)) {
608 PyErr_SetString(PyExc_TypeError, "Expected a string argument");
609 return NULL;
611 val.data = (uint8_t *)PyString_AsString(value);
612 val.length = PyString_Size(value);
615 err = ldb_dn_set_component(self->dn, num, name, val);
616 if (err != LDB_SUCCESS) {
617 PyErr_SetString(PyExc_TypeError, "Failed to set component");
618 return NULL;
621 Py_RETURN_NONE;
624 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
626 struct ldb_dn *dn;
627 const char *name;
629 dn = pyldb_Dn_AsDn((PyObject *)self);
631 name = ldb_dn_get_rdn_name(dn);
632 if (name == NULL) {
633 Py_RETURN_NONE;
636 return PyString_FromString(name);
639 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
641 struct ldb_dn *dn;
642 const struct ldb_val *val;
644 dn = pyldb_Dn_AsDn((PyObject *)self);
646 val = ldb_dn_get_rdn_val(dn);
647 if (val == NULL) {
648 Py_RETURN_NONE;
651 return PyObject_FromLdbValue(val);
654 static PyMethodDef py_ldb_dn_methods[] = {
655 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
656 "S.validate() -> bool\n"
657 "Validate DN is correct." },
658 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
659 "S.is_valid() -> bool\n" },
660 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
661 "S.is_special() -> bool\n"
662 "Check whether this is a special LDB DN." },
663 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
664 "Check whether this is a null DN." },
665 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
666 NULL },
667 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
668 NULL },
669 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
670 "S.canonical_str() -> string\n"
671 "Canonical version of this DN (like a posix path)." },
672 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
673 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
674 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
675 "S.canonical_ex_str() -> string\n"
676 "Canonical version of this DN (like a posix path, with terminating newline)." },
677 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
678 "S.extended_str(mode=1) -> string\n"
679 "Extended version of this DN" },
680 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
681 "S.parent() -> dn\n"
682 "Get the parent for this DN." },
683 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
684 "S.add_child(dn) -> None\n"
685 "Add a child DN to this DN." },
686 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
687 "S.add_base(dn) -> None\n"
688 "Add a base DN to this DN." },
689 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
690 "S.remove_base_components(int) -> bool\n"
691 "Remove a number of DN components from the base of this DN." },
692 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
693 "S.check_special(name) -> bool\n\n"
694 "Check if name is a special DN name"},
695 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
696 "S.get_extended_component(name) -> string\n\n"
697 "returns a DN extended component as a binary string"},
698 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
699 "S.set_extended_component(name, value) -> None\n\n"
700 "set a DN extended component as a binary string"},
701 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
702 "S.get_component_name(num) -> string\n"
703 "get the attribute name of the specified component" },
704 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
705 "S.get_component_value(num) -> string\n"
706 "get the attribute value of the specified component as a binary string" },
707 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
708 "S.get_component_value(num, name, value) -> None\n"
709 "set the attribute name and value of the specified component" },
710 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
711 "S.get_rdn_name() -> string\n"
712 "get the RDN attribute name" },
713 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
714 "S.get_rdn_value() -> string\n"
715 "get the RDN attribute value as a binary string" },
716 { NULL }
719 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
721 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
725 copy a DN as a python object
727 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
729 PyLdbDnObject *py_ret;
731 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
732 if (py_ret == NULL) {
733 PyErr_NoMemory();
734 return NULL;
736 py_ret->mem_ctx = talloc_new(NULL);
737 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
738 return (PyObject *)py_ret;
741 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
743 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
744 *other;
745 PyLdbDnObject *py_ret;
747 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
748 return NULL;
750 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
751 if (py_ret == NULL) {
752 PyErr_NoMemory();
753 return NULL;
755 py_ret->mem_ctx = talloc_new(NULL);
756 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
757 ldb_dn_add_base(py_ret->dn, other);
758 return (PyObject *)py_ret;
761 static PySequenceMethods py_ldb_dn_seq = {
762 .sq_length = (lenfunc)py_ldb_dn_len,
763 .sq_concat = (binaryfunc)py_ldb_dn_concat,
766 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
768 struct ldb_dn *ret;
769 char *str;
770 PyObject *py_ldb;
771 struct ldb_context *ldb_ctx;
772 TALLOC_CTX *mem_ctx;
773 PyLdbDnObject *py_ret;
774 const char * const kwnames[] = { "ldb", "dn", NULL };
776 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
777 discard_const_p(char *, kwnames),
778 &py_ldb, &str))
779 return NULL;
781 if (!PyLdb_Check(py_ldb)) {
782 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
783 return NULL;
786 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
788 mem_ctx = talloc_new(NULL);
789 if (mem_ctx == NULL) {
790 PyErr_NoMemory();
791 return NULL;
794 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
795 if (!ldb_dn_validate(ret)) {
796 talloc_free(mem_ctx);
797 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
798 return NULL;
801 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
802 if (ret == NULL) {
803 talloc_free(mem_ctx);
804 PyErr_NoMemory();
805 return NULL;
807 py_ret->mem_ctx = mem_ctx;
808 py_ret->dn = ret;
809 return (PyObject *)py_ret;
812 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
814 talloc_free(self->mem_ctx);
815 PyObject_Del(self);
818 static PyTypeObject PyLdbDn = {
819 .tp_name = "ldb.Dn",
820 .tp_methods = py_ldb_dn_methods,
821 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
822 .tp_repr = (reprfunc)py_ldb_dn_repr,
823 .tp_compare = (cmpfunc)py_ldb_dn_compare,
824 .tp_as_sequence = &py_ldb_dn_seq,
825 .tp_doc = "A LDB distinguished name.",
826 .tp_new = py_ldb_dn_new,
827 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
828 .tp_basicsize = sizeof(PyLdbDnObject),
829 .tp_flags = Py_TPFLAGS_DEFAULT,
832 /* Debug */
833 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
834 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
836 PyObject *fn = (PyObject *)context;
837 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
840 static PyObject *py_ldb_debug_func;
842 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
844 PyObject *cb;
845 struct ldb_context *ldb_ctx;
847 if (!PyArg_ParseTuple(args, "O", &cb))
848 return NULL;
850 if (py_ldb_debug_func != NULL) {
851 Py_DECREF(py_ldb_debug_func);
854 Py_INCREF(cb);
855 /* FIXME: DECREF cb when exiting program */
856 py_ldb_debug_func = cb;
857 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
858 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
859 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
860 ldb_ctx);
862 Py_RETURN_NONE;
865 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
867 unsigned int perms;
868 if (!PyArg_ParseTuple(args, "I", &perms))
869 return NULL;
871 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
873 Py_RETURN_NONE;
876 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
878 char *modules_dir;
879 if (!PyArg_ParseTuple(args, "s", &modules_dir))
880 return NULL;
882 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
884 Py_RETURN_NONE;
887 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
889 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
890 int ldb_err;
891 ldb_err = ldb_transaction_start(ldb_ctx);
892 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
893 Py_RETURN_NONE;
896 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
898 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
899 int ldb_err;
900 ldb_err = ldb_transaction_commit(ldb_ctx);
901 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
902 Py_RETURN_NONE;
905 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
907 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
908 int ldb_err;
909 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
910 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
911 Py_RETURN_NONE;
914 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
916 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
917 int ldb_err;
918 ldb_err = ldb_transaction_cancel(ldb_ctx);
919 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
920 Py_RETURN_NONE;
923 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
925 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
926 int ldb_err;
927 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
928 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
929 Py_RETURN_NONE;
932 static PyObject *py_ldb_repr(PyLdbObject *self)
934 return PyString_FromFormat("<ldb connection>");
937 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
939 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
940 if (dn == NULL)
941 Py_RETURN_NONE;
942 return py_ldb_dn_copy(dn);
946 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
948 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
949 if (dn == NULL)
950 Py_RETURN_NONE;
951 return py_ldb_dn_copy(dn);
954 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
956 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
957 if (dn == NULL)
958 Py_RETURN_NONE;
959 return py_ldb_dn_copy(dn);
962 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
964 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
965 if (dn == NULL)
966 Py_RETURN_NONE;
967 return py_ldb_dn_copy(dn);
970 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
971 const char *paramname)
973 const char **ret;
974 Py_ssize_t i;
975 if (!PyList_Check(list)) {
976 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
977 return NULL;
979 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
980 if (ret == NULL) {
981 PyErr_NoMemory();
982 return NULL;
985 for (i = 0; i < PyList_Size(list); i++) {
986 PyObject *item = PyList_GetItem(list, i);
987 if (!PyString_Check(item)) {
988 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
989 return NULL;
991 ret[i] = talloc_strndup(ret, PyString_AsString(item),
992 PyString_Size(item));
994 ret[i] = NULL;
995 return ret;
998 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1000 const char * const kwnames[] = { "url", "flags", "options", NULL };
1001 char *url = NULL;
1002 PyObject *py_options = Py_None;
1003 const char **options;
1004 unsigned int flags = 0;
1005 int ret;
1006 struct ldb_context *ldb;
1008 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1009 discard_const_p(char *, kwnames),
1010 &url, &flags, &py_options))
1011 return -1;
1013 ldb = pyldb_Ldb_AsLdbContext(self);
1015 if (py_options == Py_None) {
1016 options = NULL;
1017 } else {
1018 options = PyList_AsStringList(ldb, py_options, "options");
1019 if (options == NULL)
1020 return -1;
1023 if (url != NULL) {
1024 ret = ldb_connect(ldb, url, flags, options);
1025 if (ret != LDB_SUCCESS) {
1026 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1027 return -1;
1031 talloc_free(options);
1032 return 0;
1035 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1037 PyLdbObject *ret;
1038 struct ldb_context *ldb;
1039 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1040 if (ret == NULL) {
1041 PyErr_NoMemory();
1042 return NULL;
1044 ret->mem_ctx = talloc_new(NULL);
1045 ldb = ldb_init(ret->mem_ctx, NULL);
1047 if (ldb == NULL) {
1048 PyErr_NoMemory();
1049 return NULL;
1052 ret->ldb_ctx = ldb;
1053 return (PyObject *)ret;
1056 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1058 char *url;
1059 unsigned int flags = 0;
1060 PyObject *py_options = Py_None;
1061 int ret;
1062 const char **options;
1063 const char * const kwnames[] = { "url", "flags", "options", NULL };
1064 struct ldb_context *ldb_ctx;
1066 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
1067 discard_const_p(char *, kwnames),
1068 &url, &flags, &py_options))
1069 return NULL;
1071 if (py_options == Py_None) {
1072 options = NULL;
1073 } else {
1074 options = PyList_AsStringList(NULL, py_options, "options");
1075 if (options == NULL)
1076 return NULL;
1079 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1080 ret = ldb_connect(ldb_ctx, url, flags, options);
1081 talloc_free(options);
1083 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1085 Py_RETURN_NONE;
1088 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1090 PyObject *py_msg;
1091 PyObject *py_controls = Py_None;
1092 struct ldb_context *ldb_ctx;
1093 struct ldb_request *req;
1094 struct ldb_control **parsed_controls;
1095 struct ldb_message *msg;
1096 int ret;
1097 TALLOC_CTX *mem_ctx;
1098 bool validate=true;
1099 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1101 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1102 discard_const_p(char *, kwnames),
1103 &py_msg, &py_controls, &validate))
1104 return NULL;
1106 mem_ctx = talloc_new(NULL);
1107 if (mem_ctx == NULL) {
1108 PyErr_NoMemory();
1109 return NULL;
1111 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1113 if (py_controls == Py_None) {
1114 parsed_controls = NULL;
1115 } else {
1116 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1117 if (controls == NULL) {
1118 talloc_free(mem_ctx);
1119 return NULL;
1121 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1122 talloc_free(controls);
1125 if (!PyLdbMessage_Check(py_msg)) {
1126 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1127 talloc_free(mem_ctx);
1128 return NULL;
1130 msg = pyldb_Message_AsMessage(py_msg);
1132 if (validate) {
1133 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1134 if (ret != LDB_SUCCESS) {
1135 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1136 talloc_free(mem_ctx);
1137 return NULL;
1141 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1142 NULL, ldb_op_default_callback, NULL);
1143 if (ret != LDB_SUCCESS) {
1144 PyErr_SetString(PyExc_TypeError, "failed to build request");
1145 talloc_free(mem_ctx);
1146 return NULL;
1149 /* do request and autostart a transaction */
1150 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1152 ret = ldb_transaction_start(ldb_ctx);
1153 if (ret != LDB_SUCCESS) {
1154 talloc_free(mem_ctx);
1155 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1156 return NULL;
1159 ret = ldb_request(ldb_ctx, req);
1160 if (ret == LDB_SUCCESS) {
1161 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1164 if (ret == LDB_SUCCESS) {
1165 ret = ldb_transaction_commit(ldb_ctx);
1166 } else {
1167 ldb_transaction_cancel(ldb_ctx);
1170 talloc_free(mem_ctx);
1171 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1173 Py_RETURN_NONE;
1178 * Obtain a ldb message from a Python Dictionary object.
1180 * @param mem_ctx Memory context
1181 * @param py_obj Python Dictionary object
1182 * @param ldb_ctx LDB context
1183 * @param mod_flags Flags to be set on every message element
1184 * @return ldb_message on success or NULL on failure
1186 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1187 PyObject *py_obj,
1188 struct ldb_context *ldb_ctx,
1189 unsigned int mod_flags)
1191 struct ldb_message *msg;
1192 unsigned int msg_pos = 0;
1193 Py_ssize_t dict_pos = 0;
1194 PyObject *key, *value;
1195 struct ldb_message_element *msg_el;
1196 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1198 msg = ldb_msg_new(mem_ctx);
1199 if (msg == NULL) {
1200 PyErr_NoMemory();
1201 return NULL;
1203 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1205 if (dn_value) {
1206 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1207 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1208 return NULL;
1210 if (msg->dn == NULL) {
1211 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1212 return NULL;
1214 } else {
1215 PyErr_SetString(PyExc_TypeError, "no dn set");
1216 return NULL;
1219 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1220 char *key_str = PyString_AsString(key);
1221 if (ldb_attr_cmp(key_str, "dn") != 0) {
1222 msg_el = PyObject_AsMessageElement(msg->elements, value,
1223 mod_flags, key_str);
1224 if (msg_el == NULL) {
1225 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1226 return NULL;
1228 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1229 msg_pos++;
1233 msg->num_elements = msg_pos;
1235 return msg;
1238 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1240 PyObject *py_obj;
1241 int ret;
1242 struct ldb_context *ldb_ctx;
1243 struct ldb_request *req;
1244 struct ldb_message *msg = NULL;
1245 PyObject *py_controls = Py_None;
1246 TALLOC_CTX *mem_ctx;
1247 struct ldb_control **parsed_controls;
1248 const char * const kwnames[] = { "message", "controls", NULL };
1250 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1251 discard_const_p(char *, kwnames),
1252 &py_obj, &py_controls))
1253 return NULL;
1255 mem_ctx = talloc_new(NULL);
1256 if (mem_ctx == NULL) {
1257 PyErr_NoMemory();
1258 return NULL;
1260 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1262 if (py_controls == Py_None) {
1263 parsed_controls = NULL;
1264 } else {
1265 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1266 if (controls == NULL) {
1267 talloc_free(mem_ctx);
1268 return NULL;
1270 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1271 talloc_free(controls);
1274 if (PyLdbMessage_Check(py_obj)) {
1275 msg = pyldb_Message_AsMessage(py_obj);
1276 } else if (PyDict_Check(py_obj)) {
1277 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1278 } else {
1279 PyErr_SetString(PyExc_TypeError,
1280 "Dictionary or LdbMessage object expected!");
1283 if (!msg) {
1284 /* we should have a PyErr already set */
1285 talloc_free(mem_ctx);
1286 return NULL;
1289 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1290 if (ret != LDB_SUCCESS) {
1291 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1292 talloc_free(mem_ctx);
1293 return NULL;
1296 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1297 NULL, ldb_op_default_callback, NULL);
1298 if (ret != LDB_SUCCESS) {
1299 PyErr_SetString(PyExc_TypeError, "failed to build request");
1300 talloc_free(mem_ctx);
1301 return NULL;
1304 /* do request and autostart a transaction */
1305 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1307 ret = ldb_transaction_start(ldb_ctx);
1308 if (ret != LDB_SUCCESS) {
1309 talloc_free(mem_ctx);
1310 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1311 return NULL;
1314 ret = ldb_request(ldb_ctx, req);
1315 if (ret == LDB_SUCCESS) {
1316 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1319 if (ret == LDB_SUCCESS) {
1320 ret = ldb_transaction_commit(ldb_ctx);
1321 } else {
1322 ldb_transaction_cancel(ldb_ctx);
1325 talloc_free(mem_ctx);
1326 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1328 Py_RETURN_NONE;
1331 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1333 PyObject *py_dn;
1334 struct ldb_dn *dn;
1335 int ret;
1336 struct ldb_context *ldb_ctx;
1337 struct ldb_request *req;
1338 PyObject *py_controls = Py_None;
1339 TALLOC_CTX *mem_ctx;
1340 struct ldb_control **parsed_controls;
1341 const char * const kwnames[] = { "dn", "controls", NULL };
1343 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1344 discard_const_p(char *, kwnames),
1345 &py_dn, &py_controls))
1346 return NULL;
1348 mem_ctx = talloc_new(NULL);
1349 if (mem_ctx == NULL) {
1350 PyErr_NoMemory();
1351 return NULL;
1353 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1355 if (py_controls == Py_None) {
1356 parsed_controls = NULL;
1357 } else {
1358 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1359 if (controls == NULL) {
1360 talloc_free(mem_ctx);
1361 return NULL;
1363 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1364 talloc_free(controls);
1367 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1368 talloc_free(mem_ctx);
1369 return NULL;
1372 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1373 NULL, ldb_op_default_callback, NULL);
1374 if (ret != LDB_SUCCESS) {
1375 PyErr_SetString(PyExc_TypeError, "failed to build request");
1376 talloc_free(mem_ctx);
1377 return NULL;
1380 /* do request and autostart a transaction */
1381 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1383 ret = ldb_transaction_start(ldb_ctx);
1384 if (ret != LDB_SUCCESS) {
1385 talloc_free(mem_ctx);
1386 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1387 return NULL;
1390 ret = ldb_request(ldb_ctx, req);
1391 if (ret == LDB_SUCCESS) {
1392 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1395 if (ret == LDB_SUCCESS) {
1396 ret = ldb_transaction_commit(ldb_ctx);
1397 } else {
1398 ldb_transaction_cancel(ldb_ctx);
1401 talloc_free(mem_ctx);
1402 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1404 Py_RETURN_NONE;
1407 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1409 PyObject *py_dn1, *py_dn2;
1410 struct ldb_dn *dn1, *dn2;
1411 int ret;
1412 TALLOC_CTX *mem_ctx;
1413 PyObject *py_controls = Py_None;
1414 struct ldb_control **parsed_controls;
1415 struct ldb_context *ldb_ctx;
1416 struct ldb_request *req;
1417 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1419 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1421 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1422 discard_const_p(char *, kwnames),
1423 &py_dn1, &py_dn2, &py_controls))
1424 return NULL;
1427 mem_ctx = talloc_new(NULL);
1428 if (mem_ctx == NULL) {
1429 PyErr_NoMemory();
1430 return NULL;
1433 if (py_controls == Py_None) {
1434 parsed_controls = NULL;
1435 } else {
1436 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1437 if (controls == NULL) {
1438 talloc_free(mem_ctx);
1439 return NULL;
1441 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1442 talloc_free(controls);
1446 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1447 talloc_free(mem_ctx);
1448 return NULL;
1451 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1452 talloc_free(mem_ctx);
1453 return NULL;
1456 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1457 NULL, ldb_op_default_callback, NULL);
1458 if (ret != LDB_SUCCESS) {
1459 PyErr_SetString(PyExc_TypeError, "failed to build request");
1460 talloc_free(mem_ctx);
1461 return NULL;
1464 /* do request and autostart a transaction */
1465 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1467 ret = ldb_transaction_start(ldb_ctx);
1468 if (ret != LDB_SUCCESS) {
1469 talloc_free(mem_ctx);
1470 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1471 return NULL;
1474 ret = ldb_request(ldb_ctx, req);
1475 if (ret == LDB_SUCCESS) {
1476 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1479 if (ret == LDB_SUCCESS) {
1480 ret = ldb_transaction_commit(ldb_ctx);
1481 } else {
1482 ldb_transaction_cancel(ldb_ctx);
1485 talloc_free(mem_ctx);
1486 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1488 Py_RETURN_NONE;
1491 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1493 char *name;
1494 if (!PyArg_ParseTuple(args, "s", &name))
1495 return NULL;
1497 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1499 Py_RETURN_NONE;
1502 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1504 char *attribute, *syntax;
1505 unsigned int flags;
1506 int ret;
1507 struct ldb_context *ldb_ctx;
1509 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1510 return NULL;
1512 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1513 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1515 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1517 Py_RETURN_NONE;
1520 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1522 if (ldif == NULL) {
1523 Py_RETURN_NONE;
1524 } else {
1525 /* We don't want this attached to the 'ldb' any more */
1526 return Py_BuildValue(discard_const_p(char, "(iO)"),
1527 ldif->changetype,
1528 PyLdbMessage_FromMessage(ldif->msg));
1533 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1535 int changetype;
1536 PyObject *py_msg;
1537 struct ldb_ldif ldif;
1538 PyObject *ret;
1539 char *string;
1540 TALLOC_CTX *mem_ctx;
1542 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1543 return NULL;
1545 if (!PyLdbMessage_Check(py_msg)) {
1546 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1547 return NULL;
1550 ldif.msg = pyldb_Message_AsMessage(py_msg);
1551 ldif.changetype = changetype;
1553 mem_ctx = talloc_new(NULL);
1555 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1556 if (!string) {
1557 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1558 return NULL;
1561 ret = PyString_FromString(string);
1563 talloc_free(mem_ctx);
1565 return ret;
1568 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1570 PyObject *list, *ret;
1571 struct ldb_ldif *ldif;
1572 const char *s;
1574 TALLOC_CTX *mem_ctx;
1576 if (!PyArg_ParseTuple(args, "s", &s))
1577 return NULL;
1579 mem_ctx = talloc_new(NULL);
1580 if (!mem_ctx) {
1581 Py_RETURN_NONE;
1584 list = PyList_New(0);
1585 while (s && *s != '\0') {
1586 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1587 talloc_steal(mem_ctx, ldif);
1588 if (ldif) {
1589 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1590 } else {
1591 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1592 talloc_free(mem_ctx);
1593 return NULL;
1596 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1597 ret = PyObject_GetIter(list);
1598 Py_DECREF(list);
1599 return ret;
1602 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1604 int ldb_ret;
1605 PyObject *py_msg_old;
1606 PyObject *py_msg_new;
1607 struct ldb_message *diff;
1608 struct ldb_context *ldb;
1609 PyObject *py_ret;
1611 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1612 return NULL;
1614 if (!PyLdbMessage_Check(py_msg_old)) {
1615 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1616 return NULL;
1619 if (!PyLdbMessage_Check(py_msg_new)) {
1620 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1621 return NULL;
1624 ldb = pyldb_Ldb_AsLdbContext(self);
1625 ldb_ret = ldb_msg_difference(ldb, ldb,
1626 pyldb_Message_AsMessage(py_msg_old),
1627 pyldb_Message_AsMessage(py_msg_new),
1628 &diff);
1629 if (ldb_ret != LDB_SUCCESS) {
1630 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1631 return NULL;
1634 py_ret = PyLdbMessage_FromMessage(diff);
1636 talloc_unlink(ldb, diff);
1638 return py_ret;
1641 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1643 const struct ldb_schema_attribute *a;
1644 struct ldb_val old_val;
1645 struct ldb_val new_val;
1646 TALLOC_CTX *mem_ctx;
1647 PyObject *ret;
1648 char *element_name;
1649 PyObject *val;
1651 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1652 return NULL;
1654 old_val.data = (uint8_t *)PyString_AsString(val);
1655 old_val.length = PyString_Size(val);
1657 if (old_val.data == NULL) {
1658 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1659 return NULL;
1662 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1664 if (a == NULL) {
1665 Py_RETURN_NONE;
1668 mem_ctx = talloc_new(NULL);
1669 if (mem_ctx == NULL) {
1670 PyErr_NoMemory();
1671 return NULL;
1674 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1675 talloc_free(mem_ctx);
1676 Py_RETURN_NONE;
1679 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1681 talloc_free(mem_ctx);
1683 return ret;
1686 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1688 PyObject *py_base = Py_None;
1689 int scope = LDB_SCOPE_DEFAULT;
1690 char *expr = NULL;
1691 PyObject *py_attrs = Py_None;
1692 PyObject *py_controls = Py_None;
1693 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1694 int ret;
1695 struct ldb_result *res;
1696 struct ldb_request *req;
1697 const char **attrs;
1698 struct ldb_context *ldb_ctx;
1699 struct ldb_control **parsed_controls;
1700 struct ldb_dn *base;
1701 PyObject *py_ret;
1702 TALLOC_CTX *mem_ctx;
1704 /* type "int" rather than "enum" for "scope" is intentional */
1705 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1706 discard_const_p(char *, kwnames),
1707 &py_base, &scope, &expr, &py_attrs, &py_controls))
1708 return NULL;
1711 mem_ctx = talloc_new(NULL);
1712 if (mem_ctx == NULL) {
1713 PyErr_NoMemory();
1714 return NULL;
1716 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1718 if (py_attrs == Py_None) {
1719 attrs = NULL;
1720 } else {
1721 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1722 if (attrs == NULL) {
1723 talloc_free(mem_ctx);
1724 return NULL;
1728 if (py_base == Py_None) {
1729 base = ldb_get_default_basedn(ldb_ctx);
1730 } else {
1731 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1732 talloc_free(attrs);
1733 return NULL;
1737 if (py_controls == Py_None) {
1738 parsed_controls = NULL;
1739 } else {
1740 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1741 if (controls == NULL) {
1742 talloc_free(mem_ctx);
1743 return NULL;
1745 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1746 talloc_free(controls);
1749 res = talloc_zero(mem_ctx, struct ldb_result);
1750 if (res == NULL) {
1751 PyErr_NoMemory();
1752 talloc_free(mem_ctx);
1753 return NULL;
1756 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1757 base,
1758 scope,
1759 expr,
1760 attrs,
1761 parsed_controls,
1762 res,
1763 ldb_search_default_callback,
1764 NULL);
1766 if (ret != LDB_SUCCESS) {
1767 talloc_free(mem_ctx);
1768 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1769 return NULL;
1772 talloc_steal(req, attrs);
1774 ret = ldb_request(ldb_ctx, req);
1776 if (ret == LDB_SUCCESS) {
1777 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1780 if (ret != LDB_SUCCESS) {
1781 talloc_free(mem_ctx);
1782 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1783 return NULL;
1786 py_ret = PyLdbResult_FromResult(res);
1788 talloc_free(mem_ctx);
1790 return py_ret;
1793 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1795 char *name;
1796 void *data;
1798 if (!PyArg_ParseTuple(args, "s", &name))
1799 return NULL;
1801 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1803 if (data == NULL)
1804 Py_RETURN_NONE;
1806 /* FIXME: More interpretation */
1808 Py_RETURN_TRUE;
1811 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1813 char *name;
1814 PyObject *data;
1816 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1817 return NULL;
1819 /* FIXME: More interpretation */
1821 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1823 Py_RETURN_NONE;
1826 static PyObject *py_ldb_modules(PyLdbObject *self)
1828 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1829 PyObject *ret = PyList_New(0);
1830 struct ldb_module *mod;
1832 for (mod = ldb->modules; mod; mod = mod->next) {
1833 PyList_Append(ret, PyLdbModule_FromModule(mod));
1836 return ret;
1839 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1841 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1842 int type, ret;
1843 uint64_t value;
1845 if (!PyArg_ParseTuple(args, "i", &type))
1846 return NULL;
1848 /* FIXME: More interpretation */
1850 ret = ldb_sequence_number(ldb, type, &value);
1852 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1854 return PyLong_FromLongLong(value);
1856 static PyMethodDef py_ldb_methods[] = {
1857 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1858 "S.set_debug(callback) -> None\n"
1859 "Set callback for LDB debug messages.\n"
1860 "The callback should accept a debug level and debug text." },
1861 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1862 "S.set_create_perms(mode) -> None\n"
1863 "Set mode to use when creating new LDB files." },
1864 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1865 "S.set_modules_dir(path) -> None\n"
1866 "Set path LDB should search for modules" },
1867 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1868 "S.transaction_start() -> None\n"
1869 "Start a new transaction." },
1870 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1871 "S.transaction_prepare_commit() -> None\n"
1872 "prepare to commit a new transaction (2-stage commit)." },
1873 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1874 "S.transaction_commit() -> None\n"
1875 "commit a new transaction." },
1876 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1877 "S.transaction_cancel() -> None\n"
1878 "cancel a new transaction." },
1879 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1880 NULL },
1881 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1882 NULL },
1883 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1884 NULL },
1885 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1886 NULL },
1887 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1888 NULL },
1889 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1890 "S.connect(url, flags=0, options=None) -> None\n"
1891 "Connect to a LDB URL." },
1892 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1893 "S.modify(message, controls=None, validate=False) -> None\n"
1894 "Modify an entry." },
1895 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1896 "S.add(message, controls=None) -> None\n"
1897 "Add an entry." },
1898 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1899 "S.delete(dn, controls=None) -> None\n"
1900 "Remove an entry." },
1901 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1902 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1903 "Rename an entry." },
1904 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1905 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1906 "Search in a database.\n"
1907 "\n"
1908 ":param base: Optional base DN to search\n"
1909 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1910 ":param expression: Optional search expression\n"
1911 ":param attrs: Attributes to return (defaults to all)\n"
1912 ":param controls: Optional list of controls\n"
1913 ":return: Iterator over Message objects\n"
1915 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1916 NULL },
1917 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1918 NULL },
1919 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1920 NULL },
1921 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1922 "S.parse_ldif(ldif) -> iter(messages)\n"
1923 "Parse a string formatted using LDIF." },
1924 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1925 "S.write_ldif(message, changetype) -> ldif\n"
1926 "Print the message as a string formatted using LDIF." },
1927 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1928 "S.msg_diff(Message) -> Message\n"
1929 "Return an LDB Message of the difference between two Message objects." },
1930 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1931 "S.get_opaque(name) -> value\n"
1932 "Get an opaque value set on this LDB connection. \n"
1933 ":note: The returned value may not be useful in Python."
1935 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1936 "S.set_opaque(name, value) -> None\n"
1937 "Set an opaque value on this LDB connection. \n"
1938 ":note: Passing incorrect values may cause crashes." },
1939 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1940 "S.modules() -> list\n"
1941 "Return the list of modules on this LDB connection " },
1942 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1943 "S.sequence_number(type) -> value\n"
1944 "Return the value of the sequence according to the requested type" },
1945 { NULL },
1948 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1950 PyLdbModuleObject *ret;
1952 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1953 if (ret == NULL) {
1954 PyErr_NoMemory();
1955 return NULL;
1957 ret->mem_ctx = talloc_new(NULL);
1958 ret->mod = talloc_reference(ret->mem_ctx, mod);
1959 return (PyObject *)ret;
1962 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1964 return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1967 static PyGetSetDef py_ldb_getset[] = {
1968 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1969 { NULL }
1972 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1974 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1975 struct ldb_dn *dn;
1976 struct ldb_result *result;
1977 unsigned int count;
1978 int ret;
1980 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1981 return -1;
1984 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1985 NULL);
1986 if (ret != LDB_SUCCESS) {
1987 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1988 return -1;
1991 count = result->count;
1993 talloc_free(result);
1995 if (count > 1) {
1996 PyErr_Format(PyExc_RuntimeError,
1997 "Searching for [%s] dn gave %u results!",
1998 ldb_dn_get_linearized(dn),
1999 count);
2000 return -1;
2003 return count;
2006 static PySequenceMethods py_ldb_seq = {
2007 .sq_contains = (objobjproc)py_ldb_contains,
2010 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2012 PyLdbObject *ret;
2014 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2015 if (ret == NULL) {
2016 PyErr_NoMemory();
2017 return NULL;
2019 ret->mem_ctx = talloc_new(NULL);
2020 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2021 return (PyObject *)ret;
2024 static void py_ldb_dealloc(PyLdbObject *self)
2026 talloc_free(self->mem_ctx);
2027 Py_TYPE(self)->tp_free(self);
2030 static PyTypeObject PyLdb = {
2031 .tp_name = "ldb.Ldb",
2032 .tp_methods = py_ldb_methods,
2033 .tp_repr = (reprfunc)py_ldb_repr,
2034 .tp_new = py_ldb_new,
2035 .tp_init = (initproc)py_ldb_init,
2036 .tp_dealloc = (destructor)py_ldb_dealloc,
2037 .tp_getset = py_ldb_getset,
2038 .tp_getattro = PyObject_GenericGetAttr,
2039 .tp_basicsize = sizeof(PyLdbObject),
2040 .tp_doc = "Connection to a LDB database.",
2041 .tp_as_sequence = &py_ldb_seq,
2042 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2045 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2047 talloc_free(self->mem_ctx);
2048 Py_DECREF(self->msgs);
2049 Py_DECREF(self->referals);
2050 Py_DECREF(self->controls);
2051 Py_TYPE(self)->tp_free(self);
2054 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2056 Py_INCREF(self->msgs);
2057 return self->msgs;
2060 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2062 Py_INCREF(self->controls);
2063 return self->controls;
2066 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2068 Py_INCREF(self->referals);
2069 return self->referals;
2072 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2074 Py_ssize_t size;
2075 if (self->msgs == NULL) {
2076 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2077 return NULL;
2079 size = PyList_Size(self->msgs);
2080 return PyInt_FromLong(size);
2083 static PyGetSetDef py_ldb_result_getset[] = {
2084 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2085 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2086 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2087 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2088 { NULL }
2091 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2093 return PyObject_GetIter(self->msgs);
2096 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2098 return PySequence_Size(self->msgs);
2101 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2103 return PySequence_GetItem(self->msgs, idx);
2106 static PySequenceMethods py_ldb_result_seq = {
2107 .sq_length = (lenfunc)py_ldb_result_len,
2108 .sq_item = (ssizeargfunc)py_ldb_result_find,
2111 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2113 return PyString_FromFormat("<ldb result>");
2117 static PyTypeObject PyLdbResult = {
2118 .tp_name = "ldb.Result",
2119 .tp_repr = (reprfunc)py_ldb_result_repr,
2120 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2121 .tp_iter = (getiterfunc)py_ldb_result_iter,
2122 .tp_getset = py_ldb_result_getset,
2123 .tp_getattro = PyObject_GenericGetAttr,
2124 .tp_basicsize = sizeof(PyLdbResultObject),
2125 .tp_as_sequence = &py_ldb_result_seq,
2126 .tp_doc = "LDB result.",
2127 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2130 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2132 return PyString_FromFormat("<ldb module '%s'>",
2133 pyldb_Module_AsModule(self)->ops->name);
2136 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2138 return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
2141 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2143 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2144 Py_RETURN_NONE;
2147 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2149 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2150 Py_RETURN_NONE;
2153 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2155 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2156 Py_RETURN_NONE;
2159 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2161 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2162 int ret, scope;
2163 struct ldb_request *req;
2164 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2165 struct ldb_module *mod;
2166 const char * const*attrs;
2168 /* type "int" rather than "enum" for "scope" is intentional */
2169 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2170 discard_const_p(char *, kwnames),
2171 &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2172 return NULL;
2174 mod = self->mod;
2176 if (py_attrs == Py_None) {
2177 attrs = NULL;
2178 } else {
2179 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
2180 if (attrs == NULL)
2181 return NULL;
2184 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2185 scope, NULL /* expr */, attrs,
2186 NULL /* controls */, NULL, NULL, NULL);
2188 talloc_steal(req, attrs);
2190 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2192 req->op.search.res = NULL;
2194 ret = mod->ops->search(mod, req);
2196 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2198 py_ret = PyLdbResult_FromResult(req->op.search.res);
2200 talloc_free(req);
2202 return py_ret;
2206 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2208 struct ldb_request *req;
2209 PyObject *py_message;
2210 int ret;
2211 struct ldb_module *mod;
2213 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2214 return NULL;
2216 req = talloc_zero(NULL, struct ldb_request);
2217 req->operation = LDB_ADD;
2218 req->op.add.message = pyldb_Message_AsMessage(py_message);
2220 mod = pyldb_Module_AsModule(self);
2221 ret = mod->ops->add(mod, req);
2223 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2225 Py_RETURN_NONE;
2228 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2230 int ret;
2231 struct ldb_request *req;
2232 PyObject *py_message;
2233 struct ldb_module *mod;
2235 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2236 return NULL;
2238 req = talloc_zero(NULL, struct ldb_request);
2239 req->operation = LDB_MODIFY;
2240 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2242 mod = pyldb_Module_AsModule(self);
2243 ret = mod->ops->modify(mod, req);
2245 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2247 Py_RETURN_NONE;
2250 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2252 int ret;
2253 struct ldb_request *req;
2254 PyObject *py_dn;
2256 if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2257 return NULL;
2259 req = talloc_zero(NULL, struct ldb_request);
2260 req->operation = LDB_DELETE;
2261 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2263 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2265 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2267 Py_RETURN_NONE;
2270 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2272 int ret;
2273 struct ldb_request *req;
2274 PyObject *py_dn1, *py_dn2;
2276 if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2277 return NULL;
2279 req = talloc_zero(NULL, struct ldb_request);
2281 req->operation = LDB_RENAME;
2282 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2283 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2285 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2287 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2289 Py_RETURN_NONE;
2292 static PyMethodDef py_ldb_module_methods[] = {
2293 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2294 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2295 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2296 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2297 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2298 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2299 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2300 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2301 { NULL },
2304 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2306 talloc_free(self->mem_ctx);
2307 PyObject_Del(self);
2310 static PyTypeObject PyLdbModule = {
2311 .tp_name = "ldb.LdbModule",
2312 .tp_methods = py_ldb_module_methods,
2313 .tp_repr = (reprfunc)py_ldb_module_repr,
2314 .tp_str = (reprfunc)py_ldb_module_str,
2315 .tp_basicsize = sizeof(PyLdbModuleObject),
2316 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2317 .tp_flags = Py_TPFLAGS_DEFAULT,
2318 .tp_doc = "LDB module (extension)",
2323 * Create a ldb_message_element from a Python object.
2325 * This will accept any sequence objects that contains strings, or
2326 * a string object.
2328 * A reference to set_obj will be borrowed.
2330 * @param mem_ctx Memory context
2331 * @param set_obj Python object to convert
2332 * @param flags ldb_message_element flags to set
2333 * @param attr_name Name of the attribute
2334 * @return New ldb_message_element, allocated as child of mem_ctx
2336 static struct ldb_message_element *PyObject_AsMessageElement(
2337 TALLOC_CTX *mem_ctx,
2338 PyObject *set_obj,
2339 unsigned int flags,
2340 const char *attr_name)
2342 struct ldb_message_element *me;
2344 if (pyldb_MessageElement_Check(set_obj)) {
2345 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2346 /* We have to talloc_reference() the memory context, not the pointer
2347 * which may not actually be it's own context */
2348 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2349 return pyldb_MessageElement_AsMessageElement(set_obj);
2351 return NULL;
2354 me = talloc(mem_ctx, struct ldb_message_element);
2355 if (me == NULL) {
2356 PyErr_NoMemory();
2357 return NULL;
2360 me->name = talloc_strdup(me, attr_name);
2361 me->flags = flags;
2362 if (PyString_Check(set_obj)) {
2363 me->num_values = 1;
2364 me->values = talloc_array(me, struct ldb_val, me->num_values);
2365 me->values[0].length = PyString_Size(set_obj);
2366 me->values[0].data = talloc_memdup(me,
2367 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2368 } else if (PySequence_Check(set_obj)) {
2369 Py_ssize_t i;
2370 me->num_values = PySequence_Size(set_obj);
2371 me->values = talloc_array(me, struct ldb_val, me->num_values);
2372 for (i = 0; i < me->num_values; i++) {
2373 PyObject *obj = PySequence_GetItem(set_obj, i);
2374 if (!PyString_Check(obj)) {
2375 PyErr_Format(PyExc_TypeError,
2376 "Expected string as element %zd in list", i);
2377 talloc_free(me);
2378 return NULL;
2381 me->values[i].length = PyString_Size(obj);
2382 me->values[i].data = talloc_memdup(me,
2383 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2385 } else {
2386 PyErr_Format(PyExc_TypeError,
2387 "String or List type expected for '%s' attribute", attr_name);
2388 talloc_free(me);
2389 me = NULL;
2392 return me;
2396 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2397 struct ldb_message_element *me)
2399 Py_ssize_t i;
2400 PyObject *result;
2402 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2403 result = PyList_New(me->num_values);
2405 for (i = 0; i < me->num_values; i++) {
2406 PyList_SetItem(result, i,
2407 PyObject_FromLdbValue(&me->values[i]));
2410 return result;
2413 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2415 unsigned int i;
2416 if (!PyArg_ParseTuple(args, "I", &i))
2417 return NULL;
2418 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2419 Py_RETURN_NONE;
2421 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2424 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2426 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2427 return PyInt_FromLong(el->flags);
2430 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2432 unsigned int flags;
2433 struct ldb_message_element *el;
2434 if (!PyArg_ParseTuple(args, "I", &flags))
2435 return NULL;
2437 el = pyldb_MessageElement_AsMessageElement(self);
2438 el->flags = flags;
2439 Py_RETURN_NONE;
2442 static PyMethodDef py_ldb_msg_element_methods[] = {
2443 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2444 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2445 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2446 { NULL },
2449 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2451 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2454 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2456 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2457 if (idx < 0 || idx >= el->num_values) {
2458 PyErr_SetString(PyExc_IndexError, "Out of range");
2459 return NULL;
2461 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2464 static PySequenceMethods py_ldb_msg_element_seq = {
2465 .sq_length = (lenfunc)py_ldb_msg_element_len,
2466 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2469 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2471 int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2472 pyldb_MessageElement_AsMessageElement(other));
2473 return SIGN(ret);
2476 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2478 PyObject *el = ldb_msg_element_to_set(NULL,
2479 pyldb_MessageElement_AsMessageElement(self));
2480 PyObject *ret = PyObject_GetIter(el);
2481 Py_DECREF(el);
2482 return ret;
2485 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2487 PyLdbMessageElementObject *ret;
2488 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2489 if (ret == NULL) {
2490 PyErr_NoMemory();
2491 return NULL;
2493 ret->mem_ctx = talloc_new(NULL);
2494 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2495 PyErr_NoMemory();
2496 return NULL;
2498 ret->el = el;
2499 return (PyObject *)ret;
2502 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2504 PyObject *py_elements = NULL;
2505 struct ldb_message_element *el;
2506 unsigned int flags = 0;
2507 char *name = NULL;
2508 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2509 PyLdbMessageElementObject *ret;
2510 TALLOC_CTX *mem_ctx;
2512 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2513 discard_const_p(char *, kwnames),
2514 &py_elements, &flags, &name))
2515 return NULL;
2517 mem_ctx = talloc_new(NULL);
2518 if (mem_ctx == NULL) {
2519 PyErr_NoMemory();
2520 return NULL;
2523 el = talloc_zero(mem_ctx, struct ldb_message_element);
2524 if (el == NULL) {
2525 PyErr_NoMemory();
2526 talloc_free(mem_ctx);
2527 return NULL;
2530 if (py_elements != NULL) {
2531 Py_ssize_t i;
2532 if (PyString_Check(py_elements)) {
2533 el->num_values = 1;
2534 el->values = talloc_array(el, struct ldb_val, 1);
2535 if (el->values == NULL) {
2536 talloc_free(mem_ctx);
2537 PyErr_NoMemory();
2538 return NULL;
2540 el->values[0].length = PyString_Size(py_elements);
2541 el->values[0].data = talloc_memdup(el->values,
2542 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2543 } else if (PySequence_Check(py_elements)) {
2544 el->num_values = PySequence_Size(py_elements);
2545 el->values = talloc_array(el, struct ldb_val, el->num_values);
2546 if (el->values == NULL) {
2547 talloc_free(mem_ctx);
2548 PyErr_NoMemory();
2549 return NULL;
2551 for (i = 0; i < el->num_values; i++) {
2552 PyObject *item = PySequence_GetItem(py_elements, i);
2553 if (item == NULL) {
2554 talloc_free(mem_ctx);
2555 return NULL;
2557 if (!PyString_Check(item)) {
2558 PyErr_Format(PyExc_TypeError,
2559 "Expected string as element %zd in list", i);
2560 talloc_free(mem_ctx);
2561 return NULL;
2563 el->values[i].length = PyString_Size(item);
2564 el->values[i].data = talloc_memdup(el,
2565 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2567 } else {
2568 PyErr_SetString(PyExc_TypeError,
2569 "Expected string or list");
2570 talloc_free(mem_ctx);
2571 return NULL;
2575 el->flags = flags;
2576 el->name = talloc_strdup(el, name);
2578 ret = PyObject_New(PyLdbMessageElementObject, type);
2579 if (ret == NULL) {
2580 talloc_free(mem_ctx);
2581 return NULL;
2584 ret->mem_ctx = mem_ctx;
2585 ret->el = el;
2586 return (PyObject *)ret;
2589 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2591 char *element_str = NULL;
2592 Py_ssize_t i;
2593 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2594 PyObject *ret, *repr;
2596 for (i = 0; i < el->num_values; i++) {
2597 PyObject *o = py_ldb_msg_element_find(self, i);
2598 repr = PyObject_Repr(o);
2599 if (element_str == NULL)
2600 element_str = talloc_strdup(NULL, PyString_AsString(repr));
2601 else
2602 element_str = talloc_asprintf_append(element_str, ",%s", PyString_AsString(repr));
2603 Py_DECREF(repr);
2606 if (element_str != NULL) {
2607 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2608 talloc_free(element_str);
2609 } else {
2610 ret = PyString_FromString("MessageElement([])");
2613 return ret;
2616 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2618 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2620 if (el->num_values == 1)
2621 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2622 else
2623 Py_RETURN_NONE;
2626 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2628 talloc_free(self->mem_ctx);
2629 PyObject_Del(self);
2632 static PyTypeObject PyLdbMessageElement = {
2633 .tp_name = "ldb.MessageElement",
2634 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2635 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2636 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2637 .tp_str = (reprfunc)py_ldb_msg_element_str,
2638 .tp_methods = py_ldb_msg_element_methods,
2639 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2640 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2641 .tp_as_sequence = &py_ldb_msg_element_seq,
2642 .tp_new = py_ldb_msg_element_new,
2643 .tp_flags = Py_TPFLAGS_DEFAULT,
2644 .tp_doc = "An element of a Message",
2648 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2650 PyObject *py_ldb;
2651 PyObject *py_dict;
2652 PyObject *py_ret;
2653 struct ldb_message *msg;
2654 struct ldb_context *ldb_ctx;
2655 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2657 if (!PyArg_ParseTuple(args, "O!O!|I",
2658 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2659 &mod_flags)) {
2660 return NULL;
2663 if (!PyLdb_Check(py_ldb)) {
2664 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
2665 return NULL;
2668 /* mask only flags we are going to use */
2669 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2670 if (!mod_flags) {
2671 PyErr_SetString(PyExc_ValueError,
2672 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2673 " expected as mod_flag value");
2674 return NULL;
2677 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2679 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2680 if (!msg) {
2681 return NULL;
2684 py_ret = PyLdbMessage_FromMessage(msg);
2686 talloc_unlink(ldb_ctx, msg);
2688 return py_ret;
2691 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2693 char *name;
2694 if (!PyArg_ParseTuple(args, "s", &name))
2695 return NULL;
2697 ldb_msg_remove_attr(self->msg, name);
2699 Py_RETURN_NONE;
2702 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2704 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2705 Py_ssize_t i, j = 0;
2706 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2707 if (msg->dn != NULL) {
2708 PyList_SetItem(obj, j, PyString_FromString("dn"));
2709 j++;
2711 for (i = 0; i < msg->num_elements; i++) {
2712 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2713 j++;
2715 return obj;
2718 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2720 struct ldb_message_element *el;
2721 char *name;
2722 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2723 if (!PyString_Check(py_name)) {
2724 PyErr_SetNone(PyExc_TypeError);
2725 return NULL;
2727 name = PyString_AsString(py_name);
2728 if (!ldb_attr_cmp(name, "dn"))
2729 return pyldb_Dn_FromDn(msg->dn);
2730 el = ldb_msg_find_element(msg, name);
2731 if (el == NULL) {
2732 return NULL;
2734 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2737 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2739 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2740 if (ret == NULL) {
2741 PyErr_SetString(PyExc_KeyError, "No such element");
2742 return NULL;
2744 return ret;
2747 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2749 PyObject *def = NULL;
2750 const char *kwnames[] = { "name", "default", "idx", NULL };
2751 const char *name = NULL;
2752 int idx = -1;
2753 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2754 struct ldb_message_element *el;
2756 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2757 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2758 return NULL;
2761 if (strcasecmp(name, "dn") == 0) {
2762 return pyldb_Dn_FromDn(msg->dn);
2765 el = ldb_msg_find_element(msg, name);
2767 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2768 if (def != NULL) {
2769 Py_INCREF(def);
2770 return def;
2772 Py_RETURN_NONE;
2775 if (idx == -1) {
2776 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2779 return PyObject_FromLdbValue(&el->values[idx]);
2782 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2784 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2785 Py_ssize_t i, j = 0;
2786 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2787 if (msg->dn != NULL) {
2788 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2789 j++;
2791 for (i = 0; i < msg->num_elements; i++, j++) {
2792 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2793 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2794 PyList_SetItem(l, j, value);
2796 return l;
2799 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2801 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2802 Py_ssize_t i = 0;
2803 PyObject *l = PyList_New(msg->num_elements);
2804 for (i = 0; i < msg->num_elements; i++) {
2805 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2807 return l;
2810 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2812 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2813 PyLdbMessageElementObject *py_element;
2814 int i, ret;
2815 struct ldb_message_element *el;
2816 struct ldb_message_element *el_new;
2818 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2819 return NULL;
2821 el = py_element->el;
2822 if (el == NULL) {
2823 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
2824 return NULL;
2827 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
2828 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2830 /* now deep copy all attribute values */
2831 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
2832 if (el_new->values == NULL) {
2833 PyErr_NoMemory();
2834 return NULL;
2836 el_new->num_values = el->num_values;
2838 for (i = 0; i < el->num_values; i++) {
2839 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
2840 if (el_new->values[i].data == NULL
2841 && el->values[i].length != 0) {
2842 PyErr_NoMemory();
2843 return NULL;
2847 Py_RETURN_NONE;
2850 static PyMethodDef py_ldb_msg_methods[] = {
2851 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2852 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2853 "Class method to create ldb.Message object from Dictionary.\n"
2854 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2855 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2856 "S.keys() -> list\n\n"
2857 "Return sequence of all attribute names." },
2858 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2859 "S.remove(name)\n\n"
2860 "Remove all entries for attributes with the specified name."},
2861 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2862 "msg.get(name,default=None,idx=None) -> string\n"
2863 "idx is the index into the values array\n"
2864 "if idx is None, then a list is returned\n"
2865 "if idx is not None, then the element with that index is returned\n"
2866 "if you pass the special name 'dn' then the DN object is returned\n"},
2867 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2868 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2869 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2870 "S.add(element)\n\n"
2871 "Add an element to this message." },
2872 { NULL },
2875 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2877 PyObject *list, *iter;
2879 list = py_ldb_msg_keys(self);
2880 iter = PyObject_GetIter(list);
2881 Py_DECREF(list);
2882 return iter;
2885 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2887 char *attr_name;
2889 if (!PyString_Check(name)) {
2890 PyErr_SetNone(PyExc_TypeError);
2891 return -1;
2894 attr_name = PyString_AsString(name);
2895 if (value == NULL) {
2896 /* delitem */
2897 ldb_msg_remove_attr(self->msg, attr_name);
2898 } else {
2899 int ret;
2900 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2901 value, 0, attr_name);
2902 if (el == NULL) {
2903 return -1;
2905 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2906 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2907 if (ret != LDB_SUCCESS) {
2908 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
2909 return -1;
2912 return 0;
2915 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2917 return pyldb_Message_AsMessage(self)->num_elements;
2920 static PyMappingMethods py_ldb_msg_mapping = {
2921 .mp_length = (lenfunc)py_ldb_msg_length,
2922 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2923 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2926 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2928 const char * const kwnames[] = { "dn", NULL };
2929 struct ldb_message *ret;
2930 TALLOC_CTX *mem_ctx;
2931 PyObject *pydn = NULL;
2932 PyLdbMessageObject *py_ret;
2934 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2935 discard_const_p(char *, kwnames),
2936 &pydn))
2937 return NULL;
2939 mem_ctx = talloc_new(NULL);
2940 if (mem_ctx == NULL) {
2941 PyErr_NoMemory();
2942 return NULL;
2945 ret = ldb_msg_new(mem_ctx);
2946 if (ret == NULL) {
2947 talloc_free(mem_ctx);
2948 PyErr_NoMemory();
2949 return NULL;
2952 if (pydn != NULL) {
2953 struct ldb_dn *dn;
2954 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2955 talloc_free(mem_ctx);
2956 return NULL;
2958 ret->dn = talloc_reference(ret, dn);
2961 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2962 if (py_ret == NULL) {
2963 PyErr_NoMemory();
2964 talloc_free(mem_ctx);
2965 return NULL;
2968 py_ret->mem_ctx = mem_ctx;
2969 py_ret->msg = ret;
2970 return (PyObject *)py_ret;
2973 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2975 PyLdbMessageObject *ret;
2977 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2978 if (ret == NULL) {
2979 PyErr_NoMemory();
2980 return NULL;
2982 ret->mem_ctx = talloc_new(NULL);
2983 ret->msg = talloc_reference(ret->mem_ctx, msg);
2984 return (PyObject *)ret;
2987 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2989 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2990 return pyldb_Dn_FromDn(msg->dn);
2993 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2995 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2996 if (!pyldb_Dn_Check(value)) {
2997 PyErr_SetString(PyExc_TypeError, "expected dn");
2998 return -1;
3001 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3002 return 0;
3005 static PyGetSetDef py_ldb_msg_getset[] = {
3006 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
3007 { NULL }
3010 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3012 PyObject *dict = PyDict_New(), *ret, *repr;
3013 if (PyDict_Update(dict, (PyObject *)self) != 0)
3014 return NULL;
3015 repr = PyObject_Repr(dict);
3016 if (repr == NULL) {
3017 Py_DECREF(dict);
3018 return NULL;
3020 ret = PyString_FromFormat("Message(%s)", PyString_AsString(repr));
3021 Py_DECREF(repr);
3022 Py_DECREF(dict);
3023 return ret;
3026 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3028 talloc_free(self->mem_ctx);
3029 PyObject_Del(self);
3032 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
3033 PyLdbMessageObject *py_msg2)
3035 struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
3036 *msg2 = pyldb_Message_AsMessage(py_msg2);
3037 unsigned int i;
3038 int ret;
3040 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3041 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3042 if (ret != 0) {
3043 return SIGN(ret);
3047 ret = msg1->num_elements - msg2->num_elements;
3048 if (ret != 0) {
3049 return SIGN(ret);
3052 for (i = 0; i < msg1->num_elements; i++) {
3053 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3054 &msg2->elements[i]);
3055 if (ret != 0) {
3056 return SIGN(ret);
3059 ret = ldb_msg_element_compare(&msg1->elements[i],
3060 &msg2->elements[i]);
3061 if (ret != 0) {
3062 return SIGN(ret);
3066 return 0;
3069 static PyTypeObject PyLdbMessage = {
3070 .tp_name = "ldb.Message",
3071 .tp_methods = py_ldb_msg_methods,
3072 .tp_getset = py_ldb_msg_getset,
3073 .tp_as_mapping = &py_ldb_msg_mapping,
3074 .tp_basicsize = sizeof(PyLdbMessageObject),
3075 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3076 .tp_new = py_ldb_msg_new,
3077 .tp_repr = (reprfunc)py_ldb_msg_repr,
3078 .tp_flags = Py_TPFLAGS_DEFAULT,
3079 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3080 .tp_compare = (cmpfunc)py_ldb_msg_compare,
3081 .tp_doc = "A LDB Message",
3084 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3086 PyLdbTreeObject *ret;
3088 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3089 if (ret == NULL) {
3090 PyErr_NoMemory();
3091 return NULL;
3094 ret->mem_ctx = talloc_new(NULL);
3095 ret->tree = talloc_reference(ret->mem_ctx, tree);
3096 return (PyObject *)ret;
3099 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3101 talloc_free(self->mem_ctx);
3102 PyObject_Del(self);
3105 static PyTypeObject PyLdbTree = {
3106 .tp_name = "ldb.Tree",
3107 .tp_basicsize = sizeof(PyLdbTreeObject),
3108 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3109 .tp_flags = Py_TPFLAGS_DEFAULT,
3110 .tp_doc = "A search tree",
3113 /* Ldb_module */
3114 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3116 PyObject *py_ldb = (PyObject *)mod->private_data;
3117 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3119 py_base = pyldb_Dn_FromDn(req->op.search.base);
3121 if (py_base == NULL)
3122 return LDB_ERR_OPERATIONS_ERROR;
3124 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3126 if (py_tree == NULL)
3127 return LDB_ERR_OPERATIONS_ERROR;
3129 if (req->op.search.attrs == NULL) {
3130 py_attrs = Py_None;
3131 } else {
3132 int i, len;
3133 for (len = 0; req->op.search.attrs[len]; len++);
3134 py_attrs = PyList_New(len);
3135 for (i = 0; i < len; i++)
3136 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
3139 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3140 discard_const_p(char, "OiOO"),
3141 py_base, req->op.search.scope, py_tree, py_attrs);
3143 Py_DECREF(py_attrs);
3144 Py_DECREF(py_tree);
3145 Py_DECREF(py_base);
3147 if (py_result == NULL) {
3148 return LDB_ERR_PYTHON_EXCEPTION;
3151 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3152 if (req->op.search.res == NULL) {
3153 return LDB_ERR_PYTHON_EXCEPTION;
3156 Py_DECREF(py_result);
3158 return LDB_SUCCESS;
3161 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3163 PyObject *py_ldb = (PyObject *)mod->private_data;
3164 PyObject *py_result, *py_msg;
3166 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3168 if (py_msg == NULL) {
3169 return LDB_ERR_OPERATIONS_ERROR;
3172 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3173 discard_const_p(char, "O"),
3174 py_msg);
3176 Py_DECREF(py_msg);
3178 if (py_result == NULL) {
3179 return LDB_ERR_PYTHON_EXCEPTION;
3182 Py_DECREF(py_result);
3184 return LDB_SUCCESS;
3187 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3189 PyObject *py_ldb = (PyObject *)mod->private_data;
3190 PyObject *py_result, *py_msg;
3192 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3194 if (py_msg == NULL) {
3195 return LDB_ERR_OPERATIONS_ERROR;
3198 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3199 discard_const_p(char, "O"),
3200 py_msg);
3202 Py_DECREF(py_msg);
3204 if (py_result == NULL) {
3205 return LDB_ERR_PYTHON_EXCEPTION;
3208 Py_DECREF(py_result);
3210 return LDB_SUCCESS;
3213 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3215 PyObject *py_ldb = (PyObject *)mod->private_data;
3216 PyObject *py_result, *py_dn;
3218 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3220 if (py_dn == NULL)
3221 return LDB_ERR_OPERATIONS_ERROR;
3223 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3224 discard_const_p(char, "O"),
3225 py_dn);
3227 if (py_result == NULL) {
3228 return LDB_ERR_PYTHON_EXCEPTION;
3231 Py_DECREF(py_result);
3233 return LDB_SUCCESS;
3236 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3238 PyObject *py_ldb = (PyObject *)mod->private_data;
3239 PyObject *py_result, *py_olddn, *py_newdn;
3241 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3243 if (py_olddn == NULL)
3244 return LDB_ERR_OPERATIONS_ERROR;
3246 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3248 if (py_newdn == NULL)
3249 return LDB_ERR_OPERATIONS_ERROR;
3251 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3252 discard_const_p(char, "OO"),
3253 py_olddn, py_newdn);
3255 Py_DECREF(py_olddn);
3256 Py_DECREF(py_newdn);
3258 if (py_result == NULL) {
3259 return LDB_ERR_PYTHON_EXCEPTION;
3262 Py_DECREF(py_result);
3264 return LDB_SUCCESS;
3267 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3269 PyObject *py_ldb = (PyObject *)mod->private_data;
3270 PyObject *py_result;
3272 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3273 discard_const_p(char, ""));
3275 Py_XDECREF(py_result);
3277 return LDB_ERR_OPERATIONS_ERROR;
3280 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3282 PyObject *py_ldb = (PyObject *)mod->private_data;
3283 PyObject *py_result;
3285 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3286 discard_const_p(char, ""));
3288 Py_XDECREF(py_result);
3290 return LDB_ERR_OPERATIONS_ERROR;
3293 static int py_module_start_transaction(struct ldb_module *mod)
3295 PyObject *py_ldb = (PyObject *)mod->private_data;
3296 PyObject *py_result;
3298 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3299 discard_const_p(char, ""));
3301 if (py_result == NULL) {
3302 return LDB_ERR_PYTHON_EXCEPTION;
3305 Py_DECREF(py_result);
3307 return LDB_SUCCESS;
3310 static int py_module_end_transaction(struct ldb_module *mod)
3312 PyObject *py_ldb = (PyObject *)mod->private_data;
3313 PyObject *py_result;
3315 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3316 discard_const_p(char, ""));
3318 if (py_result == NULL) {
3319 return LDB_ERR_PYTHON_EXCEPTION;
3322 Py_DECREF(py_result);
3324 return LDB_SUCCESS;
3327 static int py_module_del_transaction(struct ldb_module *mod)
3329 PyObject *py_ldb = (PyObject *)mod->private_data;
3330 PyObject *py_result;
3332 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3333 discard_const_p(char, ""));
3335 if (py_result == NULL) {
3336 return LDB_ERR_PYTHON_EXCEPTION;
3339 Py_DECREF(py_result);
3341 return LDB_SUCCESS;
3344 static int py_module_destructor(struct ldb_module *mod)
3346 Py_DECREF((PyObject *)mod->private_data);
3347 return 0;
3350 static int py_module_init(struct ldb_module *mod)
3352 PyObject *py_class = (PyObject *)mod->ops->private_data;
3353 PyObject *py_result, *py_next, *py_ldb;
3355 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3357 if (py_ldb == NULL)
3358 return LDB_ERR_OPERATIONS_ERROR;
3360 py_next = PyLdbModule_FromModule(mod->next);
3362 if (py_next == NULL)
3363 return LDB_ERR_OPERATIONS_ERROR;
3365 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3366 py_ldb, py_next);
3368 if (py_result == NULL) {
3369 return LDB_ERR_PYTHON_EXCEPTION;
3372 mod->private_data = py_result;
3374 talloc_set_destructor(mod, py_module_destructor);
3376 return ldb_next_init(mod);
3379 static PyObject *py_register_module(PyObject *module, PyObject *args)
3381 int ret;
3382 struct ldb_module_ops *ops;
3383 PyObject *input;
3385 if (!PyArg_ParseTuple(args, "O", &input))
3386 return NULL;
3388 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3389 if (ops == NULL) {
3390 PyErr_NoMemory();
3391 return NULL;
3394 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3396 Py_INCREF(input);
3397 ops->private_data = input;
3398 ops->init_context = py_module_init;
3399 ops->search = py_module_search;
3400 ops->add = py_module_add;
3401 ops->modify = py_module_modify;
3402 ops->del = py_module_del;
3403 ops->rename = py_module_rename;
3404 ops->request = py_module_request;
3405 ops->extended = py_module_extended;
3406 ops->start_transaction = py_module_start_transaction;
3407 ops->end_transaction = py_module_end_transaction;
3408 ops->del_transaction = py_module_del_transaction;
3410 ret = ldb_register_module(ops);
3412 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3414 Py_RETURN_NONE;
3417 static PyObject *py_timestring(PyObject *module, PyObject *args)
3419 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3420 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3421 long int t_val;
3422 char *tresult;
3423 PyObject *ret;
3424 if (!PyArg_ParseTuple(args, "l", &t_val))
3425 return NULL;
3426 tresult = ldb_timestring(NULL, (time_t) t_val);
3427 ret = PyString_FromString(tresult);
3428 talloc_free(tresult);
3429 return ret;
3432 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3434 char *str;
3435 if (!PyArg_ParseTuple(args, "s", &str))
3436 return NULL;
3438 return PyInt_FromLong(ldb_string_to_time(str));
3441 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3443 char *name;
3444 if (!PyArg_ParseTuple(args, "s", &name))
3445 return NULL;
3446 return PyBool_FromLong(ldb_valid_attr_name(name));
3450 encode a string using RFC2254 rules
3452 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3454 char *str, *encoded;
3455 int size = 0;
3456 struct ldb_val val;
3457 PyObject *ret;
3459 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3460 return NULL;
3461 val.data = (uint8_t *)str;
3462 val.length = size;
3464 encoded = ldb_binary_encode(NULL, val);
3465 if (encoded == NULL) {
3466 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3467 return NULL;
3469 ret = PyString_FromString(encoded);
3470 talloc_free(encoded);
3471 return ret;
3475 decode a string using RFC2254 rules
3477 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3479 char *str;
3480 struct ldb_val val;
3481 PyObject *ret;
3483 if (!PyArg_ParseTuple(args, "s", &str))
3484 return NULL;
3486 val = ldb_binary_decode(NULL, str);
3487 if (val.data == NULL) {
3488 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3489 return NULL;
3491 ret = Py_BuildValue("s#", val.data, val.length);
3492 talloc_free(val.data);
3493 return ret;
3496 static PyMethodDef py_ldb_global_methods[] = {
3497 { "register_module", py_register_module, METH_VARARGS,
3498 "S.register_module(module) -> None\n\n"
3499 "Register a LDB module."},
3500 { "timestring", py_timestring, METH_VARARGS,
3501 "S.timestring(int) -> string\n\n"
3502 "Generate a LDAP time string from a UNIX timestamp" },
3503 { "string_to_time", py_string_to_time, METH_VARARGS,
3504 "S.string_to_time(string) -> int\n\n"
3505 "Parse a LDAP time string into a UNIX timestamp." },
3506 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3507 "S.valid_attr_name(name) -> bool\n\nn"
3508 "Check whether the supplied name is a valid attribute name." },
3509 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3510 "S.open() -> Ldb\n\n"
3511 "Open a new LDB context." },
3512 { "binary_encode", py_binary_encode, METH_VARARGS,
3513 "S.binary_encode(string) -> string\n\n"
3514 "Perform a RFC2254 binary encoding on a string" },
3515 { "binary_decode", py_binary_decode, METH_VARARGS,
3516 "S.binary_decode(string) -> string\n\n"
3517 "Perform a RFC2254 binary decode on a string" },
3518 { NULL }
3521 void initldb(void)
3523 PyObject *m;
3525 if (PyType_Ready(&PyLdbDn) < 0)
3526 return;
3528 if (PyType_Ready(&PyLdbMessage) < 0)
3529 return;
3531 if (PyType_Ready(&PyLdbMessageElement) < 0)
3532 return;
3534 if (PyType_Ready(&PyLdb) < 0)
3535 return;
3537 if (PyType_Ready(&PyLdbModule) < 0)
3538 return;
3540 if (PyType_Ready(&PyLdbTree) < 0)
3541 return;
3543 if (PyType_Ready(&PyLdbResult) < 0)
3544 return;
3546 if (PyType_Ready(&PyLdbControl) < 0)
3547 return;
3549 m = Py_InitModule3("ldb", py_ldb_global_methods,
3550 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3551 if (m == NULL)
3552 return;
3554 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3555 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3556 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3557 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3558 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3559 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3560 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3562 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3563 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3564 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3565 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3567 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3568 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3569 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3571 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3572 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3573 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3574 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3575 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3576 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3577 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3578 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3579 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3580 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3581 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3582 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3583 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3584 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3585 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3586 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3587 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3588 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3589 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3590 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3591 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3592 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3593 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3594 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3595 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3596 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3597 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3598 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3599 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3600 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3601 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3602 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3603 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3604 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3605 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3606 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3607 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3608 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3609 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3611 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3612 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3613 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3614 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3616 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3618 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3619 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3621 Py_INCREF(&PyLdb);
3622 Py_INCREF(&PyLdbDn);
3623 Py_INCREF(&PyLdbModule);
3624 Py_INCREF(&PyLdbMessage);
3625 Py_INCREF(&PyLdbMessageElement);
3626 Py_INCREF(&PyLdbTree);
3627 Py_INCREF(&PyLdbResult);
3628 Py_INCREF(&PyLdbControl);
3630 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3631 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3632 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3633 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3634 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3635 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3636 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3638 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3640 #define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3642 ADD_LDB_STRING(SYNTAX_DN);
3643 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3644 ADD_LDB_STRING(SYNTAX_INTEGER);
3645 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3646 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3647 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3648 ADD_LDB_STRING(OID_COMPARATOR_AND);
3649 ADD_LDB_STRING(OID_COMPARATOR_OR);