s3: smbd: leases - new torture test shows stat opens can get leases.
[Samba.git] / lib / ldb / pyldb.c
blob5bcff72a2117876fae240aae2603d9608673548b
1 /*
2 Unix SMB/CIFS implementation.
4 Python interface to ldb.
6 Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7 Copyright (C) 2006 Simo Sorce <idra@samba.org>
8 Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9 Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10 Copyright (C) 2009-2011 Andrew Tridgell
11 Copyright (C) 2009-2011 Andrew Bartlett
13 ** NOTE! The following LGPL license applies to the ldb
14 ** library. This does NOT imply that all of Samba is released
15 ** under the LGPL
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public
19 License as published by the Free Software Foundation; either
20 version 3 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, see <http://www.gnu.org/licenses/>.
31 #include <Python.h>
32 #include "ldb_private.h"
33 #include "pyldb.h"
35 void initldb(void);
36 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
37 static PyObject *PyExc_LdbError;
39 static PyTypeObject PyLdbControl;
40 static PyTypeObject PyLdbResult;
41 static PyTypeObject PyLdbMessage;
42 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
43 static PyTypeObject PyLdbModule;
44 static PyTypeObject PyLdbDn;
45 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
46 static PyTypeObject PyLdb;
47 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
48 static PyTypeObject PyLdbMessageElement;
49 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
51 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 i, ret;
2779 struct ldb_message_element *el;
2780 struct ldb_message_element *el_new;
2782 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2783 return NULL;
2785 el = py_element->el;
2786 if (el == NULL) {
2787 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
2788 return NULL;
2791 ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
2792 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2794 /* now deep copy all attribute values */
2795 el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
2796 if (el_new->values == NULL) {
2797 PyErr_NoMemory();
2798 return NULL;
2800 el_new->num_values = el->num_values;
2802 for (i = 0; i < el->num_values; i++) {
2803 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
2804 if (el_new->values[i].data == NULL
2805 && el->values[i].length != 0) {
2806 PyErr_NoMemory();
2807 return NULL;
2811 Py_RETURN_NONE;
2814 static PyMethodDef py_ldb_msg_methods[] = {
2815 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2816 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2817 "Class method to create ldb.Message object from Dictionary.\n"
2818 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2819 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2820 "S.keys() -> list\n\n"
2821 "Return sequence of all attribute names." },
2822 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2823 "S.remove(name)\n\n"
2824 "Remove all entries for attributes with the specified name."},
2825 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2826 "msg.get(name,default=None,idx=None) -> string\n"
2827 "idx is the index into the values array\n"
2828 "if idx is None, then a list is returned\n"
2829 "if idx is not None, then the element with that index is returned\n"
2830 "if you pass the special name 'dn' then the DN object is returned\n"},
2831 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2832 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2833 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2834 "S.add(element)\n\n"
2835 "Add an element to this message." },
2836 { NULL },
2839 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2841 PyObject *list, *iter;
2843 list = py_ldb_msg_keys(self);
2844 iter = PyObject_GetIter(list);
2845 Py_DECREF(list);
2846 return iter;
2849 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2851 char *attr_name;
2853 if (!PyString_Check(name)) {
2854 PyErr_SetNone(PyExc_TypeError);
2855 return -1;
2858 attr_name = PyString_AsString(name);
2859 if (value == NULL) {
2860 /* delitem */
2861 ldb_msg_remove_attr(self->msg, attr_name);
2862 } else {
2863 int ret;
2864 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2865 value, 0, attr_name);
2866 if (el == NULL) {
2867 return -1;
2869 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2870 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2871 if (ret != LDB_SUCCESS) {
2872 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
2873 return -1;
2876 return 0;
2879 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2881 return pyldb_Message_AsMessage(self)->num_elements;
2884 static PyMappingMethods py_ldb_msg_mapping = {
2885 .mp_length = (lenfunc)py_ldb_msg_length,
2886 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2887 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2890 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2892 const char * const kwnames[] = { "dn", NULL };
2893 struct ldb_message *ret;
2894 TALLOC_CTX *mem_ctx;
2895 PyObject *pydn = NULL;
2896 PyLdbMessageObject *py_ret;
2898 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2899 discard_const_p(char *, kwnames),
2900 &pydn))
2901 return NULL;
2903 mem_ctx = talloc_new(NULL);
2904 if (mem_ctx == NULL) {
2905 PyErr_NoMemory();
2906 return NULL;
2909 ret = ldb_msg_new(mem_ctx);
2910 if (ret == NULL) {
2911 talloc_free(mem_ctx);
2912 PyErr_NoMemory();
2913 return NULL;
2916 if (pydn != NULL) {
2917 struct ldb_dn *dn;
2918 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2919 talloc_free(mem_ctx);
2920 return NULL;
2922 ret->dn = talloc_reference(ret, dn);
2925 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2926 if (py_ret == NULL) {
2927 PyErr_NoMemory();
2928 talloc_free(mem_ctx);
2929 return NULL;
2932 py_ret->mem_ctx = mem_ctx;
2933 py_ret->msg = ret;
2934 return (PyObject *)py_ret;
2937 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2939 PyLdbMessageObject *ret;
2941 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2942 if (ret == NULL) {
2943 PyErr_NoMemory();
2944 return NULL;
2946 ret->mem_ctx = talloc_new(NULL);
2947 ret->msg = talloc_reference(ret->mem_ctx, msg);
2948 return (PyObject *)ret;
2951 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2953 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2954 return pyldb_Dn_FromDn(msg->dn);
2957 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2959 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2960 if (!pyldb_Dn_Check(value)) {
2961 PyErr_SetNone(PyExc_TypeError);
2962 return -1;
2965 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2966 return 0;
2969 static PyGetSetDef py_ldb_msg_getset[] = {
2970 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2971 { NULL }
2974 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2976 PyObject *dict = PyDict_New(), *ret;
2977 if (PyDict_Update(dict, (PyObject *)self) != 0)
2978 return NULL;
2979 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2980 Py_DECREF(dict);
2981 return ret;
2984 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2986 talloc_free(self->mem_ctx);
2987 PyObject_Del(self);
2990 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2991 PyLdbMessageObject *py_msg2)
2993 struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
2994 *msg2 = pyldb_Message_AsMessage(py_msg2);
2995 unsigned int i;
2996 int ret;
2998 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2999 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3000 if (ret != 0) {
3001 return SIGN(ret);
3005 ret = msg1->num_elements - msg2->num_elements;
3006 if (ret != 0) {
3007 return SIGN(ret);
3010 for (i = 0; i < msg1->num_elements; i++) {
3011 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3012 &msg2->elements[i]);
3013 if (ret != 0) {
3014 return SIGN(ret);
3017 ret = ldb_msg_element_compare(&msg1->elements[i],
3018 &msg2->elements[i]);
3019 if (ret != 0) {
3020 return SIGN(ret);
3024 return 0;
3027 static PyTypeObject PyLdbMessage = {
3028 .tp_name = "ldb.Message",
3029 .tp_methods = py_ldb_msg_methods,
3030 .tp_getset = py_ldb_msg_getset,
3031 .tp_as_mapping = &py_ldb_msg_mapping,
3032 .tp_basicsize = sizeof(PyLdbMessageObject),
3033 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3034 .tp_new = py_ldb_msg_new,
3035 .tp_repr = (reprfunc)py_ldb_msg_repr,
3036 .tp_flags = Py_TPFLAGS_DEFAULT,
3037 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3038 .tp_compare = (cmpfunc)py_ldb_msg_compare,
3039 .tp_doc = "A LDB Message",
3042 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3044 PyLdbTreeObject *ret;
3046 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3047 if (ret == NULL) {
3048 PyErr_NoMemory();
3049 return NULL;
3052 ret->mem_ctx = talloc_new(NULL);
3053 ret->tree = talloc_reference(ret->mem_ctx, tree);
3054 return (PyObject *)ret;
3057 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3059 talloc_free(self->mem_ctx);
3060 PyObject_Del(self);
3063 static PyTypeObject PyLdbTree = {
3064 .tp_name = "ldb.Tree",
3065 .tp_basicsize = sizeof(PyLdbTreeObject),
3066 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3067 .tp_flags = Py_TPFLAGS_DEFAULT,
3068 .tp_doc = "A search tree",
3071 /* Ldb_module */
3072 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3074 PyObject *py_ldb = (PyObject *)mod->private_data;
3075 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3077 py_base = pyldb_Dn_FromDn(req->op.search.base);
3079 if (py_base == NULL)
3080 return LDB_ERR_OPERATIONS_ERROR;
3082 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3084 if (py_tree == NULL)
3085 return LDB_ERR_OPERATIONS_ERROR;
3087 if (req->op.search.attrs == NULL) {
3088 py_attrs = Py_None;
3089 } else {
3090 int i, len;
3091 for (len = 0; req->op.search.attrs[len]; len++);
3092 py_attrs = PyList_New(len);
3093 for (i = 0; i < len; i++)
3094 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
3097 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3098 discard_const_p(char, "OiOO"),
3099 py_base, req->op.search.scope, py_tree, py_attrs);
3101 Py_DECREF(py_attrs);
3102 Py_DECREF(py_tree);
3103 Py_DECREF(py_base);
3105 if (py_result == NULL) {
3106 return LDB_ERR_PYTHON_EXCEPTION;
3109 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3110 if (req->op.search.res == NULL) {
3111 return LDB_ERR_PYTHON_EXCEPTION;
3114 Py_DECREF(py_result);
3116 return LDB_SUCCESS;
3119 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3121 PyObject *py_ldb = (PyObject *)mod->private_data;
3122 PyObject *py_result, *py_msg;
3124 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3126 if (py_msg == NULL) {
3127 return LDB_ERR_OPERATIONS_ERROR;
3130 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3131 discard_const_p(char, "O"),
3132 py_msg);
3134 Py_DECREF(py_msg);
3136 if (py_result == NULL) {
3137 return LDB_ERR_PYTHON_EXCEPTION;
3140 Py_DECREF(py_result);
3142 return LDB_SUCCESS;
3145 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3147 PyObject *py_ldb = (PyObject *)mod->private_data;
3148 PyObject *py_result, *py_msg;
3150 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3152 if (py_msg == NULL) {
3153 return LDB_ERR_OPERATIONS_ERROR;
3156 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3157 discard_const_p(char, "O"),
3158 py_msg);
3160 Py_DECREF(py_msg);
3162 if (py_result == NULL) {
3163 return LDB_ERR_PYTHON_EXCEPTION;
3166 Py_DECREF(py_result);
3168 return LDB_SUCCESS;
3171 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3173 PyObject *py_ldb = (PyObject *)mod->private_data;
3174 PyObject *py_result, *py_dn;
3176 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3178 if (py_dn == NULL)
3179 return LDB_ERR_OPERATIONS_ERROR;
3181 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3182 discard_const_p(char, "O"),
3183 py_dn);
3185 if (py_result == NULL) {
3186 return LDB_ERR_PYTHON_EXCEPTION;
3189 Py_DECREF(py_result);
3191 return LDB_SUCCESS;
3194 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3196 PyObject *py_ldb = (PyObject *)mod->private_data;
3197 PyObject *py_result, *py_olddn, *py_newdn;
3199 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3201 if (py_olddn == NULL)
3202 return LDB_ERR_OPERATIONS_ERROR;
3204 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3206 if (py_newdn == NULL)
3207 return LDB_ERR_OPERATIONS_ERROR;
3209 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3210 discard_const_p(char, "OO"),
3211 py_olddn, py_newdn);
3213 Py_DECREF(py_olddn);
3214 Py_DECREF(py_newdn);
3216 if (py_result == NULL) {
3217 return LDB_ERR_PYTHON_EXCEPTION;
3220 Py_DECREF(py_result);
3222 return LDB_SUCCESS;
3225 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3227 PyObject *py_ldb = (PyObject *)mod->private_data;
3228 PyObject *py_result;
3230 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3231 discard_const_p(char, ""));
3233 Py_XDECREF(py_result);
3235 return LDB_ERR_OPERATIONS_ERROR;
3238 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3240 PyObject *py_ldb = (PyObject *)mod->private_data;
3241 PyObject *py_result;
3243 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3244 discard_const_p(char, ""));
3246 Py_XDECREF(py_result);
3248 return LDB_ERR_OPERATIONS_ERROR;
3251 static int py_module_start_transaction(struct ldb_module *mod)
3253 PyObject *py_ldb = (PyObject *)mod->private_data;
3254 PyObject *py_result;
3256 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3257 discard_const_p(char, ""));
3259 if (py_result == NULL) {
3260 return LDB_ERR_PYTHON_EXCEPTION;
3263 Py_DECREF(py_result);
3265 return LDB_SUCCESS;
3268 static int py_module_end_transaction(struct ldb_module *mod)
3270 PyObject *py_ldb = (PyObject *)mod->private_data;
3271 PyObject *py_result;
3273 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3274 discard_const_p(char, ""));
3276 if (py_result == NULL) {
3277 return LDB_ERR_PYTHON_EXCEPTION;
3280 Py_DECREF(py_result);
3282 return LDB_SUCCESS;
3285 static int py_module_del_transaction(struct ldb_module *mod)
3287 PyObject *py_ldb = (PyObject *)mod->private_data;
3288 PyObject *py_result;
3290 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3291 discard_const_p(char, ""));
3293 if (py_result == NULL) {
3294 return LDB_ERR_PYTHON_EXCEPTION;
3297 Py_DECREF(py_result);
3299 return LDB_SUCCESS;
3302 static int py_module_destructor(struct ldb_module *mod)
3304 Py_DECREF((PyObject *)mod->private_data);
3305 return 0;
3308 static int py_module_init(struct ldb_module *mod)
3310 PyObject *py_class = (PyObject *)mod->ops->private_data;
3311 PyObject *py_result, *py_next, *py_ldb;
3313 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3315 if (py_ldb == NULL)
3316 return LDB_ERR_OPERATIONS_ERROR;
3318 py_next = PyLdbModule_FromModule(mod->next);
3320 if (py_next == NULL)
3321 return LDB_ERR_OPERATIONS_ERROR;
3323 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3324 py_ldb, py_next);
3326 if (py_result == NULL) {
3327 return LDB_ERR_PYTHON_EXCEPTION;
3330 mod->private_data = py_result;
3332 talloc_set_destructor(mod, py_module_destructor);
3334 return ldb_next_init(mod);
3337 static PyObject *py_register_module(PyObject *module, PyObject *args)
3339 int ret;
3340 struct ldb_module_ops *ops;
3341 PyObject *input;
3343 if (!PyArg_ParseTuple(args, "O", &input))
3344 return NULL;
3346 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3347 if (ops == NULL) {
3348 PyErr_NoMemory();
3349 return NULL;
3352 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3354 Py_INCREF(input);
3355 ops->private_data = input;
3356 ops->init_context = py_module_init;
3357 ops->search = py_module_search;
3358 ops->add = py_module_add;
3359 ops->modify = py_module_modify;
3360 ops->del = py_module_del;
3361 ops->rename = py_module_rename;
3362 ops->request = py_module_request;
3363 ops->extended = py_module_extended;
3364 ops->start_transaction = py_module_start_transaction;
3365 ops->end_transaction = py_module_end_transaction;
3366 ops->del_transaction = py_module_del_transaction;
3368 ret = ldb_register_module(ops);
3370 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3372 Py_RETURN_NONE;
3375 static PyObject *py_timestring(PyObject *module, PyObject *args)
3377 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3378 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3379 long int t_val;
3380 char *tresult;
3381 PyObject *ret;
3382 if (!PyArg_ParseTuple(args, "l", &t_val))
3383 return NULL;
3384 tresult = ldb_timestring(NULL, (time_t) t_val);
3385 ret = PyString_FromString(tresult);
3386 talloc_free(tresult);
3387 return ret;
3390 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3392 char *str;
3393 if (!PyArg_ParseTuple(args, "s", &str))
3394 return NULL;
3396 return PyInt_FromLong(ldb_string_to_time(str));
3399 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3401 char *name;
3402 if (!PyArg_ParseTuple(args, "s", &name))
3403 return NULL;
3404 return PyBool_FromLong(ldb_valid_attr_name(name));
3408 encode a string using RFC2254 rules
3410 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3412 char *str, *encoded;
3413 int size = 0;
3414 struct ldb_val val;
3415 PyObject *ret;
3417 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3418 return NULL;
3419 val.data = (uint8_t *)str;
3420 val.length = size;
3422 encoded = ldb_binary_encode(NULL, val);
3423 if (encoded == NULL) {
3424 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3425 return NULL;
3427 ret = PyString_FromString(encoded);
3428 talloc_free(encoded);
3429 return ret;
3433 decode a string using RFC2254 rules
3435 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3437 char *str;
3438 struct ldb_val val;
3439 PyObject *ret;
3441 if (!PyArg_ParseTuple(args, "s", &str))
3442 return NULL;
3444 val = ldb_binary_decode(NULL, str);
3445 if (val.data == NULL) {
3446 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3447 return NULL;
3449 ret = Py_BuildValue("s#", val.data, val.length);
3450 talloc_free(val.data);
3451 return ret;
3454 static PyMethodDef py_ldb_global_methods[] = {
3455 { "register_module", py_register_module, METH_VARARGS,
3456 "S.register_module(module) -> None\n\n"
3457 "Register a LDB module."},
3458 { "timestring", py_timestring, METH_VARARGS,
3459 "S.timestring(int) -> string\n\n"
3460 "Generate a LDAP time string from a UNIX timestamp" },
3461 { "string_to_time", py_string_to_time, METH_VARARGS,
3462 "S.string_to_time(string) -> int\n\n"
3463 "Parse a LDAP time string into a UNIX timestamp." },
3464 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3465 "S.valid_attr_name(name) -> bool\n\nn"
3466 "Check whether the supplied name is a valid attribute name." },
3467 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3468 "S.open() -> Ldb\n\n"
3469 "Open a new LDB context." },
3470 { "binary_encode", py_binary_encode, METH_VARARGS,
3471 "S.binary_encode(string) -> string\n\n"
3472 "Perform a RFC2254 binary encoding on a string" },
3473 { "binary_decode", py_binary_decode, METH_VARARGS,
3474 "S.binary_decode(string) -> string\n\n"
3475 "Perform a RFC2254 binary decode on a string" },
3476 { NULL }
3479 void initldb(void)
3481 PyObject *m;
3483 if (PyType_Ready(&PyLdbDn) < 0)
3484 return;
3486 if (PyType_Ready(&PyLdbMessage) < 0)
3487 return;
3489 if (PyType_Ready(&PyLdbMessageElement) < 0)
3490 return;
3492 if (PyType_Ready(&PyLdb) < 0)
3493 return;
3495 if (PyType_Ready(&PyLdbModule) < 0)
3496 return;
3498 if (PyType_Ready(&PyLdbTree) < 0)
3499 return;
3501 if (PyType_Ready(&PyLdbResult) < 0)
3502 return;
3504 if (PyType_Ready(&PyLdbControl) < 0)
3505 return;
3507 m = Py_InitModule3("ldb", py_ldb_global_methods,
3508 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3509 if (m == NULL)
3510 return;
3512 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3513 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3514 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3515 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3516 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3517 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3518 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3520 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3521 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3522 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3523 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3525 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3526 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3527 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3529 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3530 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3531 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3532 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3533 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3534 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3535 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3536 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3537 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3538 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3539 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3540 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3541 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3542 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3543 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3544 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3545 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3546 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3547 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3548 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3549 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3550 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3551 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3552 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3553 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3554 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3555 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3556 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3557 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3558 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3559 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3560 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3561 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3562 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3563 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3564 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3565 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3566 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3567 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3569 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3570 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3571 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3572 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3574 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3576 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3577 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3579 Py_INCREF(&PyLdb);
3580 Py_INCREF(&PyLdbDn);
3581 Py_INCREF(&PyLdbModule);
3582 Py_INCREF(&PyLdbMessage);
3583 Py_INCREF(&PyLdbMessageElement);
3584 Py_INCREF(&PyLdbTree);
3585 Py_INCREF(&PyLdbResult);
3586 Py_INCREF(&PyLdbControl);
3588 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3589 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3590 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3591 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3592 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3593 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3594 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3596 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3598 #define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3600 ADD_LDB_STRING(SYNTAX_DN);
3601 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3602 ADD_LDB_STRING(SYNTAX_INTEGER);
3603 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3604 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3605 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3606 ADD_LDB_STRING(OID_COMPARATOR_AND);
3607 ADD_LDB_STRING(OID_COMPARATOR_OR);