loadparm: rename variable for "hosts allow" from hostsallow to hosts_allow
[Samba/wip.git] / lib / ldb / pyldb.c
blob4360b31776e0424b34676677ea75467bc9b2c814
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(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 PyMethodDef py_ldb_dn_methods[] = {
556 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
557 "S.validate() -> bool\n"
558 "Validate DN is correct." },
559 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
560 "S.is_valid() -> bool\n" },
561 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
562 "S.is_special() -> bool\n"
563 "Check whether this is a special LDB DN." },
564 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
565 "Check whether this is a null DN." },
566 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
567 NULL },
568 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
569 NULL },
570 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
571 "S.canonical_str() -> string\n"
572 "Canonical version of this DN (like a posix path)." },
573 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
574 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
575 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
576 "S.canonical_ex_str() -> string\n"
577 "Canonical version of this DN (like a posix path, with terminating newline)." },
578 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
579 "S.extended_str(mode=1) -> string\n"
580 "Extended version of this DN" },
581 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
582 "S.parent() -> dn\n"
583 "Get the parent for this DN." },
584 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
585 "S.add_child(dn) -> None\n"
586 "Add a child DN to this DN." },
587 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
588 "S.add_base(dn) -> None\n"
589 "Add a base DN to this DN." },
590 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
591 "S.remove_base_components(int) -> bool\n"
592 "Remove a number of DN components from the base of this DN." },
593 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
594 "S.check_special(name) -> bool\n\n"
595 "Check if name is a special DN name"},
596 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
597 "S.get_extended_component(name) -> string\n\n"
598 "returns a DN extended component as a binary string"},
599 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
600 "S.set_extended_component(name, value) -> string\n\n"
601 "set a DN extended component as a binary string"},
602 { NULL }
605 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
607 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
611 copy a DN as a python object
613 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
615 PyLdbDnObject *py_ret;
617 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
618 if (py_ret == NULL) {
619 PyErr_NoMemory();
620 return NULL;
622 py_ret->mem_ctx = talloc_new(NULL);
623 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
624 return (PyObject *)py_ret;
627 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
629 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
630 *other;
631 PyLdbDnObject *py_ret;
633 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
634 return NULL;
636 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
637 if (py_ret == NULL) {
638 PyErr_NoMemory();
639 return NULL;
641 py_ret->mem_ctx = talloc_new(NULL);
642 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
643 ldb_dn_add_base(py_ret->dn, other);
644 return (PyObject *)py_ret;
647 static PySequenceMethods py_ldb_dn_seq = {
648 .sq_length = (lenfunc)py_ldb_dn_len,
649 .sq_concat = (binaryfunc)py_ldb_dn_concat,
652 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
654 struct ldb_dn *ret;
655 char *str;
656 PyObject *py_ldb;
657 struct ldb_context *ldb_ctx;
658 TALLOC_CTX *mem_ctx;
659 PyLdbDnObject *py_ret;
660 const char * const kwnames[] = { "ldb", "dn", NULL };
662 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
663 discard_const_p(char *, kwnames),
664 &py_ldb, &str))
665 return NULL;
667 if (!PyLdb_Check(py_ldb)) {
668 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
669 return NULL;
672 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
674 mem_ctx = talloc_new(NULL);
675 if (mem_ctx == NULL) {
676 PyErr_NoMemory();
677 return NULL;
680 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
681 if (!ldb_dn_validate(ret)) {
682 talloc_free(mem_ctx);
683 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
684 return NULL;
687 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
688 if (ret == NULL) {
689 talloc_free(mem_ctx);
690 PyErr_NoMemory();
691 return NULL;
693 py_ret->mem_ctx = mem_ctx;
694 py_ret->dn = ret;
695 return (PyObject *)py_ret;
698 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
700 talloc_free(self->mem_ctx);
701 PyObject_Del(self);
704 static PyTypeObject PyLdbDn = {
705 .tp_name = "ldb.Dn",
706 .tp_methods = py_ldb_dn_methods,
707 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
708 .tp_repr = (reprfunc)py_ldb_dn_repr,
709 .tp_compare = (cmpfunc)py_ldb_dn_compare,
710 .tp_as_sequence = &py_ldb_dn_seq,
711 .tp_doc = "A LDB distinguished name.",
712 .tp_new = py_ldb_dn_new,
713 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
714 .tp_basicsize = sizeof(PyLdbDnObject),
715 .tp_flags = Py_TPFLAGS_DEFAULT,
718 /* Debug */
719 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
720 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
722 PyObject *fn = (PyObject *)context;
723 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
726 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
728 PyObject *cb;
729 struct ldb_context *ldb_ctx;
731 if (!PyArg_ParseTuple(args, "O", &cb))
732 return NULL;
734 Py_INCREF(cb);
735 /* FIXME: Where do we DECREF cb ? */
736 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
737 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
738 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
739 ldb_ctx);
741 Py_RETURN_NONE;
744 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
746 unsigned int perms;
747 if (!PyArg_ParseTuple(args, "I", &perms))
748 return NULL;
750 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
752 Py_RETURN_NONE;
755 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
757 char *modules_dir;
758 if (!PyArg_ParseTuple(args, "s", &modules_dir))
759 return NULL;
761 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
763 Py_RETURN_NONE;
766 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
768 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
769 int ldb_err;
770 ldb_err = ldb_transaction_start(ldb_ctx);
771 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
772 Py_RETURN_NONE;
775 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
777 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
778 int ldb_err;
779 ldb_err = ldb_transaction_commit(ldb_ctx);
780 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
781 Py_RETURN_NONE;
784 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
786 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
787 int ldb_err;
788 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
789 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
790 Py_RETURN_NONE;
793 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
795 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
796 int ldb_err;
797 ldb_err = ldb_transaction_cancel(ldb_ctx);
798 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
799 Py_RETURN_NONE;
802 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
804 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
805 int ldb_err;
806 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
807 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
808 Py_RETURN_NONE;
811 static PyObject *py_ldb_repr(PyLdbObject *self)
813 return PyString_FromFormat("<ldb connection>");
816 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
818 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
819 if (dn == NULL)
820 Py_RETURN_NONE;
821 return py_ldb_dn_copy(dn);
825 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
827 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
828 if (dn == NULL)
829 Py_RETURN_NONE;
830 return py_ldb_dn_copy(dn);
833 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
835 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
836 if (dn == NULL)
837 Py_RETURN_NONE;
838 return py_ldb_dn_copy(dn);
841 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
843 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
844 if (dn == NULL)
845 Py_RETURN_NONE;
846 return py_ldb_dn_copy(dn);
849 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
850 const char *paramname)
852 const char **ret;
853 Py_ssize_t i;
854 if (!PyList_Check(list)) {
855 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
856 return NULL;
858 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
859 if (ret == NULL) {
860 PyErr_NoMemory();
861 return NULL;
864 for (i = 0; i < PyList_Size(list); i++) {
865 PyObject *item = PyList_GetItem(list, i);
866 if (!PyString_Check(item)) {
867 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
868 return NULL;
870 ret[i] = talloc_strndup(ret, PyString_AsString(item),
871 PyString_Size(item));
873 ret[i] = NULL;
874 return ret;
877 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
879 const char * const kwnames[] = { "url", "flags", "options", NULL };
880 char *url = NULL;
881 PyObject *py_options = Py_None;
882 const char **options;
883 unsigned int flags = 0;
884 int ret;
885 struct ldb_context *ldb;
887 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
888 discard_const_p(char *, kwnames),
889 &url, &flags, &py_options))
890 return -1;
892 ldb = pyldb_Ldb_AsLdbContext(self);
894 if (py_options == Py_None) {
895 options = NULL;
896 } else {
897 options = PyList_AsStringList(ldb, py_options, "options");
898 if (options == NULL)
899 return -1;
902 if (url != NULL) {
903 ret = ldb_connect(ldb, url, flags, options);
904 if (ret != LDB_SUCCESS) {
905 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
906 return -1;
910 talloc_free(options);
911 return 0;
914 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
916 PyLdbObject *ret;
917 struct ldb_context *ldb;
918 ret = (PyLdbObject *)type->tp_alloc(type, 0);
919 if (ret == NULL) {
920 PyErr_NoMemory();
921 return NULL;
923 ret->mem_ctx = talloc_new(NULL);
924 ldb = ldb_init(ret->mem_ctx, NULL);
926 if (ldb == NULL) {
927 PyErr_NoMemory();
928 return NULL;
931 ret->ldb_ctx = ldb;
932 return (PyObject *)ret;
935 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
937 char *url;
938 unsigned int flags = 0;
939 PyObject *py_options = Py_None;
940 int ret;
941 const char **options;
942 const char * const kwnames[] = { "url", "flags", "options", NULL };
943 struct ldb_context *ldb_ctx;
945 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
946 discard_const_p(char *, kwnames),
947 &url, &flags, &py_options))
948 return NULL;
950 if (py_options == Py_None) {
951 options = NULL;
952 } else {
953 options = PyList_AsStringList(NULL, py_options, "options");
954 if (options == NULL)
955 return NULL;
958 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
959 ret = ldb_connect(ldb_ctx, url, flags, options);
960 talloc_free(options);
962 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
964 Py_RETURN_NONE;
967 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
969 PyObject *py_msg;
970 PyObject *py_controls = Py_None;
971 struct ldb_context *ldb_ctx;
972 struct ldb_request *req;
973 struct ldb_control **parsed_controls;
974 struct ldb_message *msg;
975 int ret;
976 TALLOC_CTX *mem_ctx;
977 bool validate=true;
978 const char * const kwnames[] = { "message", "controls", "validate", NULL };
980 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
981 discard_const_p(char *, kwnames),
982 &py_msg, &py_controls, &validate))
983 return NULL;
985 mem_ctx = talloc_new(NULL);
986 if (mem_ctx == NULL) {
987 PyErr_NoMemory();
988 return NULL;
990 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
992 if (py_controls == Py_None) {
993 parsed_controls = NULL;
994 } else {
995 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
996 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
997 talloc_free(controls);
1000 if (!PyLdbMessage_Check(py_msg)) {
1001 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1002 talloc_free(mem_ctx);
1003 return NULL;
1005 msg = pyldb_Message_AsMessage(py_msg);
1007 if (validate) {
1008 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1009 if (ret != LDB_SUCCESS) {
1010 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1011 talloc_free(mem_ctx);
1012 return NULL;
1016 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1017 NULL, ldb_op_default_callback, NULL);
1018 if (ret != LDB_SUCCESS) {
1019 PyErr_SetString(PyExc_TypeError, "failed to build request");
1020 talloc_free(mem_ctx);
1021 return NULL;
1024 /* do request and autostart a transaction */
1025 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1027 ret = ldb_transaction_start(ldb_ctx);
1028 if (ret != LDB_SUCCESS) {
1029 talloc_free(mem_ctx);
1030 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1031 return NULL;
1034 ret = ldb_request(ldb_ctx, req);
1035 if (ret == LDB_SUCCESS) {
1036 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1039 if (ret == LDB_SUCCESS) {
1040 ret = ldb_transaction_commit(ldb_ctx);
1041 } else {
1042 ldb_transaction_cancel(ldb_ctx);
1045 talloc_free(mem_ctx);
1046 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1048 Py_RETURN_NONE;
1053 * Obtain a ldb message from a Python Dictionary object.
1055 * @param mem_ctx Memory context
1056 * @param py_obj Python Dictionary object
1057 * @param ldb_ctx LDB context
1058 * @param mod_flags Flags to be set on every message element
1059 * @return ldb_message on success or NULL on failure
1061 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1062 PyObject *py_obj,
1063 struct ldb_context *ldb_ctx,
1064 unsigned int mod_flags)
1066 struct ldb_message *msg;
1067 unsigned int msg_pos = 0;
1068 Py_ssize_t dict_pos = 0;
1069 PyObject *key, *value;
1070 struct ldb_message_element *msg_el;
1071 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1073 msg = ldb_msg_new(mem_ctx);
1074 if (msg == NULL) {
1075 PyErr_NoMemory();
1076 return NULL;
1078 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1080 if (dn_value) {
1081 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1082 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1083 return NULL;
1085 if (msg->dn == NULL) {
1086 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1087 return NULL;
1089 } else {
1090 PyErr_SetString(PyExc_TypeError, "no dn set");
1091 return NULL;
1094 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1095 char *key_str = PyString_AsString(key);
1096 if (ldb_attr_cmp(key_str, "dn") != 0) {
1097 msg_el = PyObject_AsMessageElement(msg->elements, value,
1098 mod_flags, key_str);
1099 if (msg_el == NULL) {
1100 PyErr_SetString(PyExc_TypeError, "unable to import element");
1101 return NULL;
1103 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1104 msg_pos++;
1108 msg->num_elements = msg_pos;
1110 return msg;
1113 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1115 PyObject *py_obj;
1116 int ret;
1117 struct ldb_context *ldb_ctx;
1118 struct ldb_request *req;
1119 struct ldb_message *msg = NULL;
1120 PyObject *py_controls = Py_None;
1121 TALLOC_CTX *mem_ctx;
1122 struct ldb_control **parsed_controls;
1123 const char * const kwnames[] = { "message", "controls", NULL };
1125 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1126 discard_const_p(char *, kwnames),
1127 &py_obj, &py_controls))
1128 return NULL;
1130 mem_ctx = talloc_new(NULL);
1131 if (mem_ctx == NULL) {
1132 PyErr_NoMemory();
1133 return NULL;
1135 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1137 if (py_controls == Py_None) {
1138 parsed_controls = NULL;
1139 } else {
1140 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1141 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1142 talloc_free(controls);
1145 if (PyLdbMessage_Check(py_obj)) {
1146 msg = pyldb_Message_AsMessage(py_obj);
1147 } else if (PyDict_Check(py_obj)) {
1148 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1149 } else {
1150 PyErr_SetString(PyExc_TypeError,
1151 "Dictionary or LdbMessage object expected!");
1154 if (!msg) {
1155 /* we should have a PyErr already set */
1156 talloc_free(mem_ctx);
1157 return NULL;
1160 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1161 if (ret != LDB_SUCCESS) {
1162 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1163 talloc_free(mem_ctx);
1164 return NULL;
1167 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1168 NULL, ldb_op_default_callback, NULL);
1169 if (ret != LDB_SUCCESS) {
1170 PyErr_SetString(PyExc_TypeError, "failed to build request");
1171 talloc_free(mem_ctx);
1172 return NULL;
1175 /* do request and autostart a transaction */
1176 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1178 ret = ldb_transaction_start(ldb_ctx);
1179 if (ret != LDB_SUCCESS) {
1180 talloc_free(mem_ctx);
1181 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1182 return NULL;
1185 ret = ldb_request(ldb_ctx, req);
1186 if (ret == LDB_SUCCESS) {
1187 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1190 if (ret == LDB_SUCCESS) {
1191 ret = ldb_transaction_commit(ldb_ctx);
1192 } else {
1193 ldb_transaction_cancel(ldb_ctx);
1196 talloc_free(mem_ctx);
1197 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1199 Py_RETURN_NONE;
1202 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1204 PyObject *py_dn;
1205 struct ldb_dn *dn;
1206 int ret;
1207 struct ldb_context *ldb_ctx;
1208 struct ldb_request *req;
1209 PyObject *py_controls = Py_None;
1210 TALLOC_CTX *mem_ctx;
1211 struct ldb_control **parsed_controls;
1212 const char * const kwnames[] = { "dn", "controls", NULL };
1214 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1215 discard_const_p(char *, kwnames),
1216 &py_dn, &py_controls))
1217 return NULL;
1219 mem_ctx = talloc_new(NULL);
1220 if (mem_ctx == NULL) {
1221 PyErr_NoMemory();
1222 return NULL;
1224 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1226 if (py_controls == Py_None) {
1227 parsed_controls = NULL;
1228 } else {
1229 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1230 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1231 talloc_free(controls);
1234 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1235 talloc_free(mem_ctx);
1236 return NULL;
1239 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1240 NULL, ldb_op_default_callback, NULL);
1241 if (ret != LDB_SUCCESS) {
1242 PyErr_SetString(PyExc_TypeError, "failed to build request");
1243 talloc_free(mem_ctx);
1244 return NULL;
1247 /* do request and autostart a transaction */
1248 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1250 ret = ldb_transaction_start(ldb_ctx);
1251 if (ret != LDB_SUCCESS) {
1252 talloc_free(mem_ctx);
1253 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1254 return NULL;
1257 ret = ldb_request(ldb_ctx, req);
1258 if (ret == LDB_SUCCESS) {
1259 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1262 if (ret == LDB_SUCCESS) {
1263 ret = ldb_transaction_commit(ldb_ctx);
1264 } else {
1265 ldb_transaction_cancel(ldb_ctx);
1268 talloc_free(mem_ctx);
1269 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1271 Py_RETURN_NONE;
1274 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1276 PyObject *py_dn1, *py_dn2;
1277 struct ldb_dn *dn1, *dn2;
1278 int ret;
1279 TALLOC_CTX *mem_ctx;
1280 PyObject *py_controls = Py_None;
1281 struct ldb_control **parsed_controls;
1282 struct ldb_context *ldb_ctx;
1283 struct ldb_request *req;
1284 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1286 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1288 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1289 discard_const_p(char *, kwnames),
1290 &py_dn1, &py_dn2, &py_controls))
1291 return NULL;
1294 mem_ctx = talloc_new(NULL);
1295 if (mem_ctx == NULL) {
1296 PyErr_NoMemory();
1297 return NULL;
1300 if (py_controls == Py_None) {
1301 parsed_controls = NULL;
1302 } else {
1303 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1304 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1305 talloc_free(controls);
1309 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1310 talloc_free(mem_ctx);
1311 return NULL;
1314 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1315 talloc_free(mem_ctx);
1316 return NULL;
1319 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1320 NULL, ldb_op_default_callback, NULL);
1321 if (ret != LDB_SUCCESS) {
1322 PyErr_SetString(PyExc_TypeError, "failed to build request");
1323 talloc_free(mem_ctx);
1324 return NULL;
1327 /* do request and autostart a transaction */
1328 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1330 ret = ldb_transaction_start(ldb_ctx);
1331 if (ret != LDB_SUCCESS) {
1332 talloc_free(mem_ctx);
1333 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1334 return NULL;
1337 ret = ldb_request(ldb_ctx, req);
1338 if (ret == LDB_SUCCESS) {
1339 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1342 if (ret == LDB_SUCCESS) {
1343 ret = ldb_transaction_commit(ldb_ctx);
1344 } else {
1345 ldb_transaction_cancel(ldb_ctx);
1348 talloc_free(mem_ctx);
1349 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1351 Py_RETURN_NONE;
1354 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1356 char *name;
1357 if (!PyArg_ParseTuple(args, "s", &name))
1358 return NULL;
1360 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1362 Py_RETURN_NONE;
1365 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1367 char *attribute, *syntax;
1368 unsigned int flags;
1369 int ret;
1370 struct ldb_context *ldb_ctx;
1372 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1373 return NULL;
1375 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1376 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1378 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1380 Py_RETURN_NONE;
1383 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1385 if (ldif == NULL) {
1386 Py_RETURN_NONE;
1387 } else {
1388 /* We don't want this attached to the 'ldb' any more */
1389 return Py_BuildValue(discard_const_p(char, "(iO)"),
1390 ldif->changetype,
1391 PyLdbMessage_FromMessage(ldif->msg));
1396 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1398 int changetype;
1399 PyObject *py_msg;
1400 struct ldb_ldif ldif;
1401 PyObject *ret;
1402 char *string;
1403 TALLOC_CTX *mem_ctx;
1405 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1406 return NULL;
1408 if (!PyLdbMessage_Check(py_msg)) {
1409 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1410 return NULL;
1413 ldif.msg = pyldb_Message_AsMessage(py_msg);
1414 ldif.changetype = changetype;
1416 mem_ctx = talloc_new(NULL);
1418 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1419 if (!string) {
1420 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1421 return NULL;
1424 ret = PyString_FromString(string);
1426 talloc_free(mem_ctx);
1428 return ret;
1431 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1433 PyObject *list;
1434 struct ldb_ldif *ldif;
1435 const char *s;
1437 TALLOC_CTX *mem_ctx;
1439 if (!PyArg_ParseTuple(args, "s", &s))
1440 return NULL;
1442 mem_ctx = talloc_new(NULL);
1443 if (!mem_ctx) {
1444 Py_RETURN_NONE;
1447 list = PyList_New(0);
1448 while (s && *s != '\0') {
1449 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1450 talloc_steal(mem_ctx, ldif);
1451 if (ldif) {
1452 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1453 } else {
1454 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1455 talloc_free(mem_ctx);
1456 return NULL;
1459 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1460 return PyObject_GetIter(list);
1463 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1465 int ldb_ret;
1466 PyObject *py_msg_old;
1467 PyObject *py_msg_new;
1468 struct ldb_message *diff;
1469 struct ldb_context *ldb;
1470 PyObject *py_ret;
1472 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1473 return NULL;
1475 if (!PyLdbMessage_Check(py_msg_old)) {
1476 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1477 return NULL;
1480 if (!PyLdbMessage_Check(py_msg_new)) {
1481 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1482 return NULL;
1485 ldb = pyldb_Ldb_AsLdbContext(self);
1486 ldb_ret = ldb_msg_difference(ldb, ldb,
1487 pyldb_Message_AsMessage(py_msg_old),
1488 pyldb_Message_AsMessage(py_msg_new),
1489 &diff);
1490 if (ldb_ret != LDB_SUCCESS) {
1491 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1492 return NULL;
1495 py_ret = PyLdbMessage_FromMessage(diff);
1497 talloc_unlink(ldb, diff);
1499 return py_ret;
1502 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1504 const struct ldb_schema_attribute *a;
1505 struct ldb_val old_val;
1506 struct ldb_val new_val;
1507 TALLOC_CTX *mem_ctx;
1508 PyObject *ret;
1509 char *element_name;
1510 PyObject *val;
1512 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1513 return NULL;
1515 mem_ctx = talloc_new(NULL);
1517 old_val.data = (uint8_t *)PyString_AsString(val);
1518 old_val.length = PyString_Size(val);
1520 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1522 if (a == NULL) {
1523 Py_RETURN_NONE;
1526 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1527 talloc_free(mem_ctx);
1528 Py_RETURN_NONE;
1531 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1533 talloc_free(mem_ctx);
1535 return ret;
1538 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1540 PyObject *py_base = Py_None;
1541 int scope = LDB_SCOPE_DEFAULT;
1542 char *expr = NULL;
1543 PyObject *py_attrs = Py_None;
1544 PyObject *py_controls = Py_None;
1545 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1546 int ret;
1547 struct ldb_result *res;
1548 struct ldb_request *req;
1549 const char **attrs;
1550 struct ldb_context *ldb_ctx;
1551 struct ldb_control **parsed_controls;
1552 struct ldb_dn *base;
1553 PyObject *py_ret;
1554 TALLOC_CTX *mem_ctx;
1556 /* type "int" rather than "enum" for "scope" is intentional */
1557 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1558 discard_const_p(char *, kwnames),
1559 &py_base, &scope, &expr, &py_attrs, &py_controls))
1560 return NULL;
1563 mem_ctx = talloc_new(NULL);
1564 if (mem_ctx == NULL) {
1565 PyErr_NoMemory();
1566 return NULL;
1568 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1570 if (py_attrs == Py_None) {
1571 attrs = NULL;
1572 } else {
1573 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1574 if (attrs == NULL) {
1575 talloc_free(mem_ctx);
1576 return NULL;
1580 if (py_base == Py_None) {
1581 base = ldb_get_default_basedn(ldb_ctx);
1582 } else {
1583 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1584 talloc_free(attrs);
1585 return NULL;
1589 if (py_controls == Py_None) {
1590 parsed_controls = NULL;
1591 } else {
1592 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1593 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1594 talloc_free(controls);
1597 res = talloc_zero(mem_ctx, struct ldb_result);
1598 if (res == NULL) {
1599 PyErr_NoMemory();
1600 talloc_free(mem_ctx);
1601 return NULL;
1604 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1605 base,
1606 scope,
1607 expr,
1608 attrs,
1609 parsed_controls,
1610 res,
1611 ldb_search_default_callback,
1612 NULL);
1614 if (ret != LDB_SUCCESS) {
1615 talloc_free(mem_ctx);
1616 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1617 return NULL;
1620 talloc_steal(req, attrs);
1622 ret = ldb_request(ldb_ctx, req);
1624 if (ret == LDB_SUCCESS) {
1625 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1628 if (ret != LDB_SUCCESS) {
1629 talloc_free(mem_ctx);
1630 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1631 return NULL;
1634 py_ret = PyLdbResult_FromResult(res);
1636 talloc_free(mem_ctx);
1638 return py_ret;
1641 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1643 char *name;
1644 void *data;
1646 if (!PyArg_ParseTuple(args, "s", &name))
1647 return NULL;
1649 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1651 if (data == NULL)
1652 Py_RETURN_NONE;
1654 /* FIXME: More interpretation */
1656 return Py_True;
1659 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1661 char *name;
1662 PyObject *data;
1664 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1665 return NULL;
1667 /* FIXME: More interpretation */
1669 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1671 Py_RETURN_NONE;
1674 static PyObject *py_ldb_modules(PyLdbObject *self)
1676 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1677 PyObject *ret = PyList_New(0);
1678 struct ldb_module *mod;
1680 for (mod = ldb->modules; mod; mod = mod->next) {
1681 PyList_Append(ret, PyLdbModule_FromModule(mod));
1684 return ret;
1687 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1689 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1690 int type, ret;
1691 uint64_t value;
1693 if (!PyArg_ParseTuple(args, "i", &type))
1694 return NULL;
1696 /* FIXME: More interpretation */
1698 ret = ldb_sequence_number(ldb, type, &value);
1700 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1702 return PyLong_FromLongLong(value);
1704 static PyMethodDef py_ldb_methods[] = {
1705 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1706 "S.set_debug(callback) -> None\n"
1707 "Set callback for LDB debug messages.\n"
1708 "The callback should accept a debug level and debug text." },
1709 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1710 "S.set_create_perms(mode) -> None\n"
1711 "Set mode to use when creating new LDB files." },
1712 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1713 "S.set_modules_dir(path) -> None\n"
1714 "Set path LDB should search for modules" },
1715 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1716 "S.transaction_start() -> None\n"
1717 "Start a new transaction." },
1718 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1719 "S.transaction_prepare_commit() -> None\n"
1720 "prepare to commit a new transaction (2-stage commit)." },
1721 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1722 "S.transaction_commit() -> None\n"
1723 "commit a new transaction." },
1724 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1725 "S.transaction_cancel() -> None\n"
1726 "cancel a new transaction." },
1727 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1728 NULL },
1729 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1730 NULL },
1731 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1732 NULL },
1733 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1734 NULL },
1735 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1736 NULL },
1737 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1738 "S.connect(url, flags=0, options=None) -> None\n"
1739 "Connect to a LDB URL." },
1740 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1741 "S.modify(message, controls=None, validate=False) -> None\n"
1742 "Modify an entry." },
1743 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1744 "S.add(message, controls=None) -> None\n"
1745 "Add an entry." },
1746 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1747 "S.delete(dn, controls=None) -> None\n"
1748 "Remove an entry." },
1749 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1750 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1751 "Rename an entry." },
1752 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1753 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1754 "Search in a database.\n"
1755 "\n"
1756 ":param base: Optional base DN to search\n"
1757 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1758 ":param expression: Optional search expression\n"
1759 ":param attrs: Attributes to return (defaults to all)\n"
1760 ":param controls: Optional list of controls\n"
1761 ":return: Iterator over Message objects\n"
1763 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1764 NULL },
1765 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1766 NULL },
1767 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1768 NULL },
1769 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1770 "S.parse_ldif(ldif) -> iter(messages)\n"
1771 "Parse a string formatted using LDIF." },
1772 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1773 "S.write_ldif(message, changetype) -> ldif\n"
1774 "Print the message as a string formatted using LDIF." },
1775 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1776 "S.msg_diff(Message) -> Message\n"
1777 "Return an LDB Message of the difference between two Message objects." },
1778 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1779 "S.get_opaque(name) -> value\n"
1780 "Get an opaque value set on this LDB connection. \n"
1781 ":note: The returned value may not be useful in Python."
1783 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1784 "S.set_opaque(name, value) -> None\n"
1785 "Set an opaque value on this LDB connection. \n"
1786 ":note: Passing incorrect values may cause crashes." },
1787 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1788 "S.modules() -> list\n"
1789 "Return the list of modules on this LDB connection " },
1790 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1791 "S.sequence_number(type) -> value\n"
1792 "Return the value of the sequence according to the requested type" },
1793 { NULL },
1796 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1798 PyLdbModuleObject *ret;
1800 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1801 if (ret == NULL) {
1802 PyErr_NoMemory();
1803 return NULL;
1805 ret->mem_ctx = talloc_new(NULL);
1806 ret->mod = talloc_reference(ret->mem_ctx, mod);
1807 return (PyObject *)ret;
1810 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1812 return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1815 static PyGetSetDef py_ldb_getset[] = {
1816 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1817 { NULL }
1820 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1822 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1823 struct ldb_dn *dn;
1824 struct ldb_result *result;
1825 unsigned int count;
1826 int ret;
1828 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1829 return -1;
1832 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1833 NULL);
1834 if (ret != LDB_SUCCESS) {
1835 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1836 return -1;
1839 count = result->count;
1841 talloc_free(result);
1843 if (count > 1) {
1844 PyErr_Format(PyExc_RuntimeError,
1845 "Searching for [%s] dn gave %u results!",
1846 ldb_dn_get_linearized(dn),
1847 count);
1848 return -1;
1851 return count;
1854 static PySequenceMethods py_ldb_seq = {
1855 .sq_contains = (objobjproc)py_ldb_contains,
1858 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1860 PyLdbObject *ret;
1862 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1863 if (ret == NULL) {
1864 PyErr_NoMemory();
1865 return NULL;
1867 ret->mem_ctx = talloc_new(NULL);
1868 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1869 return (PyObject *)ret;
1872 static void py_ldb_dealloc(PyLdbObject *self)
1874 talloc_free(self->mem_ctx);
1875 self->ob_type->tp_free(self);
1878 static PyTypeObject PyLdb = {
1879 .tp_name = "ldb.Ldb",
1880 .tp_methods = py_ldb_methods,
1881 .tp_repr = (reprfunc)py_ldb_repr,
1882 .tp_new = py_ldb_new,
1883 .tp_init = (initproc)py_ldb_init,
1884 .tp_dealloc = (destructor)py_ldb_dealloc,
1885 .tp_getset = py_ldb_getset,
1886 .tp_getattro = PyObject_GenericGetAttr,
1887 .tp_basicsize = sizeof(PyLdbObject),
1888 .tp_doc = "Connection to a LDB database.",
1889 .tp_as_sequence = &py_ldb_seq,
1890 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1893 static void py_ldb_result_dealloc(PyLdbResultObject *self)
1895 talloc_free(self->mem_ctx);
1896 Py_DECREF(self->msgs);
1897 Py_DECREF(self->referals);
1898 Py_DECREF(self->controls);
1899 self->ob_type->tp_free(self);
1902 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
1904 Py_INCREF(self->msgs);
1905 return self->msgs;
1908 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
1910 Py_INCREF(self->controls);
1911 return self->controls;
1914 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
1916 Py_INCREF(self->referals);
1917 return self->referals;
1920 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
1922 Py_ssize_t size;
1923 if (self->msgs == NULL) {
1924 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
1925 return NULL;
1927 size = PyList_Size(self->msgs);
1928 return PyInt_FromLong(size);
1931 static PyGetSetDef py_ldb_result_getset[] = {
1932 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
1933 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
1934 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
1935 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
1936 { NULL }
1939 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
1941 return PyObject_GetIter(self->msgs);
1944 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
1946 return PySequence_Size(self->msgs);
1949 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
1951 return PySequence_GetItem(self->msgs, idx);
1954 static PySequenceMethods py_ldb_result_seq = {
1955 .sq_length = (lenfunc)py_ldb_result_len,
1956 .sq_item = (ssizeargfunc)py_ldb_result_find,
1959 static PyObject *py_ldb_result_repr(PyLdbObject *self)
1961 return PyString_FromFormat("<ldb result>");
1965 static PyTypeObject PyLdbResult = {
1966 .tp_name = "ldb.Result",
1967 .tp_repr = (reprfunc)py_ldb_result_repr,
1968 .tp_dealloc = (destructor)py_ldb_result_dealloc,
1969 .tp_iter = (getiterfunc)py_ldb_result_iter,
1970 .tp_getset = py_ldb_result_getset,
1971 .tp_getattro = PyObject_GenericGetAttr,
1972 .tp_basicsize = sizeof(PyLdbResultObject),
1973 .tp_as_sequence = &py_ldb_result_seq,
1974 .tp_doc = "LDB result.",
1975 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1978 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1980 return PyString_FromFormat("<ldb module '%s'>",
1981 pyldb_Module_AsModule(self)->ops->name);
1984 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1986 return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
1989 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1991 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
1992 Py_RETURN_NONE;
1995 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1997 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
1998 Py_RETURN_NONE;
2001 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2003 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2004 Py_RETURN_NONE;
2007 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2009 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2010 int ret, scope;
2011 struct ldb_request *req;
2012 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2013 struct ldb_module *mod;
2014 const char * const*attrs;
2016 /* type "int" rather than "enum" for "scope" is intentional */
2017 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
2018 discard_const_p(char *, kwnames),
2019 &py_base, &scope, &py_tree, &py_attrs))
2020 return NULL;
2022 mod = self->mod;
2024 if (py_attrs == Py_None) {
2025 attrs = NULL;
2026 } else {
2027 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
2028 if (attrs == NULL)
2029 return NULL;
2032 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2033 scope, NULL /* expr */, attrs,
2034 NULL /* controls */, NULL, NULL, NULL);
2036 talloc_steal(req, attrs);
2038 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2040 req->op.search.res = NULL;
2042 ret = mod->ops->search(mod, req);
2044 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2046 py_ret = PyLdbResult_FromResult(req->op.search.res);
2048 talloc_free(req);
2050 return py_ret;
2054 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2056 struct ldb_request *req;
2057 PyObject *py_message;
2058 int ret;
2059 struct ldb_module *mod;
2061 if (!PyArg_ParseTuple(args, "O", &py_message))
2062 return NULL;
2064 req = talloc_zero(NULL, struct ldb_request);
2065 req->operation = LDB_ADD;
2066 req->op.add.message = pyldb_Message_AsMessage(py_message);
2068 mod = pyldb_Module_AsModule(self);
2069 ret = mod->ops->add(mod, req);
2071 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2073 Py_RETURN_NONE;
2076 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2078 int ret;
2079 struct ldb_request *req;
2080 PyObject *py_message;
2081 struct ldb_module *mod;
2083 if (!PyArg_ParseTuple(args, "O", &py_message))
2084 return NULL;
2086 req = talloc_zero(NULL, struct ldb_request);
2087 req->operation = LDB_MODIFY;
2088 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2090 mod = pyldb_Module_AsModule(self);
2091 ret = mod->ops->modify(mod, req);
2093 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2095 Py_RETURN_NONE;
2098 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2100 int ret;
2101 struct ldb_request *req;
2102 PyObject *py_dn;
2104 if (!PyArg_ParseTuple(args, "O", &py_dn))
2105 return NULL;
2107 req = talloc_zero(NULL, struct ldb_request);
2108 req->operation = LDB_DELETE;
2109 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2111 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2113 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2115 Py_RETURN_NONE;
2118 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2120 int ret;
2121 struct ldb_request *req;
2122 PyObject *py_dn1, *py_dn2;
2124 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
2125 return NULL;
2127 req = talloc_zero(NULL, struct ldb_request);
2129 req->operation = LDB_RENAME;
2130 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2131 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2133 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2135 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2137 Py_RETURN_NONE;
2140 static PyMethodDef py_ldb_module_methods[] = {
2141 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2142 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2143 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2144 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2145 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2146 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2147 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2148 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2149 { NULL },
2152 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2154 talloc_free(self->mem_ctx);
2155 PyObject_Del(self);
2158 static PyTypeObject PyLdbModule = {
2159 .tp_name = "ldb.LdbModule",
2160 .tp_methods = py_ldb_module_methods,
2161 .tp_repr = (reprfunc)py_ldb_module_repr,
2162 .tp_str = (reprfunc)py_ldb_module_str,
2163 .tp_basicsize = sizeof(PyLdbModuleObject),
2164 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2165 .tp_flags = Py_TPFLAGS_DEFAULT,
2166 .tp_doc = "LDB module (extension)",
2171 * Create a ldb_message_element from a Python object.
2173 * This will accept any sequence objects that contains strings, or
2174 * a string object.
2176 * A reference to set_obj will be borrowed.
2178 * @param mem_ctx Memory context
2179 * @param set_obj Python object to convert
2180 * @param flags ldb_message_element flags to set
2181 * @param attr_name Name of the attribute
2182 * @return New ldb_message_element, allocated as child of mem_ctx
2184 static struct ldb_message_element *PyObject_AsMessageElement(
2185 TALLOC_CTX *mem_ctx,
2186 PyObject *set_obj,
2187 unsigned int flags,
2188 const char *attr_name)
2190 struct ldb_message_element *me;
2192 if (pyldb_MessageElement_Check(set_obj)) {
2193 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2194 /* We have to talloc_reference() the memory context, not the pointer
2195 * which may not actually be it's own context */
2196 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2197 return pyldb_MessageElement_AsMessageElement(set_obj);
2199 return NULL;
2202 me = talloc(mem_ctx, struct ldb_message_element);
2203 if (me == NULL) {
2204 PyErr_NoMemory();
2205 return NULL;
2208 me->name = talloc_strdup(me, attr_name);
2209 me->flags = flags;
2210 if (PyString_Check(set_obj)) {
2211 me->num_values = 1;
2212 me->values = talloc_array(me, struct ldb_val, me->num_values);
2213 me->values[0].length = PyString_Size(set_obj);
2214 me->values[0].data = talloc_memdup(me,
2215 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2216 } else if (PySequence_Check(set_obj)) {
2217 Py_ssize_t i;
2218 me->num_values = PySequence_Size(set_obj);
2219 me->values = talloc_array(me, struct ldb_val, me->num_values);
2220 for (i = 0; i < me->num_values; i++) {
2221 PyObject *obj = PySequence_GetItem(set_obj, i);
2222 if (!PyString_Check(obj)) {
2223 PyErr_Format(PyExc_TypeError,
2224 "Expected string as element %zd in list", i);
2225 talloc_free(me);
2226 return NULL;
2229 me->values[i].length = PyString_Size(obj);
2230 me->values[i].data = talloc_memdup(me,
2231 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2233 } else {
2234 talloc_free(me);
2235 me = NULL;
2238 return me;
2242 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2243 struct ldb_message_element *me)
2245 Py_ssize_t i;
2246 PyObject *result;
2248 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2249 result = PyList_New(me->num_values);
2251 for (i = 0; i < me->num_values; i++) {
2252 PyList_SetItem(result, i,
2253 PyObject_FromLdbValue(&me->values[i]));
2256 return result;
2259 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2261 unsigned int i;
2262 if (!PyArg_ParseTuple(args, "I", &i))
2263 return NULL;
2264 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2265 Py_RETURN_NONE;
2267 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2270 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2272 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2273 return PyInt_FromLong(el->flags);
2276 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2278 unsigned int flags;
2279 struct ldb_message_element *el;
2280 if (!PyArg_ParseTuple(args, "I", &flags))
2281 return NULL;
2283 el = pyldb_MessageElement_AsMessageElement(self);
2284 el->flags = flags;
2285 Py_RETURN_NONE;
2288 static PyMethodDef py_ldb_msg_element_methods[] = {
2289 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2290 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2291 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2292 { NULL },
2295 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2297 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2300 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2302 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2303 if (idx < 0 || idx >= el->num_values) {
2304 PyErr_SetString(PyExc_IndexError, "Out of range");
2305 return NULL;
2307 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2310 static PySequenceMethods py_ldb_msg_element_seq = {
2311 .sq_length = (lenfunc)py_ldb_msg_element_len,
2312 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2315 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2317 int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2318 pyldb_MessageElement_AsMessageElement(other));
2319 return SIGN(ret);
2322 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2324 PyObject *el = ldb_msg_element_to_set(NULL,
2325 pyldb_MessageElement_AsMessageElement(self));
2326 return PyObject_GetIter(el);
2329 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2331 PyLdbMessageElementObject *ret;
2332 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2333 if (ret == NULL) {
2334 PyErr_NoMemory();
2335 return NULL;
2337 ret->mem_ctx = talloc_new(NULL);
2338 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2339 PyErr_NoMemory();
2340 return NULL;
2342 ret->el = el;
2343 return (PyObject *)ret;
2346 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2348 PyObject *py_elements = NULL;
2349 struct ldb_message_element *el;
2350 unsigned int flags = 0;
2351 char *name = NULL;
2352 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2353 PyLdbMessageElementObject *ret;
2354 TALLOC_CTX *mem_ctx;
2356 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2357 discard_const_p(char *, kwnames),
2358 &py_elements, &flags, &name))
2359 return NULL;
2361 mem_ctx = talloc_new(NULL);
2362 if (mem_ctx == NULL) {
2363 PyErr_NoMemory();
2364 return NULL;
2367 el = talloc_zero(mem_ctx, struct ldb_message_element);
2368 if (el == NULL) {
2369 PyErr_NoMemory();
2370 talloc_free(mem_ctx);
2371 return NULL;
2374 if (py_elements != NULL) {
2375 Py_ssize_t i;
2376 if (PyString_Check(py_elements)) {
2377 el->num_values = 1;
2378 el->values = talloc_array(el, struct ldb_val, 1);
2379 if (el->values == NULL) {
2380 talloc_free(mem_ctx);
2381 PyErr_NoMemory();
2382 return NULL;
2384 el->values[0].length = PyString_Size(py_elements);
2385 el->values[0].data = talloc_memdup(el->values,
2386 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2387 } else if (PySequence_Check(py_elements)) {
2388 el->num_values = PySequence_Size(py_elements);
2389 el->values = talloc_array(el, struct ldb_val, el->num_values);
2390 if (el->values == NULL) {
2391 talloc_free(mem_ctx);
2392 PyErr_NoMemory();
2393 return NULL;
2395 for (i = 0; i < el->num_values; i++) {
2396 PyObject *item = PySequence_GetItem(py_elements, i);
2397 if (item == NULL) {
2398 talloc_free(mem_ctx);
2399 return NULL;
2401 if (!PyString_Check(item)) {
2402 PyErr_Format(PyExc_TypeError,
2403 "Expected string as element %zd in list", i);
2404 talloc_free(mem_ctx);
2405 return NULL;
2407 el->values[i].length = PyString_Size(item);
2408 el->values[i].data = talloc_memdup(el,
2409 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2411 } else {
2412 PyErr_SetString(PyExc_TypeError,
2413 "Expected string or list");
2414 talloc_free(mem_ctx);
2415 return NULL;
2419 el->flags = flags;
2420 el->name = talloc_strdup(el, name);
2422 ret = PyObject_New(PyLdbMessageElementObject, type);
2423 if (ret == NULL) {
2424 talloc_free(mem_ctx);
2425 return NULL;
2428 ret->mem_ctx = mem_ctx;
2429 ret->el = el;
2430 return (PyObject *)ret;
2433 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2435 char *element_str = NULL;
2436 Py_ssize_t i;
2437 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2438 PyObject *ret;
2440 for (i = 0; i < el->num_values; i++) {
2441 PyObject *o = py_ldb_msg_element_find(self, i);
2442 if (element_str == NULL)
2443 element_str = talloc_strdup(NULL, PyObject_REPR(o));
2444 else
2445 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2448 if (element_str != NULL) {
2449 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2450 talloc_free(element_str);
2451 } else {
2452 ret = PyString_FromString("MessageElement([])");
2455 return ret;
2458 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2460 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2462 if (el->num_values == 1)
2463 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2464 else
2465 Py_RETURN_NONE;
2468 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2470 talloc_free(self->mem_ctx);
2471 PyObject_Del(self);
2474 static PyTypeObject PyLdbMessageElement = {
2475 .tp_name = "ldb.MessageElement",
2476 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2477 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2478 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2479 .tp_str = (reprfunc)py_ldb_msg_element_str,
2480 .tp_methods = py_ldb_msg_element_methods,
2481 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2482 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2483 .tp_as_sequence = &py_ldb_msg_element_seq,
2484 .tp_new = py_ldb_msg_element_new,
2485 .tp_flags = Py_TPFLAGS_DEFAULT,
2486 .tp_doc = "An element of a Message",
2490 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2492 PyObject *py_ldb;
2493 PyObject *py_dict;
2494 PyObject *py_ret;
2495 struct ldb_message *msg;
2496 struct ldb_context *ldb_ctx;
2497 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2499 if (!PyArg_ParseTuple(args, "O!O!|I",
2500 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2501 &mod_flags)) {
2502 return NULL;
2505 if (!PyLdb_Check(py_ldb)) {
2506 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
2507 return NULL;
2510 /* mask only flags we are going to use */
2511 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2512 if (!mod_flags) {
2513 PyErr_SetString(PyExc_ValueError,
2514 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2515 " expected as mod_flag value");
2516 return NULL;
2519 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2521 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2522 if (!msg) {
2523 return NULL;
2526 py_ret = PyLdbMessage_FromMessage(msg);
2528 talloc_unlink(ldb_ctx, msg);
2530 return py_ret;
2533 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2535 char *name;
2536 if (!PyArg_ParseTuple(args, "s", &name))
2537 return NULL;
2539 ldb_msg_remove_attr(self->msg, name);
2541 Py_RETURN_NONE;
2544 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2546 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2547 Py_ssize_t i, j = 0;
2548 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2549 if (msg->dn != NULL) {
2550 PyList_SetItem(obj, j, PyString_FromString("dn"));
2551 j++;
2553 for (i = 0; i < msg->num_elements; i++) {
2554 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2555 j++;
2557 return obj;
2560 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2562 struct ldb_message_element *el;
2563 char *name;
2564 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2565 if (!PyString_Check(py_name)) {
2566 PyErr_SetNone(PyExc_TypeError);
2567 return NULL;
2569 name = PyString_AsString(py_name);
2570 if (!ldb_attr_cmp(name, "dn"))
2571 return pyldb_Dn_FromDn(msg->dn);
2572 el = ldb_msg_find_element(msg, name);
2573 if (el == NULL) {
2574 return NULL;
2576 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2579 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2581 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2582 if (ret == NULL) {
2583 PyErr_SetString(PyExc_KeyError, "No such element");
2584 return NULL;
2586 return ret;
2589 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2591 PyObject *def = NULL;
2592 const char *kwnames[] = { "name", "default", "idx", NULL };
2593 const char *name = NULL;
2594 int idx = -1;
2595 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2596 struct ldb_message_element *el;
2598 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2599 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2600 return NULL;
2603 if (strcasecmp(name, "dn") == 0) {
2604 return pyldb_Dn_FromDn(msg->dn);
2607 el = ldb_msg_find_element(msg, name);
2609 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2610 if (def != NULL) {
2611 return def;
2613 Py_RETURN_NONE;
2616 if (idx == -1) {
2617 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2620 return PyObject_FromLdbValue(&el->values[idx]);
2623 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2625 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2626 Py_ssize_t i, j = 0;
2627 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2628 if (msg->dn != NULL) {
2629 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2630 j++;
2632 for (i = 0; i < msg->num_elements; i++, j++) {
2633 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2634 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2635 PyList_SetItem(l, j, value);
2637 return l;
2640 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2642 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2643 Py_ssize_t i = 0;
2644 PyObject *l = PyList_New(msg->num_elements);
2645 for (i = 0; i < msg->num_elements; i++) {
2646 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2648 return l;
2651 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2653 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2654 PyLdbMessageElementObject *py_element;
2655 int ret;
2656 struct ldb_message_element *el;
2658 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2659 return NULL;
2661 el = talloc_reference(msg, py_element->el);
2662 if (el == NULL) {
2663 PyErr_NoMemory();
2664 return NULL;
2667 ret = ldb_msg_add(msg, el, el->flags);
2668 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2670 Py_RETURN_NONE;
2673 static PyMethodDef py_ldb_msg_methods[] = {
2674 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2675 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2676 "Class method to create ldb.Message object from Dictionary.\n"
2677 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2678 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2679 "S.keys() -> list\n\n"
2680 "Return sequence of all attribute names." },
2681 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2682 "S.remove(name)\n\n"
2683 "Remove all entries for attributes with the specified name."},
2684 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2685 "msg.get(name,default=None,idx=None) -> string\n"
2686 "idx is the index into the values array\n"
2687 "if idx is None, then a list is returned\n"
2688 "if idx is not None, then the element with that index is returned\n"
2689 "if you pass the special name 'dn' then the DN object is returned\n"},
2690 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2691 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2692 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2693 "S.append(element)\n\n"
2694 "Add an element to this message." },
2695 { NULL },
2698 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2700 PyObject *list, *iter;
2702 list = py_ldb_msg_keys(self);
2703 iter = PyObject_GetIter(list);
2704 Py_DECREF(list);
2705 return iter;
2708 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2710 char *attr_name;
2712 if (!PyString_Check(name)) {
2713 PyErr_SetNone(PyExc_TypeError);
2714 return -1;
2717 attr_name = PyString_AsString(name);
2718 if (value == NULL) {
2719 /* delitem */
2720 ldb_msg_remove_attr(self->msg, attr_name);
2721 } else {
2722 int ret;
2723 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2724 value, 0, attr_name);
2725 if (el == NULL)
2726 return -1;
2727 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2728 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2729 if (ret != LDB_SUCCESS) {
2730 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
2731 return -1;
2734 return 0;
2737 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2739 return pyldb_Message_AsMessage(self)->num_elements;
2742 static PyMappingMethods py_ldb_msg_mapping = {
2743 .mp_length = (lenfunc)py_ldb_msg_length,
2744 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2745 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2748 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2750 const char * const kwnames[] = { "dn", NULL };
2751 struct ldb_message *ret;
2752 TALLOC_CTX *mem_ctx;
2753 PyObject *pydn = NULL;
2754 PyLdbMessageObject *py_ret;
2756 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2757 discard_const_p(char *, kwnames),
2758 &pydn))
2759 return NULL;
2761 mem_ctx = talloc_new(NULL);
2762 if (mem_ctx == NULL) {
2763 PyErr_NoMemory();
2764 return NULL;
2767 ret = ldb_msg_new(mem_ctx);
2768 if (ret == NULL) {
2769 talloc_free(mem_ctx);
2770 PyErr_NoMemory();
2771 return NULL;
2774 if (pydn != NULL) {
2775 struct ldb_dn *dn;
2776 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2777 talloc_free(mem_ctx);
2778 return NULL;
2780 ret->dn = talloc_reference(ret, dn);
2783 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2784 if (py_ret == NULL) {
2785 PyErr_NoMemory();
2786 talloc_free(mem_ctx);
2787 return NULL;
2790 py_ret->mem_ctx = mem_ctx;
2791 py_ret->msg = ret;
2792 return (PyObject *)py_ret;
2795 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2797 PyLdbMessageObject *ret;
2799 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2800 if (ret == NULL) {
2801 PyErr_NoMemory();
2802 return NULL;
2804 ret->mem_ctx = talloc_new(NULL);
2805 ret->msg = talloc_reference(ret->mem_ctx, msg);
2806 return (PyObject *)ret;
2809 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2811 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2812 return pyldb_Dn_FromDn(msg->dn);
2815 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2817 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2818 if (!pyldb_Dn_Check(value)) {
2819 PyErr_SetNone(PyExc_TypeError);
2820 return -1;
2823 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2824 return 0;
2827 static PyGetSetDef py_ldb_msg_getset[] = {
2828 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2829 { NULL }
2832 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2834 PyObject *dict = PyDict_New(), *ret;
2835 if (PyDict_Update(dict, (PyObject *)self) != 0)
2836 return NULL;
2837 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2838 Py_DECREF(dict);
2839 return ret;
2842 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2844 talloc_free(self->mem_ctx);
2845 PyObject_Del(self);
2848 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2849 PyLdbMessageObject *py_msg2)
2851 struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
2852 *msg2 = pyldb_Message_AsMessage(py_msg2);
2853 unsigned int i;
2854 int ret;
2856 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2857 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2858 if (ret != 0) {
2859 return SIGN(ret);
2863 ret = msg1->num_elements - msg2->num_elements;
2864 if (ret != 0) {
2865 return SIGN(ret);
2868 for (i = 0; i < msg1->num_elements; i++) {
2869 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2870 &msg2->elements[i]);
2871 if (ret != 0) {
2872 return SIGN(ret);
2875 ret = ldb_msg_element_compare(&msg1->elements[i],
2876 &msg2->elements[i]);
2877 if (ret != 0) {
2878 return SIGN(ret);
2882 return 0;
2885 static PyTypeObject PyLdbMessage = {
2886 .tp_name = "ldb.Message",
2887 .tp_methods = py_ldb_msg_methods,
2888 .tp_getset = py_ldb_msg_getset,
2889 .tp_as_mapping = &py_ldb_msg_mapping,
2890 .tp_basicsize = sizeof(PyLdbMessageObject),
2891 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2892 .tp_new = py_ldb_msg_new,
2893 .tp_repr = (reprfunc)py_ldb_msg_repr,
2894 .tp_flags = Py_TPFLAGS_DEFAULT,
2895 .tp_iter = (getiterfunc)py_ldb_msg_iter,
2896 .tp_compare = (cmpfunc)py_ldb_msg_compare,
2897 .tp_doc = "A LDB Message",
2900 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2902 PyLdbTreeObject *ret;
2904 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2905 if (ret == NULL) {
2906 PyErr_NoMemory();
2907 return NULL;
2910 ret->mem_ctx = talloc_new(NULL);
2911 ret->tree = talloc_reference(ret->mem_ctx, tree);
2912 return (PyObject *)ret;
2915 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2917 talloc_free(self->mem_ctx);
2918 PyObject_Del(self);
2921 static PyTypeObject PyLdbTree = {
2922 .tp_name = "ldb.Tree",
2923 .tp_basicsize = sizeof(PyLdbTreeObject),
2924 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2925 .tp_flags = Py_TPFLAGS_DEFAULT,
2926 .tp_doc = "A search tree",
2929 /* Ldb_module */
2930 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2932 PyObject *py_ldb = (PyObject *)mod->private_data;
2933 PyObject *py_result, *py_base, *py_attrs, *py_tree;
2935 py_base = pyldb_Dn_FromDn(req->op.search.base);
2937 if (py_base == NULL)
2938 return LDB_ERR_OPERATIONS_ERROR;
2940 py_tree = PyLdbTree_FromTree(req->op.search.tree);
2942 if (py_tree == NULL)
2943 return LDB_ERR_OPERATIONS_ERROR;
2945 if (req->op.search.attrs == NULL) {
2946 py_attrs = Py_None;
2947 } else {
2948 int i, len;
2949 for (len = 0; req->op.search.attrs[len]; len++);
2950 py_attrs = PyList_New(len);
2951 for (i = 0; i < len; i++)
2952 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2955 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2956 discard_const_p(char, "OiOO"),
2957 py_base, req->op.search.scope, py_tree, py_attrs);
2959 Py_DECREF(py_attrs);
2960 Py_DECREF(py_tree);
2961 Py_DECREF(py_base);
2963 if (py_result == NULL) {
2964 return LDB_ERR_PYTHON_EXCEPTION;
2967 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2968 if (req->op.search.res == NULL) {
2969 return LDB_ERR_PYTHON_EXCEPTION;
2972 Py_DECREF(py_result);
2974 return LDB_SUCCESS;
2977 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2979 PyObject *py_ldb = (PyObject *)mod->private_data;
2980 PyObject *py_result, *py_msg;
2982 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2984 if (py_msg == NULL) {
2985 return LDB_ERR_OPERATIONS_ERROR;
2988 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2989 discard_const_p(char, "O"),
2990 py_msg);
2992 Py_DECREF(py_msg);
2994 if (py_result == NULL) {
2995 return LDB_ERR_PYTHON_EXCEPTION;
2998 Py_DECREF(py_result);
3000 return LDB_SUCCESS;
3003 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3005 PyObject *py_ldb = (PyObject *)mod->private_data;
3006 PyObject *py_result, *py_msg;
3008 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3010 if (py_msg == NULL) {
3011 return LDB_ERR_OPERATIONS_ERROR;
3014 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3015 discard_const_p(char, "O"),
3016 py_msg);
3018 Py_DECREF(py_msg);
3020 if (py_result == NULL) {
3021 return LDB_ERR_PYTHON_EXCEPTION;
3024 Py_DECREF(py_result);
3026 return LDB_SUCCESS;
3029 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3031 PyObject *py_ldb = (PyObject *)mod->private_data;
3032 PyObject *py_result, *py_dn;
3034 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3036 if (py_dn == NULL)
3037 return LDB_ERR_OPERATIONS_ERROR;
3039 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3040 discard_const_p(char, "O"),
3041 py_dn);
3043 if (py_result == NULL) {
3044 return LDB_ERR_PYTHON_EXCEPTION;
3047 Py_DECREF(py_result);
3049 return LDB_SUCCESS;
3052 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3054 PyObject *py_ldb = (PyObject *)mod->private_data;
3055 PyObject *py_result, *py_olddn, *py_newdn;
3057 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3059 if (py_olddn == NULL)
3060 return LDB_ERR_OPERATIONS_ERROR;
3062 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3064 if (py_newdn == NULL)
3065 return LDB_ERR_OPERATIONS_ERROR;
3067 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3068 discard_const_p(char, "OO"),
3069 py_olddn, py_newdn);
3071 Py_DECREF(py_olddn);
3072 Py_DECREF(py_newdn);
3074 if (py_result == NULL) {
3075 return LDB_ERR_PYTHON_EXCEPTION;
3078 Py_DECREF(py_result);
3080 return LDB_SUCCESS;
3083 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3085 PyObject *py_ldb = (PyObject *)mod->private_data;
3086 PyObject *py_result;
3088 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3089 discard_const_p(char, ""));
3091 Py_XDECREF(py_result);
3093 return LDB_ERR_OPERATIONS_ERROR;
3096 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3098 PyObject *py_ldb = (PyObject *)mod->private_data;
3099 PyObject *py_result;
3101 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3102 discard_const_p(char, ""));
3104 Py_XDECREF(py_result);
3106 return LDB_ERR_OPERATIONS_ERROR;
3109 static int py_module_start_transaction(struct ldb_module *mod)
3111 PyObject *py_ldb = (PyObject *)mod->private_data;
3112 PyObject *py_result;
3114 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3115 discard_const_p(char, ""));
3117 if (py_result == NULL) {
3118 return LDB_ERR_PYTHON_EXCEPTION;
3121 Py_DECREF(py_result);
3123 return LDB_SUCCESS;
3126 static int py_module_end_transaction(struct ldb_module *mod)
3128 PyObject *py_ldb = (PyObject *)mod->private_data;
3129 PyObject *py_result;
3131 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3132 discard_const_p(char, ""));
3134 if (py_result == NULL) {
3135 return LDB_ERR_PYTHON_EXCEPTION;
3138 Py_DECREF(py_result);
3140 return LDB_SUCCESS;
3143 static int py_module_del_transaction(struct ldb_module *mod)
3145 PyObject *py_ldb = (PyObject *)mod->private_data;
3146 PyObject *py_result;
3148 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3149 discard_const_p(char, ""));
3151 if (py_result == NULL) {
3152 return LDB_ERR_PYTHON_EXCEPTION;
3155 Py_DECREF(py_result);
3157 return LDB_SUCCESS;
3160 static int py_module_destructor(struct ldb_module *mod)
3162 Py_DECREF((PyObject *)mod->private_data);
3163 return 0;
3166 static int py_module_init(struct ldb_module *mod)
3168 PyObject *py_class = (PyObject *)mod->ops->private_data;
3169 PyObject *py_result, *py_next, *py_ldb;
3171 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3173 if (py_ldb == NULL)
3174 return LDB_ERR_OPERATIONS_ERROR;
3176 py_next = PyLdbModule_FromModule(mod->next);
3178 if (py_next == NULL)
3179 return LDB_ERR_OPERATIONS_ERROR;
3181 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3182 py_ldb, py_next);
3184 if (py_result == NULL) {
3185 return LDB_ERR_PYTHON_EXCEPTION;
3188 mod->private_data = py_result;
3190 talloc_set_destructor(mod, py_module_destructor);
3192 return ldb_next_init(mod);
3195 static PyObject *py_register_module(PyObject *module, PyObject *args)
3197 int ret;
3198 struct ldb_module_ops *ops;
3199 PyObject *input;
3201 if (!PyArg_ParseTuple(args, "O", &input))
3202 return NULL;
3204 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3205 if (ops == NULL) {
3206 PyErr_NoMemory();
3207 return NULL;
3210 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3212 Py_INCREF(input);
3213 ops->private_data = input;
3214 ops->init_context = py_module_init;
3215 ops->search = py_module_search;
3216 ops->add = py_module_add;
3217 ops->modify = py_module_modify;
3218 ops->del = py_module_del;
3219 ops->rename = py_module_rename;
3220 ops->request = py_module_request;
3221 ops->extended = py_module_extended;
3222 ops->start_transaction = py_module_start_transaction;
3223 ops->end_transaction = py_module_end_transaction;
3224 ops->del_transaction = py_module_del_transaction;
3226 ret = ldb_register_module(ops);
3228 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3230 Py_RETURN_NONE;
3233 static PyObject *py_timestring(PyObject *module, PyObject *args)
3235 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3236 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3237 long int t_val;
3238 char *tresult;
3239 PyObject *ret;
3240 if (!PyArg_ParseTuple(args, "l", &t_val))
3241 return NULL;
3242 tresult = ldb_timestring(NULL, (time_t) t_val);
3243 ret = PyString_FromString(tresult);
3244 talloc_free(tresult);
3245 return ret;
3248 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3250 char *str;
3251 if (!PyArg_ParseTuple(args, "s", &str))
3252 return NULL;
3254 return PyInt_FromLong(ldb_string_to_time(str));
3257 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3259 char *name;
3260 if (!PyArg_ParseTuple(args, "s", &name))
3261 return NULL;
3262 return PyBool_FromLong(ldb_valid_attr_name(name));
3266 encode a string using RFC2254 rules
3268 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3270 char *str, *encoded;
3271 int size = 0;
3272 struct ldb_val val;
3273 PyObject *ret;
3275 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3276 return NULL;
3277 val.data = (uint8_t *)str;
3278 val.length = size;
3280 encoded = ldb_binary_encode(NULL, val);
3281 if (encoded == NULL) {
3282 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3283 return NULL;
3285 ret = PyString_FromString(encoded);
3286 talloc_free(encoded);
3287 return ret;
3291 decode a string using RFC2254 rules
3293 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3295 char *str;
3296 struct ldb_val val;
3297 PyObject *ret;
3299 if (!PyArg_ParseTuple(args, "s", &str))
3300 return NULL;
3302 val = ldb_binary_decode(NULL, str);
3303 if (val.data == NULL) {
3304 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3305 return NULL;
3307 ret = Py_BuildValue("s#", val.data, val.length);
3308 talloc_free(val.data);
3309 return ret;
3312 static PyMethodDef py_ldb_global_methods[] = {
3313 { "register_module", py_register_module, METH_VARARGS,
3314 "S.register_module(module) -> None\n\n"
3315 "Register a LDB module."},
3316 { "timestring", py_timestring, METH_VARARGS,
3317 "S.timestring(int) -> string\n\n"
3318 "Generate a LDAP time string from a UNIX timestamp" },
3319 { "string_to_time", py_string_to_time, METH_VARARGS,
3320 "S.string_to_time(string) -> int\n\n"
3321 "Parse a LDAP time string into a UNIX timestamp." },
3322 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3323 "S.valid_attr_name(name) -> bool\n\nn"
3324 "Check whether the supplied name is a valid attribute name." },
3325 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3326 "S.open() -> Ldb\n\n"
3327 "Open a new LDB context." },
3328 { "binary_encode", py_binary_encode, METH_VARARGS,
3329 "S.binary_encode(string) -> string\n\n"
3330 "Perform a RFC2254 binary encoding on a string" },
3331 { "binary_decode", py_binary_decode, METH_VARARGS,
3332 "S.binary_decode(string) -> string\n\n"
3333 "Perform a RFC2254 binary decode on a string" },
3334 { NULL }
3337 void initldb(void)
3339 PyObject *m;
3341 if (PyType_Ready(&PyLdbDn) < 0)
3342 return;
3344 if (PyType_Ready(&PyLdbMessage) < 0)
3345 return;
3347 if (PyType_Ready(&PyLdbMessageElement) < 0)
3348 return;
3350 if (PyType_Ready(&PyLdb) < 0)
3351 return;
3353 if (PyType_Ready(&PyLdbModule) < 0)
3354 return;
3356 if (PyType_Ready(&PyLdbTree) < 0)
3357 return;
3359 if (PyType_Ready(&PyLdbResult) < 0)
3360 return;
3362 if (PyType_Ready(&PyLdbControl) < 0)
3363 return;
3365 m = Py_InitModule3("ldb", py_ldb_global_methods,
3366 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3367 if (m == NULL)
3368 return;
3370 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3371 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3372 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3373 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3374 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3375 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3376 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3378 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3379 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3380 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3381 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3383 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3384 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3385 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3387 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3388 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3389 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3390 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3391 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3392 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3393 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3394 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3395 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3396 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3397 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3398 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3399 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3400 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3401 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3402 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3403 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3404 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3405 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3406 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3407 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3408 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3409 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3410 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3411 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3412 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3413 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3414 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3415 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3416 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3417 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3418 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3419 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3420 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3421 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3422 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3423 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3424 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3425 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3427 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3428 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3429 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3430 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3432 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3434 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3435 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3437 Py_INCREF(&PyLdb);
3438 Py_INCREF(&PyLdbDn);
3439 Py_INCREF(&PyLdbModule);
3440 Py_INCREF(&PyLdbMessage);
3441 Py_INCREF(&PyLdbMessageElement);
3442 Py_INCREF(&PyLdbTree);
3443 Py_INCREF(&PyLdbResult);
3444 Py_INCREF(&PyLdbControl);
3446 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3447 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3448 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3449 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3450 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3451 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3452 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3454 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3456 #define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3458 ADD_LDB_STRING(SYNTAX_DN);
3459 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3460 ADD_LDB_STRING(SYNTAX_INTEGER);
3461 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3462 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3463 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3464 ADD_LDB_STRING(OID_COMPARATOR_AND);
3465 ADD_LDB_STRING(OID_COMPARATOR_OR);