lib-pyldb: Throw exception when we can't create MessageElement object
[Samba.git] / lib / ldb / pyldb.c
blob40c802fd9afece980bda9a757dcbb283c19f4b14
1 /*
2 Unix SMB/CIFS implementation.
4 Python interface to ldb.
6 Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7 Copyright (C) 2006 Simo Sorce <idra@samba.org>
8 Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9 Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10 Copyright (C) 2009-2011 Andrew Tridgell
11 Copyright (C) 2009-2011 Andrew Bartlett
13 ** NOTE! The following LGPL license applies to the ldb
14 ** library. This does NOT imply that all of Samba is released
15 ** under the LGPL
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public
19 License as published by the Free Software Foundation; either
20 version 3 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, see <http://www.gnu.org/licenses/>.
31 #include <Python.h>
32 #include "ldb_private.h"
33 #include "pyldb.h"
35 void initldb(void);
36 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
37 static PyObject *PyExc_LdbError;
39 staticforward PyTypeObject PyLdbControl;
40 staticforward PyTypeObject PyLdbResult;
41 staticforward PyTypeObject PyLdbMessage;
42 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
43 staticforward PyTypeObject PyLdbModule;
44 staticforward PyTypeObject PyLdbDn;
45 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
46 staticforward PyTypeObject PyLdb;
47 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
48 staticforward PyTypeObject PyLdbMessageElement;
49 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
51 staticforward PyTypeObject PyLdbTree;
52 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
53 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
54 static struct ldb_message_element *PyObject_AsMessageElement(
55 TALLOC_CTX *mem_ctx,
56 PyObject *set_obj,
57 unsigned int flags,
58 const char *attr_name);
60 /* There's no Py_ssize_t in 2.4, apparently */
61 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
62 typedef int Py_ssize_t;
63 typedef inquiry lenfunc;
64 typedef intargfunc ssizeargfunc;
65 #endif
67 #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 self->ob_type->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, "Os",
125 discard_const_p(char *, kwnames),
126 &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 controls = PyList_New(1);
273 if (controls == NULL) {
274 Py_DECREF(ret);
275 PyErr_NoMemory();
276 return NULL;
278 for (i=0; result->controls[i]; i++) {
279 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
280 if (ctrl == NULL) {
281 Py_DECREF(ret);
282 Py_DECREF(controls);
283 PyErr_NoMemory();
284 return NULL;
286 PyList_SetItem(controls, i, ctrl);
288 } else {
290 * No controls so we keep an empty list
292 controls = PyList_New(0);
293 if (controls == NULL) {
294 Py_DECREF(ret);
295 PyErr_NoMemory();
296 return NULL;
300 ret->controls = controls;
302 i = 0;
304 while (result->refs && result->refs[i]) {
305 i++;
308 referals = PyList_New(i);
309 if (referals == NULL) {
310 Py_DECREF(ret);
311 PyErr_NoMemory();
312 return NULL;
315 for (i = 0;result->refs && result->refs[i]; i++) {
316 PyList_SetItem(referals, i, PyString_FromString(result->refs[i]));
318 ret->referals = referals;
319 return (PyObject *)ret;
323 * Create a LDB Result from a Python object.
324 * If conversion fails, NULL will be returned and a Python exception set.
326 * Note: the result object only includes the messages at the moment; extended
327 * result, controls and referrals are ignored.
329 * @param mem_ctx Memory context in which to allocate the LDB Result
330 * @param obj Python object to convert
331 * @return a ldb_result, or NULL if the conversion failed
333 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
334 PyObject *obj)
336 struct ldb_result *res;
337 Py_ssize_t i;
339 if (obj == Py_None)
340 return NULL;
342 res = talloc_zero(mem_ctx, struct ldb_result);
343 res->count = PyList_Size(obj);
344 res->msgs = talloc_array(res, struct ldb_message *, res->count);
345 for (i = 0; i < res->count; i++) {
346 PyObject *item = PyList_GetItem(obj, i);
347 res->msgs[i] = pyldb_Message_AsMessage(item);
349 return res;
352 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
354 return PyBool_FromLong(ldb_dn_validate(self->dn));
357 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
359 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
362 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
364 return PyBool_FromLong(ldb_dn_is_special(self->dn));
367 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
369 return PyBool_FromLong(ldb_dn_is_null(self->dn));
372 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
374 return PyString_FromString(ldb_dn_get_casefold(self->dn));
377 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
379 return PyString_FromString(ldb_dn_get_linearized(self->dn));
382 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
384 return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
387 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
389 return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
392 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
394 const char * const kwnames[] = { "mode", NULL };
395 int mode = 1;
396 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
397 discard_const_p(char *, kwnames),
398 &mode))
399 return NULL;
400 return PyString_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
403 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
405 char *name;
406 const struct ldb_val *val;
408 if (!PyArg_ParseTuple(args, "s", &name))
409 return NULL;
410 val = ldb_dn_get_extended_component(self->dn, name);
411 if (val == NULL) {
412 Py_RETURN_NONE;
415 return PyString_FromStringAndSize((const char *)val->data, val->length);
418 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
420 char *name;
421 PyObject *value;
422 int err;
424 if (!PyArg_ParseTuple(args, "sO", &name, &value))
425 return NULL;
427 if (value == Py_None) {
428 err = ldb_dn_set_extended_component(self->dn, name, NULL);
429 } else {
430 struct ldb_val val;
431 if (!PyString_Check(value)) {
432 PyErr_SetString(PyExc_TypeError, "Expected a string argument");
433 return NULL;
435 val.data = (uint8_t *)PyString_AsString(value);
436 val.length = PyString_Size(value);
437 err = ldb_dn_set_extended_component(self->dn, name, &val);
440 if (err != LDB_SUCCESS) {
441 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
442 return NULL;
445 Py_RETURN_NONE;
448 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
450 return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
453 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
455 char *name;
457 if (!PyArg_ParseTuple(args, "s", &name))
458 return NULL;
460 return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
463 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
465 int ret;
466 ret = ldb_dn_compare(dn1->dn, dn2->dn);
467 if (ret < 0) ret = -1;
468 if (ret > 0) ret = 1;
469 return ret;
472 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
474 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
475 struct ldb_dn *parent;
476 PyLdbDnObject *py_ret;
477 TALLOC_CTX *mem_ctx = talloc_new(NULL);
479 parent = ldb_dn_get_parent(mem_ctx, dn);
480 if (parent == NULL) {
481 talloc_free(mem_ctx);
482 Py_RETURN_NONE;
485 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
486 if (py_ret == NULL) {
487 PyErr_NoMemory();
488 talloc_free(mem_ctx);
489 return NULL;
491 py_ret->mem_ctx = mem_ctx;
492 py_ret->dn = parent;
493 return (PyObject *)py_ret;
496 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
498 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
500 PyObject *py_other;
501 struct ldb_dn *dn, *other;
502 if (!PyArg_ParseTuple(args, "O", &py_other))
503 return NULL;
505 dn = pyldb_Dn_AsDn((PyObject *)self);
507 if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
508 return NULL;
510 return ldb_dn_add_child(dn, other)?Py_True:Py_False;
513 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
515 PyObject *py_other;
516 struct ldb_dn *other, *dn;
517 if (!PyArg_ParseTuple(args, "O", &py_other))
518 return NULL;
520 dn = pyldb_Dn_AsDn((PyObject *)self);
522 if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
523 return NULL;
525 return ldb_dn_add_base(dn, other)?Py_True:Py_False;
528 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
530 struct ldb_dn *dn;
531 int i;
532 if (!PyArg_ParseTuple(args, "i", &i))
533 return NULL;
535 dn = pyldb_Dn_AsDn((PyObject *)self);
537 return ldb_dn_remove_base_components(dn, i)?Py_True:Py_False;
540 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
542 PyObject *py_base;
543 struct ldb_dn *dn, *base;
544 if (!PyArg_ParseTuple(args, "O", &py_base))
545 return NULL;
547 dn = pyldb_Dn_AsDn((PyObject *)self);
549 if (!pyldb_Object_AsDn(NULL, py_base, dn_ldb_ctx(dn), &base))
550 return NULL;
552 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
555 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
557 struct ldb_dn *dn;
558 const char *name;
559 unsigned int num = 0;
561 if (!PyArg_ParseTuple(args, "I", &num))
562 return NULL;
564 dn = pyldb_Dn_AsDn((PyObject *)self);
566 name = ldb_dn_get_component_name(dn, num);
567 if (name == NULL) {
568 Py_RETURN_NONE;
571 return PyString_FromString(name);
574 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
576 struct ldb_dn *dn;
577 const struct ldb_val *val;
578 unsigned int num = 0;
580 if (!PyArg_ParseTuple(args, "I", &num))
581 return NULL;
583 dn = pyldb_Dn_AsDn((PyObject *)self);
585 val = ldb_dn_get_component_val(dn, num);
586 if (val == NULL) {
587 Py_RETURN_NONE;
590 return PyObject_FromLdbValue(val);
593 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
595 unsigned int num = 0;
596 char *name = NULL;
597 PyObject *value = Py_None;
598 struct ldb_val val = { NULL, };
599 int err;
601 if (!PyArg_ParseTuple(args, "IsO", &num, &name, &value))
602 return NULL;
604 if (value != Py_None) {
605 if (!PyString_Check(value)) {
606 PyErr_SetString(PyExc_TypeError, "Expected a string argument");
607 return NULL;
609 val.data = (uint8_t *)PyString_AsString(value);
610 val.length = PyString_Size(value);
613 err = ldb_dn_set_component(self->dn, num, name, val);
614 if (err != LDB_SUCCESS) {
615 PyErr_SetString(PyExc_TypeError, "Failed to set component");
616 return NULL;
619 Py_RETURN_NONE;
622 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
624 struct ldb_dn *dn;
625 const char *name;
627 dn = pyldb_Dn_AsDn((PyObject *)self);
629 name = ldb_dn_get_rdn_name(dn);
630 if (name == NULL) {
631 Py_RETURN_NONE;
634 return PyString_FromString(name);
637 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
639 struct ldb_dn *dn;
640 const struct ldb_val *val;
642 dn = pyldb_Dn_AsDn((PyObject *)self);
644 val = ldb_dn_get_rdn_val(dn);
645 if (val == NULL) {
646 Py_RETURN_NONE;
649 return PyObject_FromLdbValue(val);
652 static PyMethodDef py_ldb_dn_methods[] = {
653 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
654 "S.validate() -> bool\n"
655 "Validate DN is correct." },
656 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
657 "S.is_valid() -> bool\n" },
658 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
659 "S.is_special() -> bool\n"
660 "Check whether this is a special LDB DN." },
661 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
662 "Check whether this is a null DN." },
663 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
664 NULL },
665 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
666 NULL },
667 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
668 "S.canonical_str() -> string\n"
669 "Canonical version of this DN (like a posix path)." },
670 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
671 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
672 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
673 "S.canonical_ex_str() -> string\n"
674 "Canonical version of this DN (like a posix path, with terminating newline)." },
675 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
676 "S.extended_str(mode=1) -> string\n"
677 "Extended version of this DN" },
678 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
679 "S.parent() -> dn\n"
680 "Get the parent for this DN." },
681 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
682 "S.add_child(dn) -> None\n"
683 "Add a child DN to this DN." },
684 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
685 "S.add_base(dn) -> None\n"
686 "Add a base DN to this DN." },
687 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
688 "S.remove_base_components(int) -> bool\n"
689 "Remove a number of DN components from the base of this DN." },
690 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
691 "S.check_special(name) -> bool\n\n"
692 "Check if name is a special DN name"},
693 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
694 "S.get_extended_component(name) -> string\n\n"
695 "returns a DN extended component as a binary string"},
696 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
697 "S.set_extended_component(name, value) -> None\n\n"
698 "set a DN extended component as a binary string"},
699 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
700 "S.get_component_name(num) -> string\n"
701 "get the attribute name of the specified component" },
702 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
703 "S.get_component_value(num) -> string\n"
704 "get the attribute value of the specified component as a binary string" },
705 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
706 "S.get_component_value(num, name, value) -> None\n"
707 "set the attribute name and value of the specified component" },
708 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
709 "S.get_rdn_name() -> string\n"
710 "get the RDN attribute name" },
711 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
712 "S.get_rdn_value() -> string\n"
713 "get the RDN attribute value as a binary string" },
714 { NULL }
717 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
719 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
723 copy a DN as a python object
725 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
727 PyLdbDnObject *py_ret;
729 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
730 if (py_ret == NULL) {
731 PyErr_NoMemory();
732 return NULL;
734 py_ret->mem_ctx = talloc_new(NULL);
735 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
736 return (PyObject *)py_ret;
739 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
741 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
742 *other;
743 PyLdbDnObject *py_ret;
745 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
746 return NULL;
748 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
749 if (py_ret == NULL) {
750 PyErr_NoMemory();
751 return NULL;
753 py_ret->mem_ctx = talloc_new(NULL);
754 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
755 ldb_dn_add_base(py_ret->dn, other);
756 return (PyObject *)py_ret;
759 static PySequenceMethods py_ldb_dn_seq = {
760 .sq_length = (lenfunc)py_ldb_dn_len,
761 .sq_concat = (binaryfunc)py_ldb_dn_concat,
764 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
766 struct ldb_dn *ret;
767 char *str;
768 PyObject *py_ldb;
769 struct ldb_context *ldb_ctx;
770 TALLOC_CTX *mem_ctx;
771 PyLdbDnObject *py_ret;
772 const char * const kwnames[] = { "ldb", "dn", NULL };
774 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
775 discard_const_p(char *, kwnames),
776 &py_ldb, &str))
777 return NULL;
779 if (!PyLdb_Check(py_ldb)) {
780 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
781 return NULL;
784 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
786 mem_ctx = talloc_new(NULL);
787 if (mem_ctx == NULL) {
788 PyErr_NoMemory();
789 return NULL;
792 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
793 if (!ldb_dn_validate(ret)) {
794 talloc_free(mem_ctx);
795 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
796 return NULL;
799 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
800 if (ret == NULL) {
801 talloc_free(mem_ctx);
802 PyErr_NoMemory();
803 return NULL;
805 py_ret->mem_ctx = mem_ctx;
806 py_ret->dn = ret;
807 return (PyObject *)py_ret;
810 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
812 talloc_free(self->mem_ctx);
813 PyObject_Del(self);
816 static PyTypeObject PyLdbDn = {
817 .tp_name = "ldb.Dn",
818 .tp_methods = py_ldb_dn_methods,
819 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
820 .tp_repr = (reprfunc)py_ldb_dn_repr,
821 .tp_compare = (cmpfunc)py_ldb_dn_compare,
822 .tp_as_sequence = &py_ldb_dn_seq,
823 .tp_doc = "A LDB distinguished name.",
824 .tp_new = py_ldb_dn_new,
825 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
826 .tp_basicsize = sizeof(PyLdbDnObject),
827 .tp_flags = Py_TPFLAGS_DEFAULT,
830 /* Debug */
831 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
832 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
834 PyObject *fn = (PyObject *)context;
835 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
838 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
840 PyObject *cb;
841 struct ldb_context *ldb_ctx;
843 if (!PyArg_ParseTuple(args, "O", &cb))
844 return NULL;
846 Py_INCREF(cb);
847 /* FIXME: Where do we DECREF cb ? */
848 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
849 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
850 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
851 ldb_ctx);
853 Py_RETURN_NONE;
856 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
858 unsigned int perms;
859 if (!PyArg_ParseTuple(args, "I", &perms))
860 return NULL;
862 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
864 Py_RETURN_NONE;
867 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
869 char *modules_dir;
870 if (!PyArg_ParseTuple(args, "s", &modules_dir))
871 return NULL;
873 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
875 Py_RETURN_NONE;
878 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
880 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
881 int ldb_err;
882 ldb_err = ldb_transaction_start(ldb_ctx);
883 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
884 Py_RETURN_NONE;
887 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
889 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
890 int ldb_err;
891 ldb_err = ldb_transaction_commit(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_prepare_commit(PyLdbObject *self)
898 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
899 int ldb_err;
900 ldb_err = ldb_transaction_prepare_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_cancel(PyLdbObject *self)
907 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
908 int ldb_err;
909 ldb_err = ldb_transaction_cancel(ldb_ctx);
910 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
911 Py_RETURN_NONE;
914 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
916 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
917 int ldb_err;
918 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
919 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
920 Py_RETURN_NONE;
923 static PyObject *py_ldb_repr(PyLdbObject *self)
925 return PyString_FromFormat("<ldb connection>");
928 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
930 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
931 if (dn == NULL)
932 Py_RETURN_NONE;
933 return py_ldb_dn_copy(dn);
937 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
939 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
940 if (dn == NULL)
941 Py_RETURN_NONE;
942 return py_ldb_dn_copy(dn);
945 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
947 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
948 if (dn == NULL)
949 Py_RETURN_NONE;
950 return py_ldb_dn_copy(dn);
953 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
955 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
956 if (dn == NULL)
957 Py_RETURN_NONE;
958 return py_ldb_dn_copy(dn);
961 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
962 const char *paramname)
964 const char **ret;
965 Py_ssize_t i;
966 if (!PyList_Check(list)) {
967 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
968 return NULL;
970 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
971 if (ret == NULL) {
972 PyErr_NoMemory();
973 return NULL;
976 for (i = 0; i < PyList_Size(list); i++) {
977 PyObject *item = PyList_GetItem(list, i);
978 if (!PyString_Check(item)) {
979 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
980 return NULL;
982 ret[i] = talloc_strndup(ret, PyString_AsString(item),
983 PyString_Size(item));
985 ret[i] = NULL;
986 return ret;
989 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
991 const char * const kwnames[] = { "url", "flags", "options", NULL };
992 char *url = NULL;
993 PyObject *py_options = Py_None;
994 const char **options;
995 unsigned int flags = 0;
996 int ret;
997 struct ldb_context *ldb;
999 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1000 discard_const_p(char *, kwnames),
1001 &url, &flags, &py_options))
1002 return -1;
1004 ldb = pyldb_Ldb_AsLdbContext(self);
1006 if (py_options == Py_None) {
1007 options = NULL;
1008 } else {
1009 options = PyList_AsStringList(ldb, py_options, "options");
1010 if (options == NULL)
1011 return -1;
1014 if (url != NULL) {
1015 ret = ldb_connect(ldb, url, flags, options);
1016 if (ret != LDB_SUCCESS) {
1017 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1018 return -1;
1022 talloc_free(options);
1023 return 0;
1026 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1028 PyLdbObject *ret;
1029 struct ldb_context *ldb;
1030 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1031 if (ret == NULL) {
1032 PyErr_NoMemory();
1033 return NULL;
1035 ret->mem_ctx = talloc_new(NULL);
1036 ldb = ldb_init(ret->mem_ctx, NULL);
1038 if (ldb == NULL) {
1039 PyErr_NoMemory();
1040 return NULL;
1043 ret->ldb_ctx = ldb;
1044 return (PyObject *)ret;
1047 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1049 char *url;
1050 unsigned int flags = 0;
1051 PyObject *py_options = Py_None;
1052 int ret;
1053 const char **options;
1054 const char * const kwnames[] = { "url", "flags", "options", NULL };
1055 struct ldb_context *ldb_ctx;
1057 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
1058 discard_const_p(char *, kwnames),
1059 &url, &flags, &py_options))
1060 return NULL;
1062 if (py_options == Py_None) {
1063 options = NULL;
1064 } else {
1065 options = PyList_AsStringList(NULL, py_options, "options");
1066 if (options == NULL)
1067 return NULL;
1070 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1071 ret = ldb_connect(ldb_ctx, url, flags, options);
1072 talloc_free(options);
1074 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1076 Py_RETURN_NONE;
1079 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1081 PyObject *py_msg;
1082 PyObject *py_controls = Py_None;
1083 struct ldb_context *ldb_ctx;
1084 struct ldb_request *req;
1085 struct ldb_control **parsed_controls;
1086 struct ldb_message *msg;
1087 int ret;
1088 TALLOC_CTX *mem_ctx;
1089 bool validate=true;
1090 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1092 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1093 discard_const_p(char *, kwnames),
1094 &py_msg, &py_controls, &validate))
1095 return NULL;
1097 mem_ctx = talloc_new(NULL);
1098 if (mem_ctx == NULL) {
1099 PyErr_NoMemory();
1100 return NULL;
1102 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1104 if (py_controls == Py_None) {
1105 parsed_controls = NULL;
1106 } else {
1107 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1108 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1109 talloc_free(controls);
1112 if (!PyLdbMessage_Check(py_msg)) {
1113 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1114 talloc_free(mem_ctx);
1115 return NULL;
1117 msg = pyldb_Message_AsMessage(py_msg);
1119 if (validate) {
1120 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1121 if (ret != LDB_SUCCESS) {
1122 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1123 talloc_free(mem_ctx);
1124 return NULL;
1128 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1129 NULL, ldb_op_default_callback, NULL);
1130 if (ret != LDB_SUCCESS) {
1131 PyErr_SetString(PyExc_TypeError, "failed to build request");
1132 talloc_free(mem_ctx);
1133 return NULL;
1136 /* do request and autostart a transaction */
1137 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1139 ret = ldb_transaction_start(ldb_ctx);
1140 if (ret != LDB_SUCCESS) {
1141 talloc_free(mem_ctx);
1142 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1143 return NULL;
1146 ret = ldb_request(ldb_ctx, req);
1147 if (ret == LDB_SUCCESS) {
1148 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1151 if (ret == LDB_SUCCESS) {
1152 ret = ldb_transaction_commit(ldb_ctx);
1153 } else {
1154 ldb_transaction_cancel(ldb_ctx);
1157 talloc_free(mem_ctx);
1158 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1160 Py_RETURN_NONE;
1165 * Obtain a ldb message from a Python Dictionary object.
1167 * @param mem_ctx Memory context
1168 * @param py_obj Python Dictionary object
1169 * @param ldb_ctx LDB context
1170 * @param mod_flags Flags to be set on every message element
1171 * @return ldb_message on success or NULL on failure
1173 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1174 PyObject *py_obj,
1175 struct ldb_context *ldb_ctx,
1176 unsigned int mod_flags)
1178 struct ldb_message *msg;
1179 unsigned int msg_pos = 0;
1180 Py_ssize_t dict_pos = 0;
1181 PyObject *key, *value;
1182 struct ldb_message_element *msg_el;
1183 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1185 msg = ldb_msg_new(mem_ctx);
1186 if (msg == NULL) {
1187 PyErr_NoMemory();
1188 return NULL;
1190 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1192 if (dn_value) {
1193 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1194 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1195 return NULL;
1197 if (msg->dn == NULL) {
1198 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1199 return NULL;
1201 } else {
1202 PyErr_SetString(PyExc_TypeError, "no dn set");
1203 return NULL;
1206 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1207 char *key_str = PyString_AsString(key);
1208 if (ldb_attr_cmp(key_str, "dn") != 0) {
1209 msg_el = PyObject_AsMessageElement(msg->elements, value,
1210 mod_flags, key_str);
1211 if (msg_el == NULL) {
1212 PyErr_SetString(PyExc_TypeError, "unable to import element");
1213 return NULL;
1215 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1216 msg_pos++;
1220 msg->num_elements = msg_pos;
1222 return msg;
1225 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1227 PyObject *py_obj;
1228 int ret;
1229 struct ldb_context *ldb_ctx;
1230 struct ldb_request *req;
1231 struct ldb_message *msg = NULL;
1232 PyObject *py_controls = Py_None;
1233 TALLOC_CTX *mem_ctx;
1234 struct ldb_control **parsed_controls;
1235 const char * const kwnames[] = { "message", "controls", NULL };
1237 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1238 discard_const_p(char *, kwnames),
1239 &py_obj, &py_controls))
1240 return NULL;
1242 mem_ctx = talloc_new(NULL);
1243 if (mem_ctx == NULL) {
1244 PyErr_NoMemory();
1245 return NULL;
1247 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1249 if (py_controls == Py_None) {
1250 parsed_controls = NULL;
1251 } else {
1252 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1253 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1254 talloc_free(controls);
1257 if (PyLdbMessage_Check(py_obj)) {
1258 msg = pyldb_Message_AsMessage(py_obj);
1259 } else if (PyDict_Check(py_obj)) {
1260 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1261 } else {
1262 PyErr_SetString(PyExc_TypeError,
1263 "Dictionary or LdbMessage object expected!");
1266 if (!msg) {
1267 /* we should have a PyErr already set */
1268 talloc_free(mem_ctx);
1269 return NULL;
1272 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1273 if (ret != LDB_SUCCESS) {
1274 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1275 talloc_free(mem_ctx);
1276 return NULL;
1279 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1280 NULL, ldb_op_default_callback, NULL);
1281 if (ret != LDB_SUCCESS) {
1282 PyErr_SetString(PyExc_TypeError, "failed to build request");
1283 talloc_free(mem_ctx);
1284 return NULL;
1287 /* do request and autostart a transaction */
1288 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1290 ret = ldb_transaction_start(ldb_ctx);
1291 if (ret != LDB_SUCCESS) {
1292 talloc_free(mem_ctx);
1293 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1294 return NULL;
1297 ret = ldb_request(ldb_ctx, req);
1298 if (ret == LDB_SUCCESS) {
1299 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1302 if (ret == LDB_SUCCESS) {
1303 ret = ldb_transaction_commit(ldb_ctx);
1304 } else {
1305 ldb_transaction_cancel(ldb_ctx);
1308 talloc_free(mem_ctx);
1309 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1311 Py_RETURN_NONE;
1314 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1316 PyObject *py_dn;
1317 struct ldb_dn *dn;
1318 int ret;
1319 struct ldb_context *ldb_ctx;
1320 struct ldb_request *req;
1321 PyObject *py_controls = Py_None;
1322 TALLOC_CTX *mem_ctx;
1323 struct ldb_control **parsed_controls;
1324 const char * const kwnames[] = { "dn", "controls", NULL };
1326 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1327 discard_const_p(char *, kwnames),
1328 &py_dn, &py_controls))
1329 return NULL;
1331 mem_ctx = talloc_new(NULL);
1332 if (mem_ctx == NULL) {
1333 PyErr_NoMemory();
1334 return NULL;
1336 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1338 if (py_controls == Py_None) {
1339 parsed_controls = NULL;
1340 } else {
1341 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1342 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1343 talloc_free(controls);
1346 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1347 talloc_free(mem_ctx);
1348 return NULL;
1351 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1352 NULL, ldb_op_default_callback, NULL);
1353 if (ret != LDB_SUCCESS) {
1354 PyErr_SetString(PyExc_TypeError, "failed to build request");
1355 talloc_free(mem_ctx);
1356 return NULL;
1359 /* do request and autostart a transaction */
1360 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1362 ret = ldb_transaction_start(ldb_ctx);
1363 if (ret != LDB_SUCCESS) {
1364 talloc_free(mem_ctx);
1365 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1366 return NULL;
1369 ret = ldb_request(ldb_ctx, req);
1370 if (ret == LDB_SUCCESS) {
1371 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1374 if (ret == LDB_SUCCESS) {
1375 ret = ldb_transaction_commit(ldb_ctx);
1376 } else {
1377 ldb_transaction_cancel(ldb_ctx);
1380 talloc_free(mem_ctx);
1381 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1383 Py_RETURN_NONE;
1386 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1388 PyObject *py_dn1, *py_dn2;
1389 struct ldb_dn *dn1, *dn2;
1390 int ret;
1391 TALLOC_CTX *mem_ctx;
1392 PyObject *py_controls = Py_None;
1393 struct ldb_control **parsed_controls;
1394 struct ldb_context *ldb_ctx;
1395 struct ldb_request *req;
1396 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1398 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1400 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1401 discard_const_p(char *, kwnames),
1402 &py_dn1, &py_dn2, &py_controls))
1403 return NULL;
1406 mem_ctx = talloc_new(NULL);
1407 if (mem_ctx == NULL) {
1408 PyErr_NoMemory();
1409 return NULL;
1412 if (py_controls == Py_None) {
1413 parsed_controls = NULL;
1414 } else {
1415 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1416 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1417 talloc_free(controls);
1421 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1422 talloc_free(mem_ctx);
1423 return NULL;
1426 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1427 talloc_free(mem_ctx);
1428 return NULL;
1431 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1432 NULL, ldb_op_default_callback, NULL);
1433 if (ret != LDB_SUCCESS) {
1434 PyErr_SetString(PyExc_TypeError, "failed to build request");
1435 talloc_free(mem_ctx);
1436 return NULL;
1439 /* do request and autostart a transaction */
1440 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1442 ret = ldb_transaction_start(ldb_ctx);
1443 if (ret != LDB_SUCCESS) {
1444 talloc_free(mem_ctx);
1445 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1446 return NULL;
1449 ret = ldb_request(ldb_ctx, req);
1450 if (ret == LDB_SUCCESS) {
1451 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1454 if (ret == LDB_SUCCESS) {
1455 ret = ldb_transaction_commit(ldb_ctx);
1456 } else {
1457 ldb_transaction_cancel(ldb_ctx);
1460 talloc_free(mem_ctx);
1461 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1463 Py_RETURN_NONE;
1466 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1468 char *name;
1469 if (!PyArg_ParseTuple(args, "s", &name))
1470 return NULL;
1472 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1474 Py_RETURN_NONE;
1477 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1479 char *attribute, *syntax;
1480 unsigned int flags;
1481 int ret;
1482 struct ldb_context *ldb_ctx;
1484 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1485 return NULL;
1487 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1488 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1490 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1492 Py_RETURN_NONE;
1495 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1497 if (ldif == NULL) {
1498 Py_RETURN_NONE;
1499 } else {
1500 /* We don't want this attached to the 'ldb' any more */
1501 return Py_BuildValue(discard_const_p(char, "(iO)"),
1502 ldif->changetype,
1503 PyLdbMessage_FromMessage(ldif->msg));
1508 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1510 int changetype;
1511 PyObject *py_msg;
1512 struct ldb_ldif ldif;
1513 PyObject *ret;
1514 char *string;
1515 TALLOC_CTX *mem_ctx;
1517 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1518 return NULL;
1520 if (!PyLdbMessage_Check(py_msg)) {
1521 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1522 return NULL;
1525 ldif.msg = pyldb_Message_AsMessage(py_msg);
1526 ldif.changetype = changetype;
1528 mem_ctx = talloc_new(NULL);
1530 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1531 if (!string) {
1532 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1533 return NULL;
1536 ret = PyString_FromString(string);
1538 talloc_free(mem_ctx);
1540 return ret;
1543 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1545 PyObject *list;
1546 struct ldb_ldif *ldif;
1547 const char *s;
1549 TALLOC_CTX *mem_ctx;
1551 if (!PyArg_ParseTuple(args, "s", &s))
1552 return NULL;
1554 mem_ctx = talloc_new(NULL);
1555 if (!mem_ctx) {
1556 Py_RETURN_NONE;
1559 list = PyList_New(0);
1560 while (s && *s != '\0') {
1561 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1562 talloc_steal(mem_ctx, ldif);
1563 if (ldif) {
1564 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1565 } else {
1566 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1567 talloc_free(mem_ctx);
1568 return NULL;
1571 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1572 return PyObject_GetIter(list);
1575 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1577 int ldb_ret;
1578 PyObject *py_msg_old;
1579 PyObject *py_msg_new;
1580 struct ldb_message *diff;
1581 struct ldb_context *ldb;
1582 PyObject *py_ret;
1584 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1585 return NULL;
1587 if (!PyLdbMessage_Check(py_msg_old)) {
1588 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1589 return NULL;
1592 if (!PyLdbMessage_Check(py_msg_new)) {
1593 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1594 return NULL;
1597 ldb = pyldb_Ldb_AsLdbContext(self);
1598 ldb_ret = ldb_msg_difference(ldb, ldb,
1599 pyldb_Message_AsMessage(py_msg_old),
1600 pyldb_Message_AsMessage(py_msg_new),
1601 &diff);
1602 if (ldb_ret != LDB_SUCCESS) {
1603 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1604 return NULL;
1607 py_ret = PyLdbMessage_FromMessage(diff);
1609 talloc_unlink(ldb, diff);
1611 return py_ret;
1614 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1616 const struct ldb_schema_attribute *a;
1617 struct ldb_val old_val;
1618 struct ldb_val new_val;
1619 TALLOC_CTX *mem_ctx;
1620 PyObject *ret;
1621 char *element_name;
1622 PyObject *val;
1624 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1625 return NULL;
1627 old_val.data = (uint8_t *)PyString_AsString(val);
1628 old_val.length = PyString_Size(val);
1630 if (old_val.data == NULL) {
1631 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1632 return NULL;
1635 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1637 if (a == NULL) {
1638 Py_RETURN_NONE;
1641 mem_ctx = talloc_new(NULL);
1642 if (mem_ctx == NULL) {
1643 PyErr_NoMemory();
1644 return NULL;
1647 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1648 talloc_free(mem_ctx);
1649 Py_RETURN_NONE;
1652 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1654 talloc_free(mem_ctx);
1656 return ret;
1659 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1661 PyObject *py_base = Py_None;
1662 int scope = LDB_SCOPE_DEFAULT;
1663 char *expr = NULL;
1664 PyObject *py_attrs = Py_None;
1665 PyObject *py_controls = Py_None;
1666 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1667 int ret;
1668 struct ldb_result *res;
1669 struct ldb_request *req;
1670 const char **attrs;
1671 struct ldb_context *ldb_ctx;
1672 struct ldb_control **parsed_controls;
1673 struct ldb_dn *base;
1674 PyObject *py_ret;
1675 TALLOC_CTX *mem_ctx;
1677 /* type "int" rather than "enum" for "scope" is intentional */
1678 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1679 discard_const_p(char *, kwnames),
1680 &py_base, &scope, &expr, &py_attrs, &py_controls))
1681 return NULL;
1684 mem_ctx = talloc_new(NULL);
1685 if (mem_ctx == NULL) {
1686 PyErr_NoMemory();
1687 return NULL;
1689 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1691 if (py_attrs == Py_None) {
1692 attrs = NULL;
1693 } else {
1694 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1695 if (attrs == NULL) {
1696 talloc_free(mem_ctx);
1697 return NULL;
1701 if (py_base == Py_None) {
1702 base = ldb_get_default_basedn(ldb_ctx);
1703 } else {
1704 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1705 talloc_free(attrs);
1706 return NULL;
1710 if (py_controls == Py_None) {
1711 parsed_controls = NULL;
1712 } else {
1713 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1714 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1715 talloc_free(controls);
1718 res = talloc_zero(mem_ctx, struct ldb_result);
1719 if (res == NULL) {
1720 PyErr_NoMemory();
1721 talloc_free(mem_ctx);
1722 return NULL;
1725 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1726 base,
1727 scope,
1728 expr,
1729 attrs,
1730 parsed_controls,
1731 res,
1732 ldb_search_default_callback,
1733 NULL);
1735 if (ret != LDB_SUCCESS) {
1736 talloc_free(mem_ctx);
1737 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1738 return NULL;
1741 talloc_steal(req, attrs);
1743 ret = ldb_request(ldb_ctx, req);
1745 if (ret == LDB_SUCCESS) {
1746 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1749 if (ret != LDB_SUCCESS) {
1750 talloc_free(mem_ctx);
1751 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1752 return NULL;
1755 py_ret = PyLdbResult_FromResult(res);
1757 talloc_free(mem_ctx);
1759 return py_ret;
1762 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1764 char *name;
1765 void *data;
1767 if (!PyArg_ParseTuple(args, "s", &name))
1768 return NULL;
1770 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1772 if (data == NULL)
1773 Py_RETURN_NONE;
1775 /* FIXME: More interpretation */
1777 return Py_True;
1780 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1782 char *name;
1783 PyObject *data;
1785 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1786 return NULL;
1788 /* FIXME: More interpretation */
1790 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1792 Py_RETURN_NONE;
1795 static PyObject *py_ldb_modules(PyLdbObject *self)
1797 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1798 PyObject *ret = PyList_New(0);
1799 struct ldb_module *mod;
1801 for (mod = ldb->modules; mod; mod = mod->next) {
1802 PyList_Append(ret, PyLdbModule_FromModule(mod));
1805 return ret;
1808 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1810 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1811 int type, ret;
1812 uint64_t value;
1814 if (!PyArg_ParseTuple(args, "i", &type))
1815 return NULL;
1817 /* FIXME: More interpretation */
1819 ret = ldb_sequence_number(ldb, type, &value);
1821 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1823 return PyLong_FromLongLong(value);
1825 static PyMethodDef py_ldb_methods[] = {
1826 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1827 "S.set_debug(callback) -> None\n"
1828 "Set callback for LDB debug messages.\n"
1829 "The callback should accept a debug level and debug text." },
1830 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1831 "S.set_create_perms(mode) -> None\n"
1832 "Set mode to use when creating new LDB files." },
1833 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1834 "S.set_modules_dir(path) -> None\n"
1835 "Set path LDB should search for modules" },
1836 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1837 "S.transaction_start() -> None\n"
1838 "Start a new transaction." },
1839 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1840 "S.transaction_prepare_commit() -> None\n"
1841 "prepare to commit a new transaction (2-stage commit)." },
1842 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1843 "S.transaction_commit() -> None\n"
1844 "commit a new transaction." },
1845 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1846 "S.transaction_cancel() -> None\n"
1847 "cancel a new transaction." },
1848 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1849 NULL },
1850 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1851 NULL },
1852 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1853 NULL },
1854 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1855 NULL },
1856 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1857 NULL },
1858 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1859 "S.connect(url, flags=0, options=None) -> None\n"
1860 "Connect to a LDB URL." },
1861 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1862 "S.modify(message, controls=None, validate=False) -> None\n"
1863 "Modify an entry." },
1864 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1865 "S.add(message, controls=None) -> None\n"
1866 "Add an entry." },
1867 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1868 "S.delete(dn, controls=None) -> None\n"
1869 "Remove an entry." },
1870 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1871 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1872 "Rename an entry." },
1873 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1874 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1875 "Search in a database.\n"
1876 "\n"
1877 ":param base: Optional base DN to search\n"
1878 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1879 ":param expression: Optional search expression\n"
1880 ":param attrs: Attributes to return (defaults to all)\n"
1881 ":param controls: Optional list of controls\n"
1882 ":return: Iterator over Message objects\n"
1884 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1885 NULL },
1886 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1887 NULL },
1888 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1889 NULL },
1890 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1891 "S.parse_ldif(ldif) -> iter(messages)\n"
1892 "Parse a string formatted using LDIF." },
1893 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1894 "S.write_ldif(message, changetype) -> ldif\n"
1895 "Print the message as a string formatted using LDIF." },
1896 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1897 "S.msg_diff(Message) -> Message\n"
1898 "Return an LDB Message of the difference between two Message objects." },
1899 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1900 "S.get_opaque(name) -> value\n"
1901 "Get an opaque value set on this LDB connection. \n"
1902 ":note: The returned value may not be useful in Python."
1904 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1905 "S.set_opaque(name, value) -> None\n"
1906 "Set an opaque value on this LDB connection. \n"
1907 ":note: Passing incorrect values may cause crashes." },
1908 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1909 "S.modules() -> list\n"
1910 "Return the list of modules on this LDB connection " },
1911 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1912 "S.sequence_number(type) -> value\n"
1913 "Return the value of the sequence according to the requested type" },
1914 { NULL },
1917 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1919 PyLdbModuleObject *ret;
1921 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1922 if (ret == NULL) {
1923 PyErr_NoMemory();
1924 return NULL;
1926 ret->mem_ctx = talloc_new(NULL);
1927 ret->mod = talloc_reference(ret->mem_ctx, mod);
1928 return (PyObject *)ret;
1931 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1933 return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1936 static PyGetSetDef py_ldb_getset[] = {
1937 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1938 { NULL }
1941 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1943 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1944 struct ldb_dn *dn;
1945 struct ldb_result *result;
1946 unsigned int count;
1947 int ret;
1949 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1950 return -1;
1953 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1954 NULL);
1955 if (ret != LDB_SUCCESS) {
1956 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1957 return -1;
1960 count = result->count;
1962 talloc_free(result);
1964 if (count > 1) {
1965 PyErr_Format(PyExc_RuntimeError,
1966 "Searching for [%s] dn gave %u results!",
1967 ldb_dn_get_linearized(dn),
1968 count);
1969 return -1;
1972 return count;
1975 static PySequenceMethods py_ldb_seq = {
1976 .sq_contains = (objobjproc)py_ldb_contains,
1979 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1981 PyLdbObject *ret;
1983 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1984 if (ret == NULL) {
1985 PyErr_NoMemory();
1986 return NULL;
1988 ret->mem_ctx = talloc_new(NULL);
1989 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1990 return (PyObject *)ret;
1993 static void py_ldb_dealloc(PyLdbObject *self)
1995 talloc_free(self->mem_ctx);
1996 self->ob_type->tp_free(self);
1999 static PyTypeObject PyLdb = {
2000 .tp_name = "ldb.Ldb",
2001 .tp_methods = py_ldb_methods,
2002 .tp_repr = (reprfunc)py_ldb_repr,
2003 .tp_new = py_ldb_new,
2004 .tp_init = (initproc)py_ldb_init,
2005 .tp_dealloc = (destructor)py_ldb_dealloc,
2006 .tp_getset = py_ldb_getset,
2007 .tp_getattro = PyObject_GenericGetAttr,
2008 .tp_basicsize = sizeof(PyLdbObject),
2009 .tp_doc = "Connection to a LDB database.",
2010 .tp_as_sequence = &py_ldb_seq,
2011 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2014 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2016 talloc_free(self->mem_ctx);
2017 Py_DECREF(self->msgs);
2018 Py_DECREF(self->referals);
2019 Py_DECREF(self->controls);
2020 self->ob_type->tp_free(self);
2023 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2025 Py_INCREF(self->msgs);
2026 return self->msgs;
2029 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2031 Py_INCREF(self->controls);
2032 return self->controls;
2035 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2037 Py_INCREF(self->referals);
2038 return self->referals;
2041 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2043 Py_ssize_t size;
2044 if (self->msgs == NULL) {
2045 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2046 return NULL;
2048 size = PyList_Size(self->msgs);
2049 return PyInt_FromLong(size);
2052 static PyGetSetDef py_ldb_result_getset[] = {
2053 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2054 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2055 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2056 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2057 { NULL }
2060 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2062 return PyObject_GetIter(self->msgs);
2065 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2067 return PySequence_Size(self->msgs);
2070 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2072 return PySequence_GetItem(self->msgs, idx);
2075 static PySequenceMethods py_ldb_result_seq = {
2076 .sq_length = (lenfunc)py_ldb_result_len,
2077 .sq_item = (ssizeargfunc)py_ldb_result_find,
2080 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2082 return PyString_FromFormat("<ldb result>");
2086 static PyTypeObject PyLdbResult = {
2087 .tp_name = "ldb.Result",
2088 .tp_repr = (reprfunc)py_ldb_result_repr,
2089 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2090 .tp_iter = (getiterfunc)py_ldb_result_iter,
2091 .tp_getset = py_ldb_result_getset,
2092 .tp_getattro = PyObject_GenericGetAttr,
2093 .tp_basicsize = sizeof(PyLdbResultObject),
2094 .tp_as_sequence = &py_ldb_result_seq,
2095 .tp_doc = "LDB result.",
2096 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2099 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2101 return PyString_FromFormat("<ldb module '%s'>",
2102 pyldb_Module_AsModule(self)->ops->name);
2105 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2107 return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
2110 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2112 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2113 Py_RETURN_NONE;
2116 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2118 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2119 Py_RETURN_NONE;
2122 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2124 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2125 Py_RETURN_NONE;
2128 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2130 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2131 int ret, scope;
2132 struct ldb_request *req;
2133 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2134 struct ldb_module *mod;
2135 const char * const*attrs;
2137 /* type "int" rather than "enum" for "scope" is intentional */
2138 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
2139 discard_const_p(char *, kwnames),
2140 &py_base, &scope, &py_tree, &py_attrs))
2141 return NULL;
2143 mod = self->mod;
2145 if (py_attrs == Py_None) {
2146 attrs = NULL;
2147 } else {
2148 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
2149 if (attrs == NULL)
2150 return NULL;
2153 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2154 scope, NULL /* expr */, attrs,
2155 NULL /* controls */, NULL, NULL, NULL);
2157 talloc_steal(req, attrs);
2159 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2161 req->op.search.res = NULL;
2163 ret = mod->ops->search(mod, req);
2165 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2167 py_ret = PyLdbResult_FromResult(req->op.search.res);
2169 talloc_free(req);
2171 return py_ret;
2175 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2177 struct ldb_request *req;
2178 PyObject *py_message;
2179 int ret;
2180 struct ldb_module *mod;
2182 if (!PyArg_ParseTuple(args, "O", &py_message))
2183 return NULL;
2185 req = talloc_zero(NULL, struct ldb_request);
2186 req->operation = LDB_ADD;
2187 req->op.add.message = pyldb_Message_AsMessage(py_message);
2189 mod = pyldb_Module_AsModule(self);
2190 ret = mod->ops->add(mod, req);
2192 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2194 Py_RETURN_NONE;
2197 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2199 int ret;
2200 struct ldb_request *req;
2201 PyObject *py_message;
2202 struct ldb_module *mod;
2204 if (!PyArg_ParseTuple(args, "O", &py_message))
2205 return NULL;
2207 req = talloc_zero(NULL, struct ldb_request);
2208 req->operation = LDB_MODIFY;
2209 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2211 mod = pyldb_Module_AsModule(self);
2212 ret = mod->ops->modify(mod, req);
2214 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2216 Py_RETURN_NONE;
2219 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2221 int ret;
2222 struct ldb_request *req;
2223 PyObject *py_dn;
2225 if (!PyArg_ParseTuple(args, "O", &py_dn))
2226 return NULL;
2228 req = talloc_zero(NULL, struct ldb_request);
2229 req->operation = LDB_DELETE;
2230 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2232 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2234 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2236 Py_RETURN_NONE;
2239 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2241 int ret;
2242 struct ldb_request *req;
2243 PyObject *py_dn1, *py_dn2;
2245 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
2246 return NULL;
2248 req = talloc_zero(NULL, struct ldb_request);
2250 req->operation = LDB_RENAME;
2251 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2252 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2254 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2256 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2258 Py_RETURN_NONE;
2261 static PyMethodDef py_ldb_module_methods[] = {
2262 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2263 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2264 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2265 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2266 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2267 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2268 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2269 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2270 { NULL },
2273 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2275 talloc_free(self->mem_ctx);
2276 PyObject_Del(self);
2279 static PyTypeObject PyLdbModule = {
2280 .tp_name = "ldb.LdbModule",
2281 .tp_methods = py_ldb_module_methods,
2282 .tp_repr = (reprfunc)py_ldb_module_repr,
2283 .tp_str = (reprfunc)py_ldb_module_str,
2284 .tp_basicsize = sizeof(PyLdbModuleObject),
2285 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2286 .tp_flags = Py_TPFLAGS_DEFAULT,
2287 .tp_doc = "LDB module (extension)",
2292 * Create a ldb_message_element from a Python object.
2294 * This will accept any sequence objects that contains strings, or
2295 * a string object.
2297 * A reference to set_obj will be borrowed.
2299 * @param mem_ctx Memory context
2300 * @param set_obj Python object to convert
2301 * @param flags ldb_message_element flags to set
2302 * @param attr_name Name of the attribute
2303 * @return New ldb_message_element, allocated as child of mem_ctx
2305 static struct ldb_message_element *PyObject_AsMessageElement(
2306 TALLOC_CTX *mem_ctx,
2307 PyObject *set_obj,
2308 unsigned int flags,
2309 const char *attr_name)
2311 struct ldb_message_element *me;
2313 if (pyldb_MessageElement_Check(set_obj)) {
2314 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2315 /* We have to talloc_reference() the memory context, not the pointer
2316 * which may not actually be it's own context */
2317 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2318 return pyldb_MessageElement_AsMessageElement(set_obj);
2320 return NULL;
2323 me = talloc(mem_ctx, struct ldb_message_element);
2324 if (me == NULL) {
2325 PyErr_NoMemory();
2326 return NULL;
2329 me->name = talloc_strdup(me, attr_name);
2330 me->flags = flags;
2331 if (PyString_Check(set_obj)) {
2332 me->num_values = 1;
2333 me->values = talloc_array(me, struct ldb_val, me->num_values);
2334 me->values[0].length = PyString_Size(set_obj);
2335 me->values[0].data = talloc_memdup(me,
2336 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2337 } else if (PySequence_Check(set_obj)) {
2338 Py_ssize_t i;
2339 me->num_values = PySequence_Size(set_obj);
2340 me->values = talloc_array(me, struct ldb_val, me->num_values);
2341 for (i = 0; i < me->num_values; i++) {
2342 PyObject *obj = PySequence_GetItem(set_obj, i);
2343 if (!PyString_Check(obj)) {
2344 PyErr_Format(PyExc_TypeError,
2345 "Expected string as element %zd in list", i);
2346 talloc_free(me);
2347 return NULL;
2350 me->values[i].length = PyString_Size(obj);
2351 me->values[i].data = talloc_memdup(me,
2352 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2354 } else {
2355 PyErr_Format(PyExc_TypeError,
2356 "String or List type expected for '%s' attribute", attr_name);
2357 talloc_free(me);
2358 me = NULL;
2361 return me;
2365 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2366 struct ldb_message_element *me)
2368 Py_ssize_t i;
2369 PyObject *result;
2371 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2372 result = PyList_New(me->num_values);
2374 for (i = 0; i < me->num_values; i++) {
2375 PyList_SetItem(result, i,
2376 PyObject_FromLdbValue(&me->values[i]));
2379 return result;
2382 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2384 unsigned int i;
2385 if (!PyArg_ParseTuple(args, "I", &i))
2386 return NULL;
2387 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2388 Py_RETURN_NONE;
2390 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2393 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2395 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2396 return PyInt_FromLong(el->flags);
2399 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2401 unsigned int flags;
2402 struct ldb_message_element *el;
2403 if (!PyArg_ParseTuple(args, "I", &flags))
2404 return NULL;
2406 el = pyldb_MessageElement_AsMessageElement(self);
2407 el->flags = flags;
2408 Py_RETURN_NONE;
2411 static PyMethodDef py_ldb_msg_element_methods[] = {
2412 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2413 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2414 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2415 { NULL },
2418 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2420 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2423 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2425 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2426 if (idx < 0 || idx >= el->num_values) {
2427 PyErr_SetString(PyExc_IndexError, "Out of range");
2428 return NULL;
2430 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2433 static PySequenceMethods py_ldb_msg_element_seq = {
2434 .sq_length = (lenfunc)py_ldb_msg_element_len,
2435 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2438 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2440 int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2441 pyldb_MessageElement_AsMessageElement(other));
2442 return SIGN(ret);
2445 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2447 PyObject *el = ldb_msg_element_to_set(NULL,
2448 pyldb_MessageElement_AsMessageElement(self));
2449 return PyObject_GetIter(el);
2452 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2454 PyLdbMessageElementObject *ret;
2455 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2456 if (ret == NULL) {
2457 PyErr_NoMemory();
2458 return NULL;
2460 ret->mem_ctx = talloc_new(NULL);
2461 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2462 PyErr_NoMemory();
2463 return NULL;
2465 ret->el = el;
2466 return (PyObject *)ret;
2469 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2471 PyObject *py_elements = NULL;
2472 struct ldb_message_element *el;
2473 unsigned int flags = 0;
2474 char *name = NULL;
2475 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2476 PyLdbMessageElementObject *ret;
2477 TALLOC_CTX *mem_ctx;
2479 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2480 discard_const_p(char *, kwnames),
2481 &py_elements, &flags, &name))
2482 return NULL;
2484 mem_ctx = talloc_new(NULL);
2485 if (mem_ctx == NULL) {
2486 PyErr_NoMemory();
2487 return NULL;
2490 el = talloc_zero(mem_ctx, struct ldb_message_element);
2491 if (el == NULL) {
2492 PyErr_NoMemory();
2493 talloc_free(mem_ctx);
2494 return NULL;
2497 if (py_elements != NULL) {
2498 Py_ssize_t i;
2499 if (PyString_Check(py_elements)) {
2500 el->num_values = 1;
2501 el->values = talloc_array(el, struct ldb_val, 1);
2502 if (el->values == NULL) {
2503 talloc_free(mem_ctx);
2504 PyErr_NoMemory();
2505 return NULL;
2507 el->values[0].length = PyString_Size(py_elements);
2508 el->values[0].data = talloc_memdup(el->values,
2509 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2510 } else if (PySequence_Check(py_elements)) {
2511 el->num_values = PySequence_Size(py_elements);
2512 el->values = talloc_array(el, struct ldb_val, el->num_values);
2513 if (el->values == NULL) {
2514 talloc_free(mem_ctx);
2515 PyErr_NoMemory();
2516 return NULL;
2518 for (i = 0; i < el->num_values; i++) {
2519 PyObject *item = PySequence_GetItem(py_elements, i);
2520 if (item == NULL) {
2521 talloc_free(mem_ctx);
2522 return NULL;
2524 if (!PyString_Check(item)) {
2525 PyErr_Format(PyExc_TypeError,
2526 "Expected string as element %zd in list", i);
2527 talloc_free(mem_ctx);
2528 return NULL;
2530 el->values[i].length = PyString_Size(item);
2531 el->values[i].data = talloc_memdup(el,
2532 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2534 } else {
2535 PyErr_SetString(PyExc_TypeError,
2536 "Expected string or list");
2537 talloc_free(mem_ctx);
2538 return NULL;
2542 el->flags = flags;
2543 el->name = talloc_strdup(el, name);
2545 ret = PyObject_New(PyLdbMessageElementObject, type);
2546 if (ret == NULL) {
2547 talloc_free(mem_ctx);
2548 return NULL;
2551 ret->mem_ctx = mem_ctx;
2552 ret->el = el;
2553 return (PyObject *)ret;
2556 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2558 char *element_str = NULL;
2559 Py_ssize_t i;
2560 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2561 PyObject *ret;
2563 for (i = 0; i < el->num_values; i++) {
2564 PyObject *o = py_ldb_msg_element_find(self, i);
2565 if (element_str == NULL)
2566 element_str = talloc_strdup(NULL, PyObject_REPR(o));
2567 else
2568 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2571 if (element_str != NULL) {
2572 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2573 talloc_free(element_str);
2574 } else {
2575 ret = PyString_FromString("MessageElement([])");
2578 return ret;
2581 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2583 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2585 if (el->num_values == 1)
2586 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2587 else
2588 Py_RETURN_NONE;
2591 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2593 talloc_free(self->mem_ctx);
2594 PyObject_Del(self);
2597 static PyTypeObject PyLdbMessageElement = {
2598 .tp_name = "ldb.MessageElement",
2599 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2600 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2601 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2602 .tp_str = (reprfunc)py_ldb_msg_element_str,
2603 .tp_methods = py_ldb_msg_element_methods,
2604 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2605 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2606 .tp_as_sequence = &py_ldb_msg_element_seq,
2607 .tp_new = py_ldb_msg_element_new,
2608 .tp_flags = Py_TPFLAGS_DEFAULT,
2609 .tp_doc = "An element of a Message",
2613 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2615 PyObject *py_ldb;
2616 PyObject *py_dict;
2617 PyObject *py_ret;
2618 struct ldb_message *msg;
2619 struct ldb_context *ldb_ctx;
2620 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2622 if (!PyArg_ParseTuple(args, "O!O!|I",
2623 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2624 &mod_flags)) {
2625 return NULL;
2628 if (!PyLdb_Check(py_ldb)) {
2629 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
2630 return NULL;
2633 /* mask only flags we are going to use */
2634 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2635 if (!mod_flags) {
2636 PyErr_SetString(PyExc_ValueError,
2637 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2638 " expected as mod_flag value");
2639 return NULL;
2642 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2644 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2645 if (!msg) {
2646 return NULL;
2649 py_ret = PyLdbMessage_FromMessage(msg);
2651 talloc_unlink(ldb_ctx, msg);
2653 return py_ret;
2656 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2658 char *name;
2659 if (!PyArg_ParseTuple(args, "s", &name))
2660 return NULL;
2662 ldb_msg_remove_attr(self->msg, name);
2664 Py_RETURN_NONE;
2667 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2669 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2670 Py_ssize_t i, j = 0;
2671 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2672 if (msg->dn != NULL) {
2673 PyList_SetItem(obj, j, PyString_FromString("dn"));
2674 j++;
2676 for (i = 0; i < msg->num_elements; i++) {
2677 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2678 j++;
2680 return obj;
2683 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2685 struct ldb_message_element *el;
2686 char *name;
2687 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2688 if (!PyString_Check(py_name)) {
2689 PyErr_SetNone(PyExc_TypeError);
2690 return NULL;
2692 name = PyString_AsString(py_name);
2693 if (!ldb_attr_cmp(name, "dn"))
2694 return pyldb_Dn_FromDn(msg->dn);
2695 el = ldb_msg_find_element(msg, name);
2696 if (el == NULL) {
2697 return NULL;
2699 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2702 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2704 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2705 if (ret == NULL) {
2706 PyErr_SetString(PyExc_KeyError, "No such element");
2707 return NULL;
2709 return ret;
2712 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2714 PyObject *def = NULL;
2715 const char *kwnames[] = { "name", "default", "idx", NULL };
2716 const char *name = NULL;
2717 int idx = -1;
2718 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2719 struct ldb_message_element *el;
2721 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2722 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2723 return NULL;
2726 if (strcasecmp(name, "dn") == 0) {
2727 return pyldb_Dn_FromDn(msg->dn);
2730 el = ldb_msg_find_element(msg, name);
2732 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2733 if (def != NULL) {
2734 return def;
2736 Py_RETURN_NONE;
2739 if (idx == -1) {
2740 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2743 return PyObject_FromLdbValue(&el->values[idx]);
2746 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2748 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2749 Py_ssize_t i, j = 0;
2750 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2751 if (msg->dn != NULL) {
2752 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2753 j++;
2755 for (i = 0; i < msg->num_elements; i++, j++) {
2756 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2757 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2758 PyList_SetItem(l, j, value);
2760 return l;
2763 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2765 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2766 Py_ssize_t i = 0;
2767 PyObject *l = PyList_New(msg->num_elements);
2768 for (i = 0; i < msg->num_elements; i++) {
2769 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2771 return l;
2774 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2776 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2777 PyLdbMessageElementObject *py_element;
2778 int ret;
2779 struct ldb_message_element *el;
2781 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2782 return NULL;
2784 el = talloc_reference(msg, py_element->el);
2785 if (el == NULL) {
2786 PyErr_NoMemory();
2787 return NULL;
2790 ret = ldb_msg_add(msg, el, el->flags);
2791 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2793 Py_RETURN_NONE;
2796 static PyMethodDef py_ldb_msg_methods[] = {
2797 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2798 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2799 "Class method to create ldb.Message object from Dictionary.\n"
2800 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2801 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2802 "S.keys() -> list\n\n"
2803 "Return sequence of all attribute names." },
2804 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2805 "S.remove(name)\n\n"
2806 "Remove all entries for attributes with the specified name."},
2807 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2808 "msg.get(name,default=None,idx=None) -> string\n"
2809 "idx is the index into the values array\n"
2810 "if idx is None, then a list is returned\n"
2811 "if idx is not None, then the element with that index is returned\n"
2812 "if you pass the special name 'dn' then the DN object is returned\n"},
2813 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2814 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2815 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2816 "S.append(element)\n\n"
2817 "Add an element to this message." },
2818 { NULL },
2821 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2823 PyObject *list, *iter;
2825 list = py_ldb_msg_keys(self);
2826 iter = PyObject_GetIter(list);
2827 Py_DECREF(list);
2828 return iter;
2831 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2833 char *attr_name;
2835 if (!PyString_Check(name)) {
2836 PyErr_SetNone(PyExc_TypeError);
2837 return -1;
2840 attr_name = PyString_AsString(name);
2841 if (value == NULL) {
2842 /* delitem */
2843 ldb_msg_remove_attr(self->msg, attr_name);
2844 } else {
2845 int ret;
2846 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2847 value, 0, attr_name);
2848 if (el == NULL)
2849 return -1;
2850 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2851 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2852 if (ret != LDB_SUCCESS) {
2853 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
2854 return -1;
2857 return 0;
2860 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2862 return pyldb_Message_AsMessage(self)->num_elements;
2865 static PyMappingMethods py_ldb_msg_mapping = {
2866 .mp_length = (lenfunc)py_ldb_msg_length,
2867 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2868 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2871 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2873 const char * const kwnames[] = { "dn", NULL };
2874 struct ldb_message *ret;
2875 TALLOC_CTX *mem_ctx;
2876 PyObject *pydn = NULL;
2877 PyLdbMessageObject *py_ret;
2879 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2880 discard_const_p(char *, kwnames),
2881 &pydn))
2882 return NULL;
2884 mem_ctx = talloc_new(NULL);
2885 if (mem_ctx == NULL) {
2886 PyErr_NoMemory();
2887 return NULL;
2890 ret = ldb_msg_new(mem_ctx);
2891 if (ret == NULL) {
2892 talloc_free(mem_ctx);
2893 PyErr_NoMemory();
2894 return NULL;
2897 if (pydn != NULL) {
2898 struct ldb_dn *dn;
2899 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2900 talloc_free(mem_ctx);
2901 return NULL;
2903 ret->dn = talloc_reference(ret, dn);
2906 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2907 if (py_ret == NULL) {
2908 PyErr_NoMemory();
2909 talloc_free(mem_ctx);
2910 return NULL;
2913 py_ret->mem_ctx = mem_ctx;
2914 py_ret->msg = ret;
2915 return (PyObject *)py_ret;
2918 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2920 PyLdbMessageObject *ret;
2922 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2923 if (ret == NULL) {
2924 PyErr_NoMemory();
2925 return NULL;
2927 ret->mem_ctx = talloc_new(NULL);
2928 ret->msg = talloc_reference(ret->mem_ctx, msg);
2929 return (PyObject *)ret;
2932 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2934 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2935 return pyldb_Dn_FromDn(msg->dn);
2938 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2940 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2941 if (!pyldb_Dn_Check(value)) {
2942 PyErr_SetNone(PyExc_TypeError);
2943 return -1;
2946 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2947 return 0;
2950 static PyGetSetDef py_ldb_msg_getset[] = {
2951 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2952 { NULL }
2955 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2957 PyObject *dict = PyDict_New(), *ret;
2958 if (PyDict_Update(dict, (PyObject *)self) != 0)
2959 return NULL;
2960 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2961 Py_DECREF(dict);
2962 return ret;
2965 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2967 talloc_free(self->mem_ctx);
2968 PyObject_Del(self);
2971 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2972 PyLdbMessageObject *py_msg2)
2974 struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
2975 *msg2 = pyldb_Message_AsMessage(py_msg2);
2976 unsigned int i;
2977 int ret;
2979 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2980 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2981 if (ret != 0) {
2982 return SIGN(ret);
2986 ret = msg1->num_elements - msg2->num_elements;
2987 if (ret != 0) {
2988 return SIGN(ret);
2991 for (i = 0; i < msg1->num_elements; i++) {
2992 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2993 &msg2->elements[i]);
2994 if (ret != 0) {
2995 return SIGN(ret);
2998 ret = ldb_msg_element_compare(&msg1->elements[i],
2999 &msg2->elements[i]);
3000 if (ret != 0) {
3001 return SIGN(ret);
3005 return 0;
3008 static PyTypeObject PyLdbMessage = {
3009 .tp_name = "ldb.Message",
3010 .tp_methods = py_ldb_msg_methods,
3011 .tp_getset = py_ldb_msg_getset,
3012 .tp_as_mapping = &py_ldb_msg_mapping,
3013 .tp_basicsize = sizeof(PyLdbMessageObject),
3014 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3015 .tp_new = py_ldb_msg_new,
3016 .tp_repr = (reprfunc)py_ldb_msg_repr,
3017 .tp_flags = Py_TPFLAGS_DEFAULT,
3018 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3019 .tp_compare = (cmpfunc)py_ldb_msg_compare,
3020 .tp_doc = "A LDB Message",
3023 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3025 PyLdbTreeObject *ret;
3027 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3028 if (ret == NULL) {
3029 PyErr_NoMemory();
3030 return NULL;
3033 ret->mem_ctx = talloc_new(NULL);
3034 ret->tree = talloc_reference(ret->mem_ctx, tree);
3035 return (PyObject *)ret;
3038 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3040 talloc_free(self->mem_ctx);
3041 PyObject_Del(self);
3044 static PyTypeObject PyLdbTree = {
3045 .tp_name = "ldb.Tree",
3046 .tp_basicsize = sizeof(PyLdbTreeObject),
3047 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3048 .tp_flags = Py_TPFLAGS_DEFAULT,
3049 .tp_doc = "A search tree",
3052 /* Ldb_module */
3053 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3055 PyObject *py_ldb = (PyObject *)mod->private_data;
3056 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3058 py_base = pyldb_Dn_FromDn(req->op.search.base);
3060 if (py_base == NULL)
3061 return LDB_ERR_OPERATIONS_ERROR;
3063 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3065 if (py_tree == NULL)
3066 return LDB_ERR_OPERATIONS_ERROR;
3068 if (req->op.search.attrs == NULL) {
3069 py_attrs = Py_None;
3070 } else {
3071 int i, len;
3072 for (len = 0; req->op.search.attrs[len]; len++);
3073 py_attrs = PyList_New(len);
3074 for (i = 0; i < len; i++)
3075 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
3078 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3079 discard_const_p(char, "OiOO"),
3080 py_base, req->op.search.scope, py_tree, py_attrs);
3082 Py_DECREF(py_attrs);
3083 Py_DECREF(py_tree);
3084 Py_DECREF(py_base);
3086 if (py_result == NULL) {
3087 return LDB_ERR_PYTHON_EXCEPTION;
3090 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3091 if (req->op.search.res == NULL) {
3092 return LDB_ERR_PYTHON_EXCEPTION;
3095 Py_DECREF(py_result);
3097 return LDB_SUCCESS;
3100 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3102 PyObject *py_ldb = (PyObject *)mod->private_data;
3103 PyObject *py_result, *py_msg;
3105 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3107 if (py_msg == NULL) {
3108 return LDB_ERR_OPERATIONS_ERROR;
3111 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3112 discard_const_p(char, "O"),
3113 py_msg);
3115 Py_DECREF(py_msg);
3117 if (py_result == NULL) {
3118 return LDB_ERR_PYTHON_EXCEPTION;
3121 Py_DECREF(py_result);
3123 return LDB_SUCCESS;
3126 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3128 PyObject *py_ldb = (PyObject *)mod->private_data;
3129 PyObject *py_result, *py_msg;
3131 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3133 if (py_msg == NULL) {
3134 return LDB_ERR_OPERATIONS_ERROR;
3137 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3138 discard_const_p(char, "O"),
3139 py_msg);
3141 Py_DECREF(py_msg);
3143 if (py_result == NULL) {
3144 return LDB_ERR_PYTHON_EXCEPTION;
3147 Py_DECREF(py_result);
3149 return LDB_SUCCESS;
3152 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3154 PyObject *py_ldb = (PyObject *)mod->private_data;
3155 PyObject *py_result, *py_dn;
3157 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3159 if (py_dn == NULL)
3160 return LDB_ERR_OPERATIONS_ERROR;
3162 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3163 discard_const_p(char, "O"),
3164 py_dn);
3166 if (py_result == NULL) {
3167 return LDB_ERR_PYTHON_EXCEPTION;
3170 Py_DECREF(py_result);
3172 return LDB_SUCCESS;
3175 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3177 PyObject *py_ldb = (PyObject *)mod->private_data;
3178 PyObject *py_result, *py_olddn, *py_newdn;
3180 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3182 if (py_olddn == NULL)
3183 return LDB_ERR_OPERATIONS_ERROR;
3185 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3187 if (py_newdn == NULL)
3188 return LDB_ERR_OPERATIONS_ERROR;
3190 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3191 discard_const_p(char, "OO"),
3192 py_olddn, py_newdn);
3194 Py_DECREF(py_olddn);
3195 Py_DECREF(py_newdn);
3197 if (py_result == NULL) {
3198 return LDB_ERR_PYTHON_EXCEPTION;
3201 Py_DECREF(py_result);
3203 return LDB_SUCCESS;
3206 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3208 PyObject *py_ldb = (PyObject *)mod->private_data;
3209 PyObject *py_result;
3211 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3212 discard_const_p(char, ""));
3214 Py_XDECREF(py_result);
3216 return LDB_ERR_OPERATIONS_ERROR;
3219 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3221 PyObject *py_ldb = (PyObject *)mod->private_data;
3222 PyObject *py_result;
3224 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3225 discard_const_p(char, ""));
3227 Py_XDECREF(py_result);
3229 return LDB_ERR_OPERATIONS_ERROR;
3232 static int py_module_start_transaction(struct ldb_module *mod)
3234 PyObject *py_ldb = (PyObject *)mod->private_data;
3235 PyObject *py_result;
3237 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3238 discard_const_p(char, ""));
3240 if (py_result == NULL) {
3241 return LDB_ERR_PYTHON_EXCEPTION;
3244 Py_DECREF(py_result);
3246 return LDB_SUCCESS;
3249 static int py_module_end_transaction(struct ldb_module *mod)
3251 PyObject *py_ldb = (PyObject *)mod->private_data;
3252 PyObject *py_result;
3254 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3255 discard_const_p(char, ""));
3257 if (py_result == NULL) {
3258 return LDB_ERR_PYTHON_EXCEPTION;
3261 Py_DECREF(py_result);
3263 return LDB_SUCCESS;
3266 static int py_module_del_transaction(struct ldb_module *mod)
3268 PyObject *py_ldb = (PyObject *)mod->private_data;
3269 PyObject *py_result;
3271 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3272 discard_const_p(char, ""));
3274 if (py_result == NULL) {
3275 return LDB_ERR_PYTHON_EXCEPTION;
3278 Py_DECREF(py_result);
3280 return LDB_SUCCESS;
3283 static int py_module_destructor(struct ldb_module *mod)
3285 Py_DECREF((PyObject *)mod->private_data);
3286 return 0;
3289 static int py_module_init(struct ldb_module *mod)
3291 PyObject *py_class = (PyObject *)mod->ops->private_data;
3292 PyObject *py_result, *py_next, *py_ldb;
3294 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3296 if (py_ldb == NULL)
3297 return LDB_ERR_OPERATIONS_ERROR;
3299 py_next = PyLdbModule_FromModule(mod->next);
3301 if (py_next == NULL)
3302 return LDB_ERR_OPERATIONS_ERROR;
3304 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3305 py_ldb, py_next);
3307 if (py_result == NULL) {
3308 return LDB_ERR_PYTHON_EXCEPTION;
3311 mod->private_data = py_result;
3313 talloc_set_destructor(mod, py_module_destructor);
3315 return ldb_next_init(mod);
3318 static PyObject *py_register_module(PyObject *module, PyObject *args)
3320 int ret;
3321 struct ldb_module_ops *ops;
3322 PyObject *input;
3324 if (!PyArg_ParseTuple(args, "O", &input))
3325 return NULL;
3327 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3328 if (ops == NULL) {
3329 PyErr_NoMemory();
3330 return NULL;
3333 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3335 Py_INCREF(input);
3336 ops->private_data = input;
3337 ops->init_context = py_module_init;
3338 ops->search = py_module_search;
3339 ops->add = py_module_add;
3340 ops->modify = py_module_modify;
3341 ops->del = py_module_del;
3342 ops->rename = py_module_rename;
3343 ops->request = py_module_request;
3344 ops->extended = py_module_extended;
3345 ops->start_transaction = py_module_start_transaction;
3346 ops->end_transaction = py_module_end_transaction;
3347 ops->del_transaction = py_module_del_transaction;
3349 ret = ldb_register_module(ops);
3351 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3353 Py_RETURN_NONE;
3356 static PyObject *py_timestring(PyObject *module, PyObject *args)
3358 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3359 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3360 long int t_val;
3361 char *tresult;
3362 PyObject *ret;
3363 if (!PyArg_ParseTuple(args, "l", &t_val))
3364 return NULL;
3365 tresult = ldb_timestring(NULL, (time_t) t_val);
3366 ret = PyString_FromString(tresult);
3367 talloc_free(tresult);
3368 return ret;
3371 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3373 char *str;
3374 if (!PyArg_ParseTuple(args, "s", &str))
3375 return NULL;
3377 return PyInt_FromLong(ldb_string_to_time(str));
3380 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3382 char *name;
3383 if (!PyArg_ParseTuple(args, "s", &name))
3384 return NULL;
3385 return PyBool_FromLong(ldb_valid_attr_name(name));
3389 encode a string using RFC2254 rules
3391 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3393 char *str, *encoded;
3394 int size = 0;
3395 struct ldb_val val;
3396 PyObject *ret;
3398 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3399 return NULL;
3400 val.data = (uint8_t *)str;
3401 val.length = size;
3403 encoded = ldb_binary_encode(NULL, val);
3404 if (encoded == NULL) {
3405 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3406 return NULL;
3408 ret = PyString_FromString(encoded);
3409 talloc_free(encoded);
3410 return ret;
3414 decode a string using RFC2254 rules
3416 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3418 char *str;
3419 struct ldb_val val;
3420 PyObject *ret;
3422 if (!PyArg_ParseTuple(args, "s", &str))
3423 return NULL;
3425 val = ldb_binary_decode(NULL, str);
3426 if (val.data == NULL) {
3427 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3428 return NULL;
3430 ret = Py_BuildValue("s#", val.data, val.length);
3431 talloc_free(val.data);
3432 return ret;
3435 static PyMethodDef py_ldb_global_methods[] = {
3436 { "register_module", py_register_module, METH_VARARGS,
3437 "S.register_module(module) -> None\n\n"
3438 "Register a LDB module."},
3439 { "timestring", py_timestring, METH_VARARGS,
3440 "S.timestring(int) -> string\n\n"
3441 "Generate a LDAP time string from a UNIX timestamp" },
3442 { "string_to_time", py_string_to_time, METH_VARARGS,
3443 "S.string_to_time(string) -> int\n\n"
3444 "Parse a LDAP time string into a UNIX timestamp." },
3445 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3446 "S.valid_attr_name(name) -> bool\n\nn"
3447 "Check whether the supplied name is a valid attribute name." },
3448 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3449 "S.open() -> Ldb\n\n"
3450 "Open a new LDB context." },
3451 { "binary_encode", py_binary_encode, METH_VARARGS,
3452 "S.binary_encode(string) -> string\n\n"
3453 "Perform a RFC2254 binary encoding on a string" },
3454 { "binary_decode", py_binary_decode, METH_VARARGS,
3455 "S.binary_decode(string) -> string\n\n"
3456 "Perform a RFC2254 binary decode on a string" },
3457 { NULL }
3460 void initldb(void)
3462 PyObject *m;
3464 if (PyType_Ready(&PyLdbDn) < 0)
3465 return;
3467 if (PyType_Ready(&PyLdbMessage) < 0)
3468 return;
3470 if (PyType_Ready(&PyLdbMessageElement) < 0)
3471 return;
3473 if (PyType_Ready(&PyLdb) < 0)
3474 return;
3476 if (PyType_Ready(&PyLdbModule) < 0)
3477 return;
3479 if (PyType_Ready(&PyLdbTree) < 0)
3480 return;
3482 if (PyType_Ready(&PyLdbResult) < 0)
3483 return;
3485 if (PyType_Ready(&PyLdbControl) < 0)
3486 return;
3488 m = Py_InitModule3("ldb", py_ldb_global_methods,
3489 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3490 if (m == NULL)
3491 return;
3493 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3494 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3495 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3496 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3497 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3498 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3499 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3501 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3502 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3503 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3504 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3506 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3507 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3508 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3510 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3511 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3512 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3513 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3514 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3515 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3516 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3517 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3518 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3519 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3520 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3521 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3522 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3523 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3524 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3525 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3526 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3527 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3528 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3529 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3530 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3531 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3532 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3533 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3534 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3535 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3536 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3537 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3538 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3539 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3540 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3541 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3542 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3543 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3544 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3545 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3546 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3547 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3548 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3550 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3551 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3552 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3553 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3555 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3557 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3558 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3560 Py_INCREF(&PyLdb);
3561 Py_INCREF(&PyLdbDn);
3562 Py_INCREF(&PyLdbModule);
3563 Py_INCREF(&PyLdbMessage);
3564 Py_INCREF(&PyLdbMessageElement);
3565 Py_INCREF(&PyLdbTree);
3566 Py_INCREF(&PyLdbResult);
3567 Py_INCREF(&PyLdbControl);
3569 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3570 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3571 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3572 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3573 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3574 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3575 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3577 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3579 #define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3581 ADD_LDB_STRING(SYNTAX_DN);
3582 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3583 ADD_LDB_STRING(SYNTAX_INTEGER);
3584 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3585 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3586 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3587 ADD_LDB_STRING(OID_COMPARATOR_AND);
3588 ADD_LDB_STRING(OID_COMPARATOR_OR);