unix_msg: Use empty arrays in structs
[Samba.git] / lib / ldb / pyldb.c
blob78b801218f9151fd904068b2e289780223a284ea
1 /*
2 Unix SMB/CIFS implementation.
4 Python interface to ldb.
6 Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7 Copyright (C) 2006 Simo Sorce <idra@samba.org>
8 Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9 Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10 Copyright (C) 2009-2011 Andrew Tridgell
11 Copyright (C) 2009-2011 Andrew Bartlett
13 ** NOTE! The following LGPL license applies to the ldb
14 ** library. This does NOT imply that all of Samba is released
15 ** under the LGPL
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public
19 License as published by the Free Software Foundation; either
20 version 3 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, see <http://www.gnu.org/licenses/>.
31 #include <Python.h>
32 #include "ldb_private.h"
33 #include "pyldb.h"
35 void initldb(void);
36 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
37 static PyObject *PyExc_LdbError;
39 staticforward PyTypeObject PyLdbControl;
40 staticforward PyTypeObject PyLdbResult;
41 staticforward PyTypeObject PyLdbMessage;
42 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
43 staticforward PyTypeObject PyLdbModule;
44 staticforward PyTypeObject PyLdbDn;
45 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
46 staticforward PyTypeObject PyLdb;
47 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
48 staticforward PyTypeObject PyLdbMessageElement;
49 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
51 staticforward PyTypeObject PyLdbTree;
52 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
53 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
54 static struct ldb_message_element *PyObject_AsMessageElement(
55 TALLOC_CTX *mem_ctx,
56 PyObject *set_obj,
57 unsigned int flags,
58 const char *attr_name);
60 /* There's no Py_ssize_t in 2.4, apparently */
61 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
62 typedef int Py_ssize_t;
63 typedef inquiry lenfunc;
64 typedef intargfunc ssizeargfunc;
65 #endif
67 #define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
71 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
73 if (self->data != NULL) {
74 char* control = ldb_control_to_string(self->mem_ctx, self->data);
75 if (control == NULL) {
76 PyErr_NoMemory();
77 return NULL;
79 return PyString_FromString(control);
80 } else {
81 return PyString_FromFormat("ldb control");
85 static void py_ldb_control_dealloc(PyLdbControlObject *self)
87 if (self->mem_ctx != NULL) {
88 talloc_free(self->mem_ctx);
90 self->data = NULL;
91 self->ob_type->tp_free(self);
94 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
96 return PyString_FromString(self->data->oid);
99 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
101 return PyBool_FromLong(self->data->critical);
104 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
106 if (PyObject_IsTrue(value)) {
107 self->data->critical = true;
108 } else {
109 self->data->critical = false;
111 return 0;
114 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
116 char *data = NULL;
117 const char * const kwnames[] = { "ldb", "data", NULL };
118 struct ldb_control *parsed_controls;
119 PyLdbControlObject *ret;
120 PyObject *py_ldb;
121 TALLOC_CTX *mem_ctx;
122 struct ldb_context *ldb_ctx;
124 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
125 discard_const_p(char *, kwnames),
126 &py_ldb, &data))
127 return NULL;
129 mem_ctx = talloc_new(NULL);
130 if (mem_ctx == NULL) {
131 PyErr_NoMemory();
132 return NULL;
135 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
136 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
138 if (!parsed_controls) {
139 talloc_free(mem_ctx);
140 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
141 return NULL;
144 ret = PyObject_New(PyLdbControlObject, type);
145 if (ret == NULL) {
146 PyErr_NoMemory();
147 talloc_free(mem_ctx);
148 return NULL;
151 ret->mem_ctx = mem_ctx;
153 ret->data = talloc_move(mem_ctx, &parsed_controls);
154 if (ret->data == NULL) {
155 Py_DECREF(ret);
156 PyErr_NoMemory();
157 talloc_free(mem_ctx);
158 return NULL;
161 return (PyObject *)ret;
164 static PyGetSetDef py_ldb_control_getset[] = {
165 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
166 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
167 { NULL }
170 static PyTypeObject PyLdbControl = {
171 .tp_name = "ldb.control",
172 .tp_dealloc = (destructor)py_ldb_control_dealloc,
173 .tp_getattro = PyObject_GenericGetAttr,
174 .tp_basicsize = sizeof(PyLdbControlObject),
175 .tp_getset = py_ldb_control_getset,
176 .tp_doc = "LDB control.",
177 .tp_str = (reprfunc)py_ldb_control_str,
178 .tp_new = py_ldb_control_new,
179 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
182 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
184 if (ret == LDB_ERR_PYTHON_EXCEPTION)
185 return; /* Python exception should already be set, just keep that */
187 PyErr_SetObject(error,
188 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
189 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
192 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
194 return PyString_FromStringAndSize((const char *)val->data, val->length);
198 * Create a Python object from a ldb_result.
200 * @param result LDB result to convert
201 * @return Python object with converted result (a list object)
203 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
205 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
206 PyLdbControlObject *ctrl;
207 if (ctl_ctx == NULL) {
208 PyErr_NoMemory();
209 return NULL;
212 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
213 if (ctrl == NULL) {
214 talloc_free(ctl_ctx);
215 PyErr_NoMemory();
216 return NULL;
218 ctrl->mem_ctx = ctl_ctx;
219 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
220 if (ctrl->data == NULL) {
221 Py_DECREF(ctrl);
222 PyErr_NoMemory();
223 return NULL;
225 return (PyObject*) ctrl;
229 * Create a Python object from a ldb_result.
231 * @param result LDB result to convert
232 * @return Python object with converted result (a list object)
234 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
236 PyLdbResultObject *ret;
237 PyObject *list, *controls, *referals;
238 Py_ssize_t i;
240 if (result == NULL) {
241 Py_RETURN_NONE;
244 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
245 if (ret == NULL) {
246 PyErr_NoMemory();
247 return NULL;
250 list = PyList_New(result->count);
251 if (list == NULL) {
252 PyErr_NoMemory();
253 Py_DECREF(ret);
254 return NULL;
257 for (i = 0; i < result->count; i++) {
258 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
261 ret->mem_ctx = talloc_new(NULL);
262 if (ret->mem_ctx == NULL) {
263 Py_DECREF(list);
264 Py_DECREF(ret);
265 PyErr_NoMemory();
266 return NULL;
269 ret->msgs = list;
271 if (result->controls) {
272 controls = PyList_New(1);
273 if (controls == NULL) {
274 Py_DECREF(ret);
275 PyErr_NoMemory();
276 return NULL;
278 for (i=0; result->controls[i]; i++) {
279 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
280 if (ctrl == NULL) {
281 Py_DECREF(ret);
282 Py_DECREF(controls);
283 PyErr_NoMemory();
284 return NULL;
286 PyList_SetItem(controls, i, ctrl);
288 } else {
290 * No controls so we keep an empty list
292 controls = PyList_New(0);
293 if (controls == NULL) {
294 Py_DECREF(ret);
295 PyErr_NoMemory();
296 return NULL;
300 ret->controls = controls;
302 i = 0;
304 while (result->refs && result->refs[i]) {
305 i++;
308 referals = PyList_New(i);
309 if (referals == NULL) {
310 Py_DECREF(ret);
311 PyErr_NoMemory();
312 return NULL;
315 for (i = 0;result->refs && result->refs[i]; i++) {
316 PyList_SetItem(referals, i, PyString_FromString(result->refs[i]));
318 ret->referals = referals;
319 return (PyObject *)ret;
323 * Create a LDB Result from a Python object.
324 * If conversion fails, NULL will be returned and a Python exception set.
326 * Note: the result object only includes the messages at the moment; extended
327 * result, controls and referrals are ignored.
329 * @param mem_ctx Memory context in which to allocate the LDB Result
330 * @param obj Python object to convert
331 * @return a ldb_result, or NULL if the conversion failed
333 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
334 PyObject *obj)
336 struct ldb_result *res;
337 Py_ssize_t i;
339 if (obj == Py_None)
340 return NULL;
342 res = talloc_zero(mem_ctx, struct ldb_result);
343 res->count = PyList_Size(obj);
344 res->msgs = talloc_array(res, struct ldb_message *, res->count);
345 for (i = 0; i < res->count; i++) {
346 PyObject *item = PyList_GetItem(obj, i);
347 res->msgs[i] = pyldb_Message_AsMessage(item);
349 return res;
352 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
354 return PyBool_FromLong(ldb_dn_validate(self->dn));
357 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
359 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
362 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
364 return PyBool_FromLong(ldb_dn_is_special(self->dn));
367 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
369 return PyBool_FromLong(ldb_dn_is_null(self->dn));
372 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
374 return PyString_FromString(ldb_dn_get_casefold(self->dn));
377 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
379 return PyString_FromString(ldb_dn_get_linearized(self->dn));
382 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
384 return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
387 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
389 return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
392 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
394 const char * const kwnames[] = { "mode", NULL };
395 int mode = 1;
396 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
397 discard_const_p(char *, kwnames),
398 &mode))
399 return NULL;
400 return PyString_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
403 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
405 char *name;
406 const struct ldb_val *val;
408 if (!PyArg_ParseTuple(args, "s", &name))
409 return NULL;
410 val = ldb_dn_get_extended_component(self->dn, name);
411 if (val == NULL) {
412 Py_RETURN_NONE;
415 return PyString_FromStringAndSize((const char *)val->data, val->length);
418 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
420 char *name;
421 PyObject *value;
422 int err;
424 if (!PyArg_ParseTuple(args, "sO", &name, &value))
425 return NULL;
427 if (value == Py_None) {
428 err = ldb_dn_set_extended_component(self->dn, name, NULL);
429 } else {
430 struct ldb_val val;
431 if (!PyString_Check(value)) {
432 PyErr_SetString(PyExc_TypeError, "Expected a string argument");
433 return NULL;
435 val.data = (uint8_t *)PyString_AsString(value);
436 val.length = PyString_Size(value);
437 err = ldb_dn_set_extended_component(self->dn, name, &val);
440 if (err != LDB_SUCCESS) {
441 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
442 return NULL;
445 Py_RETURN_NONE;
448 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
450 return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
453 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
455 char *name;
457 if (!PyArg_ParseTuple(args, "s", &name))
458 return NULL;
460 return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
463 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
465 int ret;
466 ret = ldb_dn_compare(dn1->dn, dn2->dn);
467 if (ret < 0) ret = -1;
468 if (ret > 0) ret = 1;
469 return ret;
472 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
474 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
475 struct ldb_dn *parent;
476 PyLdbDnObject *py_ret;
477 TALLOC_CTX *mem_ctx = talloc_new(NULL);
479 parent = ldb_dn_get_parent(mem_ctx, dn);
480 if (parent == NULL) {
481 talloc_free(mem_ctx);
482 Py_RETURN_NONE;
485 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
486 if (py_ret == NULL) {
487 PyErr_NoMemory();
488 talloc_free(mem_ctx);
489 return NULL;
491 py_ret->mem_ctx = mem_ctx;
492 py_ret->dn = parent;
493 return (PyObject *)py_ret;
496 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
498 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
500 PyObject *py_other;
501 struct ldb_dn *dn, *other;
502 if (!PyArg_ParseTuple(args, "O", &py_other))
503 return NULL;
505 dn = pyldb_Dn_AsDn((PyObject *)self);
507 if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
508 return NULL;
510 return ldb_dn_add_child(dn, other)?Py_True:Py_False;
513 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
515 PyObject *py_other;
516 struct ldb_dn *other, *dn;
517 if (!PyArg_ParseTuple(args, "O", &py_other))
518 return NULL;
520 dn = pyldb_Dn_AsDn((PyObject *)self);
522 if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
523 return NULL;
525 return ldb_dn_add_base(dn, other)?Py_True:Py_False;
528 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
530 struct ldb_dn *dn;
531 int i;
532 if (!PyArg_ParseTuple(args, "i", &i))
533 return NULL;
535 dn = pyldb_Dn_AsDn((PyObject *)self);
537 return ldb_dn_remove_base_components(dn, i)?Py_True:Py_False;
540 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
542 PyObject *py_base;
543 struct ldb_dn *dn, *base;
544 if (!PyArg_ParseTuple(args, "O", &py_base))
545 return NULL;
547 dn = pyldb_Dn_AsDn((PyObject *)self);
549 if (!pyldb_Object_AsDn(NULL, py_base, dn_ldb_ctx(dn), &base))
550 return NULL;
552 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
555 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
557 struct ldb_dn *dn;
558 const char *name;
559 unsigned int num = 0;
561 if (!PyArg_ParseTuple(args, "I", &num))
562 return NULL;
564 dn = pyldb_Dn_AsDn((PyObject *)self);
566 name = ldb_dn_get_component_name(dn, num);
567 if (name == NULL) {
568 Py_RETURN_NONE;
571 return PyString_FromString(name);
574 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
576 struct ldb_dn *dn;
577 const struct ldb_val *val;
578 unsigned int num = 0;
580 if (!PyArg_ParseTuple(args, "I", &num))
581 return NULL;
583 dn = pyldb_Dn_AsDn((PyObject *)self);
585 val = ldb_dn_get_component_val(dn, num);
586 if (val == NULL) {
587 Py_RETURN_NONE;
590 return PyObject_FromLdbValue(val);
593 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
595 unsigned int num = 0;
596 char *name = NULL;
597 PyObject *value = Py_None;
598 struct ldb_val val = { NULL, };
599 int err;
601 if (!PyArg_ParseTuple(args, "IsO", &num, &name, &value))
602 return NULL;
604 if (value != Py_None) {
605 if (!PyString_Check(value)) {
606 PyErr_SetString(PyExc_TypeError, "Expected a string argument");
607 return NULL;
609 val.data = (uint8_t *)PyString_AsString(value);
610 val.length = PyString_Size(value);
613 err = ldb_dn_set_component(self->dn, num, name, val);
614 if (err != LDB_SUCCESS) {
615 PyErr_SetString(PyExc_TypeError, "Failed to set component");
616 return NULL;
619 Py_RETURN_NONE;
622 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
624 struct ldb_dn *dn;
625 const char *name;
627 dn = pyldb_Dn_AsDn((PyObject *)self);
629 name = ldb_dn_get_rdn_name(dn);
630 if (name == NULL) {
631 Py_RETURN_NONE;
634 return PyString_FromString(name);
637 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
639 struct ldb_dn *dn;
640 const struct ldb_val *val;
642 dn = pyldb_Dn_AsDn((PyObject *)self);
644 val = ldb_dn_get_rdn_val(dn);
645 if (val == NULL) {
646 Py_RETURN_NONE;
649 return PyObject_FromLdbValue(val);
652 static PyMethodDef py_ldb_dn_methods[] = {
653 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
654 "S.validate() -> bool\n"
655 "Validate DN is correct." },
656 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
657 "S.is_valid() -> bool\n" },
658 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
659 "S.is_special() -> bool\n"
660 "Check whether this is a special LDB DN." },
661 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
662 "Check whether this is a null DN." },
663 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
664 NULL },
665 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
666 NULL },
667 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
668 "S.canonical_str() -> string\n"
669 "Canonical version of this DN (like a posix path)." },
670 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
671 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
672 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
673 "S.canonical_ex_str() -> string\n"
674 "Canonical version of this DN (like a posix path, with terminating newline)." },
675 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
676 "S.extended_str(mode=1) -> string\n"
677 "Extended version of this DN" },
678 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
679 "S.parent() -> dn\n"
680 "Get the parent for this DN." },
681 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
682 "S.add_child(dn) -> None\n"
683 "Add a child DN to this DN." },
684 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
685 "S.add_base(dn) -> None\n"
686 "Add a base DN to this DN." },
687 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
688 "S.remove_base_components(int) -> bool\n"
689 "Remove a number of DN components from the base of this DN." },
690 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
691 "S.check_special(name) -> bool\n\n"
692 "Check if name is a special DN name"},
693 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
694 "S.get_extended_component(name) -> string\n\n"
695 "returns a DN extended component as a binary string"},
696 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
697 "S.set_extended_component(name, value) -> None\n\n"
698 "set a DN extended component as a binary string"},
699 { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
700 "S.get_component_name(num) -> string\n"
701 "get the attribute name of the specified component" },
702 { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
703 "S.get_component_value(num) -> string\n"
704 "get the attribute value of the specified component as a binary string" },
705 { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
706 "S.get_component_value(num, name, value) -> None\n"
707 "set the attribute name and value of the specified component" },
708 { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
709 "S.get_rdn_name() -> string\n"
710 "get the RDN attribute name" },
711 { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
712 "S.get_rdn_value() -> string\n"
713 "get the RDN attribute value as a binary string" },
714 { NULL }
717 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
719 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
723 copy a DN as a python object
725 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
727 PyLdbDnObject *py_ret;
729 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
730 if (py_ret == NULL) {
731 PyErr_NoMemory();
732 return NULL;
734 py_ret->mem_ctx = talloc_new(NULL);
735 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
736 return (PyObject *)py_ret;
739 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
741 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
742 *other;
743 PyLdbDnObject *py_ret;
745 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
746 return NULL;
748 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
749 if (py_ret == NULL) {
750 PyErr_NoMemory();
751 return NULL;
753 py_ret->mem_ctx = talloc_new(NULL);
754 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
755 ldb_dn_add_base(py_ret->dn, other);
756 return (PyObject *)py_ret;
759 static PySequenceMethods py_ldb_dn_seq = {
760 .sq_length = (lenfunc)py_ldb_dn_len,
761 .sq_concat = (binaryfunc)py_ldb_dn_concat,
764 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
766 struct ldb_dn *ret;
767 char *str;
768 PyObject *py_ldb;
769 struct ldb_context *ldb_ctx;
770 TALLOC_CTX *mem_ctx;
771 PyLdbDnObject *py_ret;
772 const char * const kwnames[] = { "ldb", "dn", NULL };
774 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
775 discard_const_p(char *, kwnames),
776 &py_ldb, &str))
777 return NULL;
779 if (!PyLdb_Check(py_ldb)) {
780 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
781 return NULL;
784 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
786 mem_ctx = talloc_new(NULL);
787 if (mem_ctx == NULL) {
788 PyErr_NoMemory();
789 return NULL;
792 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
793 if (!ldb_dn_validate(ret)) {
794 talloc_free(mem_ctx);
795 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
796 return NULL;
799 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
800 if (ret == NULL) {
801 talloc_free(mem_ctx);
802 PyErr_NoMemory();
803 return NULL;
805 py_ret->mem_ctx = mem_ctx;
806 py_ret->dn = ret;
807 return (PyObject *)py_ret;
810 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
812 talloc_free(self->mem_ctx);
813 PyObject_Del(self);
816 static PyTypeObject PyLdbDn = {
817 .tp_name = "ldb.Dn",
818 .tp_methods = py_ldb_dn_methods,
819 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
820 .tp_repr = (reprfunc)py_ldb_dn_repr,
821 .tp_compare = (cmpfunc)py_ldb_dn_compare,
822 .tp_as_sequence = &py_ldb_dn_seq,
823 .tp_doc = "A LDB distinguished name.",
824 .tp_new = py_ldb_dn_new,
825 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
826 .tp_basicsize = sizeof(PyLdbDnObject),
827 .tp_flags = Py_TPFLAGS_DEFAULT,
830 /* Debug */
831 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
832 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
834 PyObject *fn = (PyObject *)context;
835 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
838 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
840 PyObject *cb;
841 struct ldb_context *ldb_ctx;
843 if (!PyArg_ParseTuple(args, "O", &cb))
844 return NULL;
846 Py_INCREF(cb);
847 /* FIXME: Where do we DECREF cb ? */
848 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
849 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
850 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
851 ldb_ctx);
853 Py_RETURN_NONE;
856 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
858 unsigned int perms;
859 if (!PyArg_ParseTuple(args, "I", &perms))
860 return NULL;
862 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
864 Py_RETURN_NONE;
867 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
869 char *modules_dir;
870 if (!PyArg_ParseTuple(args, "s", &modules_dir))
871 return NULL;
873 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
875 Py_RETURN_NONE;
878 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
880 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
881 int ldb_err;
882 ldb_err = ldb_transaction_start(ldb_ctx);
883 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
884 Py_RETURN_NONE;
887 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
889 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
890 int ldb_err;
891 ldb_err = ldb_transaction_commit(ldb_ctx);
892 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
893 Py_RETURN_NONE;
896 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
898 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
899 int ldb_err;
900 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
901 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
902 Py_RETURN_NONE;
905 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
907 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
908 int ldb_err;
909 ldb_err = ldb_transaction_cancel(ldb_ctx);
910 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
911 Py_RETURN_NONE;
914 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
916 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
917 int ldb_err;
918 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
919 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
920 Py_RETURN_NONE;
923 static PyObject *py_ldb_repr(PyLdbObject *self)
925 return PyString_FromFormat("<ldb connection>");
928 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
930 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
931 if (dn == NULL)
932 Py_RETURN_NONE;
933 return py_ldb_dn_copy(dn);
937 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
939 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
940 if (dn == NULL)
941 Py_RETURN_NONE;
942 return py_ldb_dn_copy(dn);
945 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
947 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
948 if (dn == NULL)
949 Py_RETURN_NONE;
950 return py_ldb_dn_copy(dn);
953 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
955 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
956 if (dn == NULL)
957 Py_RETURN_NONE;
958 return py_ldb_dn_copy(dn);
961 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
962 const char *paramname)
964 const char **ret;
965 Py_ssize_t i;
966 if (!PyList_Check(list)) {
967 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
968 return NULL;
970 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
971 if (ret == NULL) {
972 PyErr_NoMemory();
973 return NULL;
976 for (i = 0; i < PyList_Size(list); i++) {
977 PyObject *item = PyList_GetItem(list, i);
978 if (!PyString_Check(item)) {
979 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
980 return NULL;
982 ret[i] = talloc_strndup(ret, PyString_AsString(item),
983 PyString_Size(item));
985 ret[i] = NULL;
986 return ret;
989 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
991 const char * const kwnames[] = { "url", "flags", "options", NULL };
992 char *url = NULL;
993 PyObject *py_options = Py_None;
994 const char **options;
995 unsigned int flags = 0;
996 int ret;
997 struct ldb_context *ldb;
999 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1000 discard_const_p(char *, kwnames),
1001 &url, &flags, &py_options))
1002 return -1;
1004 ldb = pyldb_Ldb_AsLdbContext(self);
1006 if (py_options == Py_None) {
1007 options = NULL;
1008 } else {
1009 options = PyList_AsStringList(ldb, py_options, "options");
1010 if (options == NULL)
1011 return -1;
1014 if (url != NULL) {
1015 ret = ldb_connect(ldb, url, flags, options);
1016 if (ret != LDB_SUCCESS) {
1017 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1018 return -1;
1022 talloc_free(options);
1023 return 0;
1026 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1028 PyLdbObject *ret;
1029 struct ldb_context *ldb;
1030 ret = (PyLdbObject *)type->tp_alloc(type, 0);
1031 if (ret == NULL) {
1032 PyErr_NoMemory();
1033 return NULL;
1035 ret->mem_ctx = talloc_new(NULL);
1036 ldb = ldb_init(ret->mem_ctx, NULL);
1038 if (ldb == NULL) {
1039 PyErr_NoMemory();
1040 return NULL;
1043 ret->ldb_ctx = ldb;
1044 return (PyObject *)ret;
1047 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1049 char *url;
1050 unsigned int flags = 0;
1051 PyObject *py_options = Py_None;
1052 int ret;
1053 const char **options;
1054 const char * const kwnames[] = { "url", "flags", "options", NULL };
1055 struct ldb_context *ldb_ctx;
1057 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
1058 discard_const_p(char *, kwnames),
1059 &url, &flags, &py_options))
1060 return NULL;
1062 if (py_options == Py_None) {
1063 options = NULL;
1064 } else {
1065 options = PyList_AsStringList(NULL, py_options, "options");
1066 if (options == NULL)
1067 return NULL;
1070 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1071 ret = ldb_connect(ldb_ctx, url, flags, options);
1072 talloc_free(options);
1074 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1076 Py_RETURN_NONE;
1079 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1081 PyObject *py_msg;
1082 PyObject *py_controls = Py_None;
1083 struct ldb_context *ldb_ctx;
1084 struct ldb_request *req;
1085 struct ldb_control **parsed_controls;
1086 struct ldb_message *msg;
1087 int ret;
1088 TALLOC_CTX *mem_ctx;
1089 bool validate=true;
1090 const char * const kwnames[] = { "message", "controls", "validate", NULL };
1092 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1093 discard_const_p(char *, kwnames),
1094 &py_msg, &py_controls, &validate))
1095 return NULL;
1097 mem_ctx = talloc_new(NULL);
1098 if (mem_ctx == NULL) {
1099 PyErr_NoMemory();
1100 return NULL;
1102 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1104 if (py_controls == Py_None) {
1105 parsed_controls = NULL;
1106 } else {
1107 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1108 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1109 talloc_free(controls);
1112 if (!PyLdbMessage_Check(py_msg)) {
1113 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1114 talloc_free(mem_ctx);
1115 return NULL;
1117 msg = pyldb_Message_AsMessage(py_msg);
1119 if (validate) {
1120 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1121 if (ret != LDB_SUCCESS) {
1122 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1123 talloc_free(mem_ctx);
1124 return NULL;
1128 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1129 NULL, ldb_op_default_callback, NULL);
1130 if (ret != LDB_SUCCESS) {
1131 PyErr_SetString(PyExc_TypeError, "failed to build request");
1132 talloc_free(mem_ctx);
1133 return NULL;
1136 /* do request and autostart a transaction */
1137 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1139 ret = ldb_transaction_start(ldb_ctx);
1140 if (ret != LDB_SUCCESS) {
1141 talloc_free(mem_ctx);
1142 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1143 return NULL;
1146 ret = ldb_request(ldb_ctx, req);
1147 if (ret == LDB_SUCCESS) {
1148 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1151 if (ret == LDB_SUCCESS) {
1152 ret = ldb_transaction_commit(ldb_ctx);
1153 } else {
1154 ldb_transaction_cancel(ldb_ctx);
1157 talloc_free(mem_ctx);
1158 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1160 Py_RETURN_NONE;
1165 * Obtain a ldb message from a Python Dictionary object.
1167 * @param mem_ctx Memory context
1168 * @param py_obj Python Dictionary object
1169 * @param ldb_ctx LDB context
1170 * @param mod_flags Flags to be set on every message element
1171 * @return ldb_message on success or NULL on failure
1173 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1174 PyObject *py_obj,
1175 struct ldb_context *ldb_ctx,
1176 unsigned int mod_flags)
1178 struct ldb_message *msg;
1179 unsigned int msg_pos = 0;
1180 Py_ssize_t dict_pos = 0;
1181 PyObject *key, *value;
1182 struct ldb_message_element *msg_el;
1183 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1185 msg = ldb_msg_new(mem_ctx);
1186 if (msg == NULL) {
1187 PyErr_NoMemory();
1188 return NULL;
1190 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1192 if (dn_value) {
1193 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1194 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1195 return NULL;
1197 if (msg->dn == NULL) {
1198 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1199 return NULL;
1201 } else {
1202 PyErr_SetString(PyExc_TypeError, "no dn set");
1203 return NULL;
1206 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1207 char *key_str = PyString_AsString(key);
1208 if (ldb_attr_cmp(key_str, "dn") != 0) {
1209 msg_el = PyObject_AsMessageElement(msg->elements, value,
1210 mod_flags, key_str);
1211 if (msg_el == NULL) {
1212 PyErr_SetString(PyExc_TypeError, "unable to import element");
1213 return NULL;
1215 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1216 msg_pos++;
1220 msg->num_elements = msg_pos;
1222 return msg;
1225 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1227 PyObject *py_obj;
1228 int ret;
1229 struct ldb_context *ldb_ctx;
1230 struct ldb_request *req;
1231 struct ldb_message *msg = NULL;
1232 PyObject *py_controls = Py_None;
1233 TALLOC_CTX *mem_ctx;
1234 struct ldb_control **parsed_controls;
1235 const char * const kwnames[] = { "message", "controls", NULL };
1237 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1238 discard_const_p(char *, kwnames),
1239 &py_obj, &py_controls))
1240 return NULL;
1242 mem_ctx = talloc_new(NULL);
1243 if (mem_ctx == NULL) {
1244 PyErr_NoMemory();
1245 return NULL;
1247 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1249 if (py_controls == Py_None) {
1250 parsed_controls = NULL;
1251 } else {
1252 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1253 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1254 talloc_free(controls);
1257 if (PyLdbMessage_Check(py_obj)) {
1258 msg = pyldb_Message_AsMessage(py_obj);
1259 } else if (PyDict_Check(py_obj)) {
1260 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1261 } else {
1262 PyErr_SetString(PyExc_TypeError,
1263 "Dictionary or LdbMessage object expected!");
1266 if (!msg) {
1267 /* we should have a PyErr already set */
1268 talloc_free(mem_ctx);
1269 return NULL;
1272 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1273 if (ret != LDB_SUCCESS) {
1274 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1275 talloc_free(mem_ctx);
1276 return NULL;
1279 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1280 NULL, ldb_op_default_callback, NULL);
1281 if (ret != LDB_SUCCESS) {
1282 PyErr_SetString(PyExc_TypeError, "failed to build request");
1283 talloc_free(mem_ctx);
1284 return NULL;
1287 /* do request and autostart a transaction */
1288 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1290 ret = ldb_transaction_start(ldb_ctx);
1291 if (ret != LDB_SUCCESS) {
1292 talloc_free(mem_ctx);
1293 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1294 return NULL;
1297 ret = ldb_request(ldb_ctx, req);
1298 if (ret == LDB_SUCCESS) {
1299 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1302 if (ret == LDB_SUCCESS) {
1303 ret = ldb_transaction_commit(ldb_ctx);
1304 } else {
1305 ldb_transaction_cancel(ldb_ctx);
1308 talloc_free(mem_ctx);
1309 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1311 Py_RETURN_NONE;
1314 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1316 PyObject *py_dn;
1317 struct ldb_dn *dn;
1318 int ret;
1319 struct ldb_context *ldb_ctx;
1320 struct ldb_request *req;
1321 PyObject *py_controls = Py_None;
1322 TALLOC_CTX *mem_ctx;
1323 struct ldb_control **parsed_controls;
1324 const char * const kwnames[] = { "dn", "controls", NULL };
1326 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1327 discard_const_p(char *, kwnames),
1328 &py_dn, &py_controls))
1329 return NULL;
1331 mem_ctx = talloc_new(NULL);
1332 if (mem_ctx == NULL) {
1333 PyErr_NoMemory();
1334 return NULL;
1336 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1338 if (py_controls == Py_None) {
1339 parsed_controls = NULL;
1340 } else {
1341 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1342 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1343 talloc_free(controls);
1346 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1347 talloc_free(mem_ctx);
1348 return NULL;
1351 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1352 NULL, ldb_op_default_callback, NULL);
1353 if (ret != LDB_SUCCESS) {
1354 PyErr_SetString(PyExc_TypeError, "failed to build request");
1355 talloc_free(mem_ctx);
1356 return NULL;
1359 /* do request and autostart a transaction */
1360 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1362 ret = ldb_transaction_start(ldb_ctx);
1363 if (ret != LDB_SUCCESS) {
1364 talloc_free(mem_ctx);
1365 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1366 return NULL;
1369 ret = ldb_request(ldb_ctx, req);
1370 if (ret == LDB_SUCCESS) {
1371 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1374 if (ret == LDB_SUCCESS) {
1375 ret = ldb_transaction_commit(ldb_ctx);
1376 } else {
1377 ldb_transaction_cancel(ldb_ctx);
1380 talloc_free(mem_ctx);
1381 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1383 Py_RETURN_NONE;
1386 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1388 PyObject *py_dn1, *py_dn2;
1389 struct ldb_dn *dn1, *dn2;
1390 int ret;
1391 TALLOC_CTX *mem_ctx;
1392 PyObject *py_controls = Py_None;
1393 struct ldb_control **parsed_controls;
1394 struct ldb_context *ldb_ctx;
1395 struct ldb_request *req;
1396 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1398 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1400 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1401 discard_const_p(char *, kwnames),
1402 &py_dn1, &py_dn2, &py_controls))
1403 return NULL;
1406 mem_ctx = talloc_new(NULL);
1407 if (mem_ctx == NULL) {
1408 PyErr_NoMemory();
1409 return NULL;
1412 if (py_controls == Py_None) {
1413 parsed_controls = NULL;
1414 } else {
1415 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1416 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1417 talloc_free(controls);
1421 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1422 talloc_free(mem_ctx);
1423 return NULL;
1426 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1427 talloc_free(mem_ctx);
1428 return NULL;
1431 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1432 NULL, ldb_op_default_callback, NULL);
1433 if (ret != LDB_SUCCESS) {
1434 PyErr_SetString(PyExc_TypeError, "failed to build request");
1435 talloc_free(mem_ctx);
1436 return NULL;
1439 /* do request and autostart a transaction */
1440 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1442 ret = ldb_transaction_start(ldb_ctx);
1443 if (ret != LDB_SUCCESS) {
1444 talloc_free(mem_ctx);
1445 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1446 return NULL;
1449 ret = ldb_request(ldb_ctx, req);
1450 if (ret == LDB_SUCCESS) {
1451 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1454 if (ret == LDB_SUCCESS) {
1455 ret = ldb_transaction_commit(ldb_ctx);
1456 } else {
1457 ldb_transaction_cancel(ldb_ctx);
1460 talloc_free(mem_ctx);
1461 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1463 Py_RETURN_NONE;
1466 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1468 char *name;
1469 if (!PyArg_ParseTuple(args, "s", &name))
1470 return NULL;
1472 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1474 Py_RETURN_NONE;
1477 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1479 char *attribute, *syntax;
1480 unsigned int flags;
1481 int ret;
1482 struct ldb_context *ldb_ctx;
1484 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1485 return NULL;
1487 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1488 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1490 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1492 Py_RETURN_NONE;
1495 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1497 if (ldif == NULL) {
1498 Py_RETURN_NONE;
1499 } else {
1500 /* We don't want this attached to the 'ldb' any more */
1501 return Py_BuildValue(discard_const_p(char, "(iO)"),
1502 ldif->changetype,
1503 PyLdbMessage_FromMessage(ldif->msg));
1508 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1510 int changetype;
1511 PyObject *py_msg;
1512 struct ldb_ldif ldif;
1513 PyObject *ret;
1514 char *string;
1515 TALLOC_CTX *mem_ctx;
1517 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1518 return NULL;
1520 if (!PyLdbMessage_Check(py_msg)) {
1521 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1522 return NULL;
1525 ldif.msg = pyldb_Message_AsMessage(py_msg);
1526 ldif.changetype = changetype;
1528 mem_ctx = talloc_new(NULL);
1530 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1531 if (!string) {
1532 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1533 return NULL;
1536 ret = PyString_FromString(string);
1538 talloc_free(mem_ctx);
1540 return ret;
1543 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1545 PyObject *list;
1546 struct ldb_ldif *ldif;
1547 const char *s;
1549 TALLOC_CTX *mem_ctx;
1551 if (!PyArg_ParseTuple(args, "s", &s))
1552 return NULL;
1554 mem_ctx = talloc_new(NULL);
1555 if (!mem_ctx) {
1556 Py_RETURN_NONE;
1559 list = PyList_New(0);
1560 while (s && *s != '\0') {
1561 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1562 talloc_steal(mem_ctx, ldif);
1563 if (ldif) {
1564 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1565 } else {
1566 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1567 talloc_free(mem_ctx);
1568 return NULL;
1571 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1572 return PyObject_GetIter(list);
1575 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1577 int ldb_ret;
1578 PyObject *py_msg_old;
1579 PyObject *py_msg_new;
1580 struct ldb_message *diff;
1581 struct ldb_context *ldb;
1582 PyObject *py_ret;
1584 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1585 return NULL;
1587 if (!PyLdbMessage_Check(py_msg_old)) {
1588 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1589 return NULL;
1592 if (!PyLdbMessage_Check(py_msg_new)) {
1593 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1594 return NULL;
1597 ldb = pyldb_Ldb_AsLdbContext(self);
1598 ldb_ret = ldb_msg_difference(ldb, ldb,
1599 pyldb_Message_AsMessage(py_msg_old),
1600 pyldb_Message_AsMessage(py_msg_new),
1601 &diff);
1602 if (ldb_ret != LDB_SUCCESS) {
1603 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1604 return NULL;
1607 py_ret = PyLdbMessage_FromMessage(diff);
1609 talloc_unlink(ldb, diff);
1611 return py_ret;
1614 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1616 const struct ldb_schema_attribute *a;
1617 struct ldb_val old_val;
1618 struct ldb_val new_val;
1619 TALLOC_CTX *mem_ctx;
1620 PyObject *ret;
1621 char *element_name;
1622 PyObject *val;
1624 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1625 return NULL;
1627 mem_ctx = talloc_new(NULL);
1629 old_val.data = (uint8_t *)PyString_AsString(val);
1630 old_val.length = PyString_Size(val);
1632 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1634 if (a == NULL) {
1635 Py_RETURN_NONE;
1638 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1639 talloc_free(mem_ctx);
1640 Py_RETURN_NONE;
1643 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1645 talloc_free(mem_ctx);
1647 return ret;
1650 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1652 PyObject *py_base = Py_None;
1653 int scope = LDB_SCOPE_DEFAULT;
1654 char *expr = NULL;
1655 PyObject *py_attrs = Py_None;
1656 PyObject *py_controls = Py_None;
1657 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1658 int ret;
1659 struct ldb_result *res;
1660 struct ldb_request *req;
1661 const char **attrs;
1662 struct ldb_context *ldb_ctx;
1663 struct ldb_control **parsed_controls;
1664 struct ldb_dn *base;
1665 PyObject *py_ret;
1666 TALLOC_CTX *mem_ctx;
1668 /* type "int" rather than "enum" for "scope" is intentional */
1669 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1670 discard_const_p(char *, kwnames),
1671 &py_base, &scope, &expr, &py_attrs, &py_controls))
1672 return NULL;
1675 mem_ctx = talloc_new(NULL);
1676 if (mem_ctx == NULL) {
1677 PyErr_NoMemory();
1678 return NULL;
1680 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1682 if (py_attrs == Py_None) {
1683 attrs = NULL;
1684 } else {
1685 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1686 if (attrs == NULL) {
1687 talloc_free(mem_ctx);
1688 return NULL;
1692 if (py_base == Py_None) {
1693 base = ldb_get_default_basedn(ldb_ctx);
1694 } else {
1695 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1696 talloc_free(attrs);
1697 return NULL;
1701 if (py_controls == Py_None) {
1702 parsed_controls = NULL;
1703 } else {
1704 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1705 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1706 talloc_free(controls);
1709 res = talloc_zero(mem_ctx, struct ldb_result);
1710 if (res == NULL) {
1711 PyErr_NoMemory();
1712 talloc_free(mem_ctx);
1713 return NULL;
1716 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1717 base,
1718 scope,
1719 expr,
1720 attrs,
1721 parsed_controls,
1722 res,
1723 ldb_search_default_callback,
1724 NULL);
1726 if (ret != LDB_SUCCESS) {
1727 talloc_free(mem_ctx);
1728 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1729 return NULL;
1732 talloc_steal(req, attrs);
1734 ret = ldb_request(ldb_ctx, req);
1736 if (ret == LDB_SUCCESS) {
1737 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1740 if (ret != LDB_SUCCESS) {
1741 talloc_free(mem_ctx);
1742 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1743 return NULL;
1746 py_ret = PyLdbResult_FromResult(res);
1748 talloc_free(mem_ctx);
1750 return py_ret;
1753 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1755 char *name;
1756 void *data;
1758 if (!PyArg_ParseTuple(args, "s", &name))
1759 return NULL;
1761 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1763 if (data == NULL)
1764 Py_RETURN_NONE;
1766 /* FIXME: More interpretation */
1768 return Py_True;
1771 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1773 char *name;
1774 PyObject *data;
1776 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1777 return NULL;
1779 /* FIXME: More interpretation */
1781 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1783 Py_RETURN_NONE;
1786 static PyObject *py_ldb_modules(PyLdbObject *self)
1788 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1789 PyObject *ret = PyList_New(0);
1790 struct ldb_module *mod;
1792 for (mod = ldb->modules; mod; mod = mod->next) {
1793 PyList_Append(ret, PyLdbModule_FromModule(mod));
1796 return ret;
1799 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1801 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1802 int type, ret;
1803 uint64_t value;
1805 if (!PyArg_ParseTuple(args, "i", &type))
1806 return NULL;
1808 /* FIXME: More interpretation */
1810 ret = ldb_sequence_number(ldb, type, &value);
1812 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1814 return PyLong_FromLongLong(value);
1816 static PyMethodDef py_ldb_methods[] = {
1817 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1818 "S.set_debug(callback) -> None\n"
1819 "Set callback for LDB debug messages.\n"
1820 "The callback should accept a debug level and debug text." },
1821 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1822 "S.set_create_perms(mode) -> None\n"
1823 "Set mode to use when creating new LDB files." },
1824 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1825 "S.set_modules_dir(path) -> None\n"
1826 "Set path LDB should search for modules" },
1827 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1828 "S.transaction_start() -> None\n"
1829 "Start a new transaction." },
1830 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1831 "S.transaction_prepare_commit() -> None\n"
1832 "prepare to commit a new transaction (2-stage commit)." },
1833 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1834 "S.transaction_commit() -> None\n"
1835 "commit a new transaction." },
1836 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1837 "S.transaction_cancel() -> None\n"
1838 "cancel a new transaction." },
1839 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1840 NULL },
1841 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1842 NULL },
1843 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1844 NULL },
1845 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1846 NULL },
1847 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1848 NULL },
1849 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1850 "S.connect(url, flags=0, options=None) -> None\n"
1851 "Connect to a LDB URL." },
1852 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1853 "S.modify(message, controls=None, validate=False) -> None\n"
1854 "Modify an entry." },
1855 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1856 "S.add(message, controls=None) -> None\n"
1857 "Add an entry." },
1858 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1859 "S.delete(dn, controls=None) -> None\n"
1860 "Remove an entry." },
1861 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1862 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1863 "Rename an entry." },
1864 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1865 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1866 "Search in a database.\n"
1867 "\n"
1868 ":param base: Optional base DN to search\n"
1869 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1870 ":param expression: Optional search expression\n"
1871 ":param attrs: Attributes to return (defaults to all)\n"
1872 ":param controls: Optional list of controls\n"
1873 ":return: Iterator over Message objects\n"
1875 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1876 NULL },
1877 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1878 NULL },
1879 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1880 NULL },
1881 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1882 "S.parse_ldif(ldif) -> iter(messages)\n"
1883 "Parse a string formatted using LDIF." },
1884 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1885 "S.write_ldif(message, changetype) -> ldif\n"
1886 "Print the message as a string formatted using LDIF." },
1887 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1888 "S.msg_diff(Message) -> Message\n"
1889 "Return an LDB Message of the difference between two Message objects." },
1890 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1891 "S.get_opaque(name) -> value\n"
1892 "Get an opaque value set on this LDB connection. \n"
1893 ":note: The returned value may not be useful in Python."
1895 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1896 "S.set_opaque(name, value) -> None\n"
1897 "Set an opaque value on this LDB connection. \n"
1898 ":note: Passing incorrect values may cause crashes." },
1899 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1900 "S.modules() -> list\n"
1901 "Return the list of modules on this LDB connection " },
1902 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1903 "S.sequence_number(type) -> value\n"
1904 "Return the value of the sequence according to the requested type" },
1905 { NULL },
1908 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1910 PyLdbModuleObject *ret;
1912 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1913 if (ret == NULL) {
1914 PyErr_NoMemory();
1915 return NULL;
1917 ret->mem_ctx = talloc_new(NULL);
1918 ret->mod = talloc_reference(ret->mem_ctx, mod);
1919 return (PyObject *)ret;
1922 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1924 return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1927 static PyGetSetDef py_ldb_getset[] = {
1928 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1929 { NULL }
1932 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1934 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1935 struct ldb_dn *dn;
1936 struct ldb_result *result;
1937 unsigned int count;
1938 int ret;
1940 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1941 return -1;
1944 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1945 NULL);
1946 if (ret != LDB_SUCCESS) {
1947 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1948 return -1;
1951 count = result->count;
1953 talloc_free(result);
1955 if (count > 1) {
1956 PyErr_Format(PyExc_RuntimeError,
1957 "Searching for [%s] dn gave %u results!",
1958 ldb_dn_get_linearized(dn),
1959 count);
1960 return -1;
1963 return count;
1966 static PySequenceMethods py_ldb_seq = {
1967 .sq_contains = (objobjproc)py_ldb_contains,
1970 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1972 PyLdbObject *ret;
1974 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1975 if (ret == NULL) {
1976 PyErr_NoMemory();
1977 return NULL;
1979 ret->mem_ctx = talloc_new(NULL);
1980 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1981 return (PyObject *)ret;
1984 static void py_ldb_dealloc(PyLdbObject *self)
1986 talloc_free(self->mem_ctx);
1987 self->ob_type->tp_free(self);
1990 static PyTypeObject PyLdb = {
1991 .tp_name = "ldb.Ldb",
1992 .tp_methods = py_ldb_methods,
1993 .tp_repr = (reprfunc)py_ldb_repr,
1994 .tp_new = py_ldb_new,
1995 .tp_init = (initproc)py_ldb_init,
1996 .tp_dealloc = (destructor)py_ldb_dealloc,
1997 .tp_getset = py_ldb_getset,
1998 .tp_getattro = PyObject_GenericGetAttr,
1999 .tp_basicsize = sizeof(PyLdbObject),
2000 .tp_doc = "Connection to a LDB database.",
2001 .tp_as_sequence = &py_ldb_seq,
2002 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2005 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2007 talloc_free(self->mem_ctx);
2008 Py_DECREF(self->msgs);
2009 Py_DECREF(self->referals);
2010 Py_DECREF(self->controls);
2011 self->ob_type->tp_free(self);
2014 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2016 Py_INCREF(self->msgs);
2017 return self->msgs;
2020 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2022 Py_INCREF(self->controls);
2023 return self->controls;
2026 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2028 Py_INCREF(self->referals);
2029 return self->referals;
2032 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2034 Py_ssize_t size;
2035 if (self->msgs == NULL) {
2036 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2037 return NULL;
2039 size = PyList_Size(self->msgs);
2040 return PyInt_FromLong(size);
2043 static PyGetSetDef py_ldb_result_getset[] = {
2044 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2045 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2046 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2047 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2048 { NULL }
2051 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2053 return PyObject_GetIter(self->msgs);
2056 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2058 return PySequence_Size(self->msgs);
2061 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2063 return PySequence_GetItem(self->msgs, idx);
2066 static PySequenceMethods py_ldb_result_seq = {
2067 .sq_length = (lenfunc)py_ldb_result_len,
2068 .sq_item = (ssizeargfunc)py_ldb_result_find,
2071 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2073 return PyString_FromFormat("<ldb result>");
2077 static PyTypeObject PyLdbResult = {
2078 .tp_name = "ldb.Result",
2079 .tp_repr = (reprfunc)py_ldb_result_repr,
2080 .tp_dealloc = (destructor)py_ldb_result_dealloc,
2081 .tp_iter = (getiterfunc)py_ldb_result_iter,
2082 .tp_getset = py_ldb_result_getset,
2083 .tp_getattro = PyObject_GenericGetAttr,
2084 .tp_basicsize = sizeof(PyLdbResultObject),
2085 .tp_as_sequence = &py_ldb_result_seq,
2086 .tp_doc = "LDB result.",
2087 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2090 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2092 return PyString_FromFormat("<ldb module '%s'>",
2093 pyldb_Module_AsModule(self)->ops->name);
2096 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2098 return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
2101 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2103 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2104 Py_RETURN_NONE;
2107 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2109 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2110 Py_RETURN_NONE;
2113 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2115 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2116 Py_RETURN_NONE;
2119 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2121 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2122 int ret, scope;
2123 struct ldb_request *req;
2124 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2125 struct ldb_module *mod;
2126 const char * const*attrs;
2128 /* type "int" rather than "enum" for "scope" is intentional */
2129 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
2130 discard_const_p(char *, kwnames),
2131 &py_base, &scope, &py_tree, &py_attrs))
2132 return NULL;
2134 mod = self->mod;
2136 if (py_attrs == Py_None) {
2137 attrs = NULL;
2138 } else {
2139 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
2140 if (attrs == NULL)
2141 return NULL;
2144 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2145 scope, NULL /* expr */, attrs,
2146 NULL /* controls */, NULL, NULL, NULL);
2148 talloc_steal(req, attrs);
2150 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2152 req->op.search.res = NULL;
2154 ret = mod->ops->search(mod, req);
2156 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2158 py_ret = PyLdbResult_FromResult(req->op.search.res);
2160 talloc_free(req);
2162 return py_ret;
2166 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2168 struct ldb_request *req;
2169 PyObject *py_message;
2170 int ret;
2171 struct ldb_module *mod;
2173 if (!PyArg_ParseTuple(args, "O", &py_message))
2174 return NULL;
2176 req = talloc_zero(NULL, struct ldb_request);
2177 req->operation = LDB_ADD;
2178 req->op.add.message = pyldb_Message_AsMessage(py_message);
2180 mod = pyldb_Module_AsModule(self);
2181 ret = mod->ops->add(mod, req);
2183 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2185 Py_RETURN_NONE;
2188 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2190 int ret;
2191 struct ldb_request *req;
2192 PyObject *py_message;
2193 struct ldb_module *mod;
2195 if (!PyArg_ParseTuple(args, "O", &py_message))
2196 return NULL;
2198 req = talloc_zero(NULL, struct ldb_request);
2199 req->operation = LDB_MODIFY;
2200 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2202 mod = pyldb_Module_AsModule(self);
2203 ret = mod->ops->modify(mod, req);
2205 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2207 Py_RETURN_NONE;
2210 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2212 int ret;
2213 struct ldb_request *req;
2214 PyObject *py_dn;
2216 if (!PyArg_ParseTuple(args, "O", &py_dn))
2217 return NULL;
2219 req = talloc_zero(NULL, struct ldb_request);
2220 req->operation = LDB_DELETE;
2221 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2223 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2225 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2227 Py_RETURN_NONE;
2230 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2232 int ret;
2233 struct ldb_request *req;
2234 PyObject *py_dn1, *py_dn2;
2236 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
2237 return NULL;
2239 req = talloc_zero(NULL, struct ldb_request);
2241 req->operation = LDB_RENAME;
2242 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2243 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2245 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2247 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2249 Py_RETURN_NONE;
2252 static PyMethodDef py_ldb_module_methods[] = {
2253 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2254 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2255 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2256 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2257 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2258 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2259 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2260 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2261 { NULL },
2264 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2266 talloc_free(self->mem_ctx);
2267 PyObject_Del(self);
2270 static PyTypeObject PyLdbModule = {
2271 .tp_name = "ldb.LdbModule",
2272 .tp_methods = py_ldb_module_methods,
2273 .tp_repr = (reprfunc)py_ldb_module_repr,
2274 .tp_str = (reprfunc)py_ldb_module_str,
2275 .tp_basicsize = sizeof(PyLdbModuleObject),
2276 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2277 .tp_flags = Py_TPFLAGS_DEFAULT,
2278 .tp_doc = "LDB module (extension)",
2283 * Create a ldb_message_element from a Python object.
2285 * This will accept any sequence objects that contains strings, or
2286 * a string object.
2288 * A reference to set_obj will be borrowed.
2290 * @param mem_ctx Memory context
2291 * @param set_obj Python object to convert
2292 * @param flags ldb_message_element flags to set
2293 * @param attr_name Name of the attribute
2294 * @return New ldb_message_element, allocated as child of mem_ctx
2296 static struct ldb_message_element *PyObject_AsMessageElement(
2297 TALLOC_CTX *mem_ctx,
2298 PyObject *set_obj,
2299 unsigned int flags,
2300 const char *attr_name)
2302 struct ldb_message_element *me;
2304 if (pyldb_MessageElement_Check(set_obj)) {
2305 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2306 /* We have to talloc_reference() the memory context, not the pointer
2307 * which may not actually be it's own context */
2308 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2309 return pyldb_MessageElement_AsMessageElement(set_obj);
2311 return NULL;
2314 me = talloc(mem_ctx, struct ldb_message_element);
2315 if (me == NULL) {
2316 PyErr_NoMemory();
2317 return NULL;
2320 me->name = talloc_strdup(me, attr_name);
2321 me->flags = flags;
2322 if (PyString_Check(set_obj)) {
2323 me->num_values = 1;
2324 me->values = talloc_array(me, struct ldb_val, me->num_values);
2325 me->values[0].length = PyString_Size(set_obj);
2326 me->values[0].data = talloc_memdup(me,
2327 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2328 } else if (PySequence_Check(set_obj)) {
2329 Py_ssize_t i;
2330 me->num_values = PySequence_Size(set_obj);
2331 me->values = talloc_array(me, struct ldb_val, me->num_values);
2332 for (i = 0; i < me->num_values; i++) {
2333 PyObject *obj = PySequence_GetItem(set_obj, i);
2334 if (!PyString_Check(obj)) {
2335 PyErr_Format(PyExc_TypeError,
2336 "Expected string as element %zd in list", i);
2337 talloc_free(me);
2338 return NULL;
2341 me->values[i].length = PyString_Size(obj);
2342 me->values[i].data = talloc_memdup(me,
2343 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2345 } else {
2346 talloc_free(me);
2347 me = NULL;
2350 return me;
2354 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2355 struct ldb_message_element *me)
2357 Py_ssize_t i;
2358 PyObject *result;
2360 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2361 result = PyList_New(me->num_values);
2363 for (i = 0; i < me->num_values; i++) {
2364 PyList_SetItem(result, i,
2365 PyObject_FromLdbValue(&me->values[i]));
2368 return result;
2371 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2373 unsigned int i;
2374 if (!PyArg_ParseTuple(args, "I", &i))
2375 return NULL;
2376 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2377 Py_RETURN_NONE;
2379 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2382 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2384 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2385 return PyInt_FromLong(el->flags);
2388 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2390 unsigned int flags;
2391 struct ldb_message_element *el;
2392 if (!PyArg_ParseTuple(args, "I", &flags))
2393 return NULL;
2395 el = pyldb_MessageElement_AsMessageElement(self);
2396 el->flags = flags;
2397 Py_RETURN_NONE;
2400 static PyMethodDef py_ldb_msg_element_methods[] = {
2401 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2402 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2403 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2404 { NULL },
2407 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2409 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2412 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2414 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2415 if (idx < 0 || idx >= el->num_values) {
2416 PyErr_SetString(PyExc_IndexError, "Out of range");
2417 return NULL;
2419 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2422 static PySequenceMethods py_ldb_msg_element_seq = {
2423 .sq_length = (lenfunc)py_ldb_msg_element_len,
2424 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2427 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2429 int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2430 pyldb_MessageElement_AsMessageElement(other));
2431 return SIGN(ret);
2434 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2436 PyObject *el = ldb_msg_element_to_set(NULL,
2437 pyldb_MessageElement_AsMessageElement(self));
2438 return PyObject_GetIter(el);
2441 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2443 PyLdbMessageElementObject *ret;
2444 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2445 if (ret == NULL) {
2446 PyErr_NoMemory();
2447 return NULL;
2449 ret->mem_ctx = talloc_new(NULL);
2450 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2451 PyErr_NoMemory();
2452 return NULL;
2454 ret->el = el;
2455 return (PyObject *)ret;
2458 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2460 PyObject *py_elements = NULL;
2461 struct ldb_message_element *el;
2462 unsigned int flags = 0;
2463 char *name = NULL;
2464 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2465 PyLdbMessageElementObject *ret;
2466 TALLOC_CTX *mem_ctx;
2468 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2469 discard_const_p(char *, kwnames),
2470 &py_elements, &flags, &name))
2471 return NULL;
2473 mem_ctx = talloc_new(NULL);
2474 if (mem_ctx == NULL) {
2475 PyErr_NoMemory();
2476 return NULL;
2479 el = talloc_zero(mem_ctx, struct ldb_message_element);
2480 if (el == NULL) {
2481 PyErr_NoMemory();
2482 talloc_free(mem_ctx);
2483 return NULL;
2486 if (py_elements != NULL) {
2487 Py_ssize_t i;
2488 if (PyString_Check(py_elements)) {
2489 el->num_values = 1;
2490 el->values = talloc_array(el, struct ldb_val, 1);
2491 if (el->values == NULL) {
2492 talloc_free(mem_ctx);
2493 PyErr_NoMemory();
2494 return NULL;
2496 el->values[0].length = PyString_Size(py_elements);
2497 el->values[0].data = talloc_memdup(el->values,
2498 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2499 } else if (PySequence_Check(py_elements)) {
2500 el->num_values = PySequence_Size(py_elements);
2501 el->values = talloc_array(el, struct ldb_val, el->num_values);
2502 if (el->values == NULL) {
2503 talloc_free(mem_ctx);
2504 PyErr_NoMemory();
2505 return NULL;
2507 for (i = 0; i < el->num_values; i++) {
2508 PyObject *item = PySequence_GetItem(py_elements, i);
2509 if (item == NULL) {
2510 talloc_free(mem_ctx);
2511 return NULL;
2513 if (!PyString_Check(item)) {
2514 PyErr_Format(PyExc_TypeError,
2515 "Expected string as element %zd in list", i);
2516 talloc_free(mem_ctx);
2517 return NULL;
2519 el->values[i].length = PyString_Size(item);
2520 el->values[i].data = talloc_memdup(el,
2521 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2523 } else {
2524 PyErr_SetString(PyExc_TypeError,
2525 "Expected string or list");
2526 talloc_free(mem_ctx);
2527 return NULL;
2531 el->flags = flags;
2532 el->name = talloc_strdup(el, name);
2534 ret = PyObject_New(PyLdbMessageElementObject, type);
2535 if (ret == NULL) {
2536 talloc_free(mem_ctx);
2537 return NULL;
2540 ret->mem_ctx = mem_ctx;
2541 ret->el = el;
2542 return (PyObject *)ret;
2545 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2547 char *element_str = NULL;
2548 Py_ssize_t i;
2549 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2550 PyObject *ret;
2552 for (i = 0; i < el->num_values; i++) {
2553 PyObject *o = py_ldb_msg_element_find(self, i);
2554 if (element_str == NULL)
2555 element_str = talloc_strdup(NULL, PyObject_REPR(o));
2556 else
2557 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2560 if (element_str != NULL) {
2561 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2562 talloc_free(element_str);
2563 } else {
2564 ret = PyString_FromString("MessageElement([])");
2567 return ret;
2570 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2572 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2574 if (el->num_values == 1)
2575 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2576 else
2577 Py_RETURN_NONE;
2580 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2582 talloc_free(self->mem_ctx);
2583 PyObject_Del(self);
2586 static PyTypeObject PyLdbMessageElement = {
2587 .tp_name = "ldb.MessageElement",
2588 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2589 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2590 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2591 .tp_str = (reprfunc)py_ldb_msg_element_str,
2592 .tp_methods = py_ldb_msg_element_methods,
2593 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2594 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2595 .tp_as_sequence = &py_ldb_msg_element_seq,
2596 .tp_new = py_ldb_msg_element_new,
2597 .tp_flags = Py_TPFLAGS_DEFAULT,
2598 .tp_doc = "An element of a Message",
2602 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2604 PyObject *py_ldb;
2605 PyObject *py_dict;
2606 PyObject *py_ret;
2607 struct ldb_message *msg;
2608 struct ldb_context *ldb_ctx;
2609 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2611 if (!PyArg_ParseTuple(args, "O!O!|I",
2612 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2613 &mod_flags)) {
2614 return NULL;
2617 if (!PyLdb_Check(py_ldb)) {
2618 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
2619 return NULL;
2622 /* mask only flags we are going to use */
2623 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2624 if (!mod_flags) {
2625 PyErr_SetString(PyExc_ValueError,
2626 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2627 " expected as mod_flag value");
2628 return NULL;
2631 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2633 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2634 if (!msg) {
2635 return NULL;
2638 py_ret = PyLdbMessage_FromMessage(msg);
2640 talloc_unlink(ldb_ctx, msg);
2642 return py_ret;
2645 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2647 char *name;
2648 if (!PyArg_ParseTuple(args, "s", &name))
2649 return NULL;
2651 ldb_msg_remove_attr(self->msg, name);
2653 Py_RETURN_NONE;
2656 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2658 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2659 Py_ssize_t i, j = 0;
2660 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2661 if (msg->dn != NULL) {
2662 PyList_SetItem(obj, j, PyString_FromString("dn"));
2663 j++;
2665 for (i = 0; i < msg->num_elements; i++) {
2666 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2667 j++;
2669 return obj;
2672 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2674 struct ldb_message_element *el;
2675 char *name;
2676 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2677 if (!PyString_Check(py_name)) {
2678 PyErr_SetNone(PyExc_TypeError);
2679 return NULL;
2681 name = PyString_AsString(py_name);
2682 if (!ldb_attr_cmp(name, "dn"))
2683 return pyldb_Dn_FromDn(msg->dn);
2684 el = ldb_msg_find_element(msg, name);
2685 if (el == NULL) {
2686 return NULL;
2688 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2691 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2693 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2694 if (ret == NULL) {
2695 PyErr_SetString(PyExc_KeyError, "No such element");
2696 return NULL;
2698 return ret;
2701 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2703 PyObject *def = NULL;
2704 const char *kwnames[] = { "name", "default", "idx", NULL };
2705 const char *name = NULL;
2706 int idx = -1;
2707 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2708 struct ldb_message_element *el;
2710 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2711 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2712 return NULL;
2715 if (strcasecmp(name, "dn") == 0) {
2716 return pyldb_Dn_FromDn(msg->dn);
2719 el = ldb_msg_find_element(msg, name);
2721 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2722 if (def != NULL) {
2723 return def;
2725 Py_RETURN_NONE;
2728 if (idx == -1) {
2729 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2732 return PyObject_FromLdbValue(&el->values[idx]);
2735 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2737 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2738 Py_ssize_t i, j = 0;
2739 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2740 if (msg->dn != NULL) {
2741 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2742 j++;
2744 for (i = 0; i < msg->num_elements; i++, j++) {
2745 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2746 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2747 PyList_SetItem(l, j, value);
2749 return l;
2752 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2754 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2755 Py_ssize_t i = 0;
2756 PyObject *l = PyList_New(msg->num_elements);
2757 for (i = 0; i < msg->num_elements; i++) {
2758 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2760 return l;
2763 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2765 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2766 PyLdbMessageElementObject *py_element;
2767 int ret;
2768 struct ldb_message_element *el;
2770 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2771 return NULL;
2773 el = talloc_reference(msg, py_element->el);
2774 if (el == NULL) {
2775 PyErr_NoMemory();
2776 return NULL;
2779 ret = ldb_msg_add(msg, el, el->flags);
2780 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2782 Py_RETURN_NONE;
2785 static PyMethodDef py_ldb_msg_methods[] = {
2786 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2787 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2788 "Class method to create ldb.Message object from Dictionary.\n"
2789 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2790 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2791 "S.keys() -> list\n\n"
2792 "Return sequence of all attribute names." },
2793 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2794 "S.remove(name)\n\n"
2795 "Remove all entries for attributes with the specified name."},
2796 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2797 "msg.get(name,default=None,idx=None) -> string\n"
2798 "idx is the index into the values array\n"
2799 "if idx is None, then a list is returned\n"
2800 "if idx is not None, then the element with that index is returned\n"
2801 "if you pass the special name 'dn' then the DN object is returned\n"},
2802 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2803 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2804 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2805 "S.append(element)\n\n"
2806 "Add an element to this message." },
2807 { NULL },
2810 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2812 PyObject *list, *iter;
2814 list = py_ldb_msg_keys(self);
2815 iter = PyObject_GetIter(list);
2816 Py_DECREF(list);
2817 return iter;
2820 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2822 char *attr_name;
2824 if (!PyString_Check(name)) {
2825 PyErr_SetNone(PyExc_TypeError);
2826 return -1;
2829 attr_name = PyString_AsString(name);
2830 if (value == NULL) {
2831 /* delitem */
2832 ldb_msg_remove_attr(self->msg, attr_name);
2833 } else {
2834 int ret;
2835 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2836 value, 0, attr_name);
2837 if (el == NULL)
2838 return -1;
2839 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2840 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2841 if (ret != LDB_SUCCESS) {
2842 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
2843 return -1;
2846 return 0;
2849 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2851 return pyldb_Message_AsMessage(self)->num_elements;
2854 static PyMappingMethods py_ldb_msg_mapping = {
2855 .mp_length = (lenfunc)py_ldb_msg_length,
2856 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2857 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2860 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2862 const char * const kwnames[] = { "dn", NULL };
2863 struct ldb_message *ret;
2864 TALLOC_CTX *mem_ctx;
2865 PyObject *pydn = NULL;
2866 PyLdbMessageObject *py_ret;
2868 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2869 discard_const_p(char *, kwnames),
2870 &pydn))
2871 return NULL;
2873 mem_ctx = talloc_new(NULL);
2874 if (mem_ctx == NULL) {
2875 PyErr_NoMemory();
2876 return NULL;
2879 ret = ldb_msg_new(mem_ctx);
2880 if (ret == NULL) {
2881 talloc_free(mem_ctx);
2882 PyErr_NoMemory();
2883 return NULL;
2886 if (pydn != NULL) {
2887 struct ldb_dn *dn;
2888 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2889 talloc_free(mem_ctx);
2890 return NULL;
2892 ret->dn = talloc_reference(ret, dn);
2895 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2896 if (py_ret == NULL) {
2897 PyErr_NoMemory();
2898 talloc_free(mem_ctx);
2899 return NULL;
2902 py_ret->mem_ctx = mem_ctx;
2903 py_ret->msg = ret;
2904 return (PyObject *)py_ret;
2907 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2909 PyLdbMessageObject *ret;
2911 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2912 if (ret == NULL) {
2913 PyErr_NoMemory();
2914 return NULL;
2916 ret->mem_ctx = talloc_new(NULL);
2917 ret->msg = talloc_reference(ret->mem_ctx, msg);
2918 return (PyObject *)ret;
2921 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2923 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2924 return pyldb_Dn_FromDn(msg->dn);
2927 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2929 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2930 if (!pyldb_Dn_Check(value)) {
2931 PyErr_SetNone(PyExc_TypeError);
2932 return -1;
2935 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2936 return 0;
2939 static PyGetSetDef py_ldb_msg_getset[] = {
2940 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2941 { NULL }
2944 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2946 PyObject *dict = PyDict_New(), *ret;
2947 if (PyDict_Update(dict, (PyObject *)self) != 0)
2948 return NULL;
2949 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2950 Py_DECREF(dict);
2951 return ret;
2954 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2956 talloc_free(self->mem_ctx);
2957 PyObject_Del(self);
2960 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2961 PyLdbMessageObject *py_msg2)
2963 struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
2964 *msg2 = pyldb_Message_AsMessage(py_msg2);
2965 unsigned int i;
2966 int ret;
2968 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2969 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2970 if (ret != 0) {
2971 return SIGN(ret);
2975 ret = msg1->num_elements - msg2->num_elements;
2976 if (ret != 0) {
2977 return SIGN(ret);
2980 for (i = 0; i < msg1->num_elements; i++) {
2981 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2982 &msg2->elements[i]);
2983 if (ret != 0) {
2984 return SIGN(ret);
2987 ret = ldb_msg_element_compare(&msg1->elements[i],
2988 &msg2->elements[i]);
2989 if (ret != 0) {
2990 return SIGN(ret);
2994 return 0;
2997 static PyTypeObject PyLdbMessage = {
2998 .tp_name = "ldb.Message",
2999 .tp_methods = py_ldb_msg_methods,
3000 .tp_getset = py_ldb_msg_getset,
3001 .tp_as_mapping = &py_ldb_msg_mapping,
3002 .tp_basicsize = sizeof(PyLdbMessageObject),
3003 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3004 .tp_new = py_ldb_msg_new,
3005 .tp_repr = (reprfunc)py_ldb_msg_repr,
3006 .tp_flags = Py_TPFLAGS_DEFAULT,
3007 .tp_iter = (getiterfunc)py_ldb_msg_iter,
3008 .tp_compare = (cmpfunc)py_ldb_msg_compare,
3009 .tp_doc = "A LDB Message",
3012 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3014 PyLdbTreeObject *ret;
3016 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3017 if (ret == NULL) {
3018 PyErr_NoMemory();
3019 return NULL;
3022 ret->mem_ctx = talloc_new(NULL);
3023 ret->tree = talloc_reference(ret->mem_ctx, tree);
3024 return (PyObject *)ret;
3027 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3029 talloc_free(self->mem_ctx);
3030 PyObject_Del(self);
3033 static PyTypeObject PyLdbTree = {
3034 .tp_name = "ldb.Tree",
3035 .tp_basicsize = sizeof(PyLdbTreeObject),
3036 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3037 .tp_flags = Py_TPFLAGS_DEFAULT,
3038 .tp_doc = "A search tree",
3041 /* Ldb_module */
3042 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3044 PyObject *py_ldb = (PyObject *)mod->private_data;
3045 PyObject *py_result, *py_base, *py_attrs, *py_tree;
3047 py_base = pyldb_Dn_FromDn(req->op.search.base);
3049 if (py_base == NULL)
3050 return LDB_ERR_OPERATIONS_ERROR;
3052 py_tree = PyLdbTree_FromTree(req->op.search.tree);
3054 if (py_tree == NULL)
3055 return LDB_ERR_OPERATIONS_ERROR;
3057 if (req->op.search.attrs == NULL) {
3058 py_attrs = Py_None;
3059 } else {
3060 int i, len;
3061 for (len = 0; req->op.search.attrs[len]; len++);
3062 py_attrs = PyList_New(len);
3063 for (i = 0; i < len; i++)
3064 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
3067 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3068 discard_const_p(char, "OiOO"),
3069 py_base, req->op.search.scope, py_tree, py_attrs);
3071 Py_DECREF(py_attrs);
3072 Py_DECREF(py_tree);
3073 Py_DECREF(py_base);
3075 if (py_result == NULL) {
3076 return LDB_ERR_PYTHON_EXCEPTION;
3079 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3080 if (req->op.search.res == NULL) {
3081 return LDB_ERR_PYTHON_EXCEPTION;
3084 Py_DECREF(py_result);
3086 return LDB_SUCCESS;
3089 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3091 PyObject *py_ldb = (PyObject *)mod->private_data;
3092 PyObject *py_result, *py_msg;
3094 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3096 if (py_msg == NULL) {
3097 return LDB_ERR_OPERATIONS_ERROR;
3100 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3101 discard_const_p(char, "O"),
3102 py_msg);
3104 Py_DECREF(py_msg);
3106 if (py_result == NULL) {
3107 return LDB_ERR_PYTHON_EXCEPTION;
3110 Py_DECREF(py_result);
3112 return LDB_SUCCESS;
3115 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3117 PyObject *py_ldb = (PyObject *)mod->private_data;
3118 PyObject *py_result, *py_msg;
3120 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3122 if (py_msg == NULL) {
3123 return LDB_ERR_OPERATIONS_ERROR;
3126 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3127 discard_const_p(char, "O"),
3128 py_msg);
3130 Py_DECREF(py_msg);
3132 if (py_result == NULL) {
3133 return LDB_ERR_PYTHON_EXCEPTION;
3136 Py_DECREF(py_result);
3138 return LDB_SUCCESS;
3141 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3143 PyObject *py_ldb = (PyObject *)mod->private_data;
3144 PyObject *py_result, *py_dn;
3146 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3148 if (py_dn == NULL)
3149 return LDB_ERR_OPERATIONS_ERROR;
3151 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3152 discard_const_p(char, "O"),
3153 py_dn);
3155 if (py_result == NULL) {
3156 return LDB_ERR_PYTHON_EXCEPTION;
3159 Py_DECREF(py_result);
3161 return LDB_SUCCESS;
3164 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3166 PyObject *py_ldb = (PyObject *)mod->private_data;
3167 PyObject *py_result, *py_olddn, *py_newdn;
3169 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3171 if (py_olddn == NULL)
3172 return LDB_ERR_OPERATIONS_ERROR;
3174 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3176 if (py_newdn == NULL)
3177 return LDB_ERR_OPERATIONS_ERROR;
3179 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3180 discard_const_p(char, "OO"),
3181 py_olddn, py_newdn);
3183 Py_DECREF(py_olddn);
3184 Py_DECREF(py_newdn);
3186 if (py_result == NULL) {
3187 return LDB_ERR_PYTHON_EXCEPTION;
3190 Py_DECREF(py_result);
3192 return LDB_SUCCESS;
3195 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3197 PyObject *py_ldb = (PyObject *)mod->private_data;
3198 PyObject *py_result;
3200 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3201 discard_const_p(char, ""));
3203 Py_XDECREF(py_result);
3205 return LDB_ERR_OPERATIONS_ERROR;
3208 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3210 PyObject *py_ldb = (PyObject *)mod->private_data;
3211 PyObject *py_result;
3213 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3214 discard_const_p(char, ""));
3216 Py_XDECREF(py_result);
3218 return LDB_ERR_OPERATIONS_ERROR;
3221 static int py_module_start_transaction(struct ldb_module *mod)
3223 PyObject *py_ldb = (PyObject *)mod->private_data;
3224 PyObject *py_result;
3226 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3227 discard_const_p(char, ""));
3229 if (py_result == NULL) {
3230 return LDB_ERR_PYTHON_EXCEPTION;
3233 Py_DECREF(py_result);
3235 return LDB_SUCCESS;
3238 static int py_module_end_transaction(struct ldb_module *mod)
3240 PyObject *py_ldb = (PyObject *)mod->private_data;
3241 PyObject *py_result;
3243 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3244 discard_const_p(char, ""));
3246 if (py_result == NULL) {
3247 return LDB_ERR_PYTHON_EXCEPTION;
3250 Py_DECREF(py_result);
3252 return LDB_SUCCESS;
3255 static int py_module_del_transaction(struct ldb_module *mod)
3257 PyObject *py_ldb = (PyObject *)mod->private_data;
3258 PyObject *py_result;
3260 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3261 discard_const_p(char, ""));
3263 if (py_result == NULL) {
3264 return LDB_ERR_PYTHON_EXCEPTION;
3267 Py_DECREF(py_result);
3269 return LDB_SUCCESS;
3272 static int py_module_destructor(struct ldb_module *mod)
3274 Py_DECREF((PyObject *)mod->private_data);
3275 return 0;
3278 static int py_module_init(struct ldb_module *mod)
3280 PyObject *py_class = (PyObject *)mod->ops->private_data;
3281 PyObject *py_result, *py_next, *py_ldb;
3283 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3285 if (py_ldb == NULL)
3286 return LDB_ERR_OPERATIONS_ERROR;
3288 py_next = PyLdbModule_FromModule(mod->next);
3290 if (py_next == NULL)
3291 return LDB_ERR_OPERATIONS_ERROR;
3293 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3294 py_ldb, py_next);
3296 if (py_result == NULL) {
3297 return LDB_ERR_PYTHON_EXCEPTION;
3300 mod->private_data = py_result;
3302 talloc_set_destructor(mod, py_module_destructor);
3304 return ldb_next_init(mod);
3307 static PyObject *py_register_module(PyObject *module, PyObject *args)
3309 int ret;
3310 struct ldb_module_ops *ops;
3311 PyObject *input;
3313 if (!PyArg_ParseTuple(args, "O", &input))
3314 return NULL;
3316 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3317 if (ops == NULL) {
3318 PyErr_NoMemory();
3319 return NULL;
3322 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3324 Py_INCREF(input);
3325 ops->private_data = input;
3326 ops->init_context = py_module_init;
3327 ops->search = py_module_search;
3328 ops->add = py_module_add;
3329 ops->modify = py_module_modify;
3330 ops->del = py_module_del;
3331 ops->rename = py_module_rename;
3332 ops->request = py_module_request;
3333 ops->extended = py_module_extended;
3334 ops->start_transaction = py_module_start_transaction;
3335 ops->end_transaction = py_module_end_transaction;
3336 ops->del_transaction = py_module_del_transaction;
3338 ret = ldb_register_module(ops);
3340 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3342 Py_RETURN_NONE;
3345 static PyObject *py_timestring(PyObject *module, PyObject *args)
3347 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3348 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3349 long int t_val;
3350 char *tresult;
3351 PyObject *ret;
3352 if (!PyArg_ParseTuple(args, "l", &t_val))
3353 return NULL;
3354 tresult = ldb_timestring(NULL, (time_t) t_val);
3355 ret = PyString_FromString(tresult);
3356 talloc_free(tresult);
3357 return ret;
3360 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3362 char *str;
3363 if (!PyArg_ParseTuple(args, "s", &str))
3364 return NULL;
3366 return PyInt_FromLong(ldb_string_to_time(str));
3369 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3371 char *name;
3372 if (!PyArg_ParseTuple(args, "s", &name))
3373 return NULL;
3374 return PyBool_FromLong(ldb_valid_attr_name(name));
3378 encode a string using RFC2254 rules
3380 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3382 char *str, *encoded;
3383 int size = 0;
3384 struct ldb_val val;
3385 PyObject *ret;
3387 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3388 return NULL;
3389 val.data = (uint8_t *)str;
3390 val.length = size;
3392 encoded = ldb_binary_encode(NULL, val);
3393 if (encoded == NULL) {
3394 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3395 return NULL;
3397 ret = PyString_FromString(encoded);
3398 talloc_free(encoded);
3399 return ret;
3403 decode a string using RFC2254 rules
3405 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3407 char *str;
3408 struct ldb_val val;
3409 PyObject *ret;
3411 if (!PyArg_ParseTuple(args, "s", &str))
3412 return NULL;
3414 val = ldb_binary_decode(NULL, str);
3415 if (val.data == NULL) {
3416 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3417 return NULL;
3419 ret = Py_BuildValue("s#", val.data, val.length);
3420 talloc_free(val.data);
3421 return ret;
3424 static PyMethodDef py_ldb_global_methods[] = {
3425 { "register_module", py_register_module, METH_VARARGS,
3426 "S.register_module(module) -> None\n\n"
3427 "Register a LDB module."},
3428 { "timestring", py_timestring, METH_VARARGS,
3429 "S.timestring(int) -> string\n\n"
3430 "Generate a LDAP time string from a UNIX timestamp" },
3431 { "string_to_time", py_string_to_time, METH_VARARGS,
3432 "S.string_to_time(string) -> int\n\n"
3433 "Parse a LDAP time string into a UNIX timestamp." },
3434 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3435 "S.valid_attr_name(name) -> bool\n\nn"
3436 "Check whether the supplied name is a valid attribute name." },
3437 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3438 "S.open() -> Ldb\n\n"
3439 "Open a new LDB context." },
3440 { "binary_encode", py_binary_encode, METH_VARARGS,
3441 "S.binary_encode(string) -> string\n\n"
3442 "Perform a RFC2254 binary encoding on a string" },
3443 { "binary_decode", py_binary_decode, METH_VARARGS,
3444 "S.binary_decode(string) -> string\n\n"
3445 "Perform a RFC2254 binary decode on a string" },
3446 { NULL }
3449 void initldb(void)
3451 PyObject *m;
3453 if (PyType_Ready(&PyLdbDn) < 0)
3454 return;
3456 if (PyType_Ready(&PyLdbMessage) < 0)
3457 return;
3459 if (PyType_Ready(&PyLdbMessageElement) < 0)
3460 return;
3462 if (PyType_Ready(&PyLdb) < 0)
3463 return;
3465 if (PyType_Ready(&PyLdbModule) < 0)
3466 return;
3468 if (PyType_Ready(&PyLdbTree) < 0)
3469 return;
3471 if (PyType_Ready(&PyLdbResult) < 0)
3472 return;
3474 if (PyType_Ready(&PyLdbControl) < 0)
3475 return;
3477 m = Py_InitModule3("ldb", py_ldb_global_methods,
3478 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3479 if (m == NULL)
3480 return;
3482 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3483 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3484 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3485 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3486 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3487 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3488 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3490 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3491 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3492 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3493 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3495 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3496 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3497 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3499 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3500 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3501 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3502 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3503 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3504 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3505 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3506 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3507 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3508 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3509 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3510 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3511 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3512 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3513 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3514 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3515 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3516 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3517 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3518 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3519 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3520 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3521 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3522 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3523 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3524 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3525 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3526 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3527 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3528 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3529 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3530 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3531 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3532 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3533 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3534 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3535 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3536 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3537 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3539 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3540 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3541 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3542 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3544 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3546 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3547 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3549 Py_INCREF(&PyLdb);
3550 Py_INCREF(&PyLdbDn);
3551 Py_INCREF(&PyLdbModule);
3552 Py_INCREF(&PyLdbMessage);
3553 Py_INCREF(&PyLdbMessageElement);
3554 Py_INCREF(&PyLdbTree);
3555 Py_INCREF(&PyLdbResult);
3556 Py_INCREF(&PyLdbControl);
3558 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3559 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3560 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3561 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3562 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3563 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3564 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3566 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3568 #define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3570 ADD_LDB_STRING(SYNTAX_DN);
3571 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3572 ADD_LDB_STRING(SYNTAX_INTEGER);
3573 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3574 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3575 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3576 ADD_LDB_STRING(OID_COMPARATOR_AND);
3577 ADD_LDB_STRING(OID_COMPARATOR_OR);