Remove dead code. Now we have no SWAT we don't use the invalid_services array or...
[Samba.git] / lib / ldb / pyldb.c
blob45831329009e630420993a31f8216c1c6e1fa18a
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 #ifndef Py_RETURN_NONE
68 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
69 #endif
71 #define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
75 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
77 if (self->data != NULL) {
78 char* control = ldb_control_to_string(self->mem_ctx, self->data);
79 if (control == NULL) {
80 PyErr_NoMemory();
81 return NULL;
83 return PyString_FromString(control);
84 } else {
85 return PyString_FromFormat("ldb control");
89 static void py_ldb_control_dealloc(PyLdbControlObject *self)
91 if (self->mem_ctx != NULL) {
92 talloc_free(self->mem_ctx);
94 self->data = NULL;
95 self->ob_type->tp_free(self);
98 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
100 return PyString_FromString(self->data->oid);
103 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
105 return PyBool_FromLong(self->data->critical);
108 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
110 if (PyObject_IsTrue(value)) {
111 self->data->critical = true;
112 } else {
113 self->data->critical = false;
115 return 0;
118 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
120 char *data = NULL;
121 const char * const kwnames[] = { "ldb", "data", NULL };
122 struct ldb_control *parsed_controls;
123 PyLdbControlObject *ret;
124 PyObject *py_ldb;
125 TALLOC_CTX *mem_ctx;
126 struct ldb_context *ldb_ctx;
128 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
129 discard_const_p(char *, kwnames),
130 &py_ldb, &data))
131 return NULL;
133 mem_ctx = talloc_new(NULL);
134 if (mem_ctx == NULL) {
135 PyErr_NoMemory();
136 return NULL;
139 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
140 parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
142 if (!parsed_controls) {
143 talloc_free(mem_ctx);
144 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
145 return NULL;
148 ret = PyObject_New(PyLdbControlObject, type);
149 if (ret == NULL) {
150 PyErr_NoMemory();
151 talloc_free(mem_ctx);
152 return NULL;
155 ret->mem_ctx = mem_ctx;
157 ret->data = talloc_move(mem_ctx, &parsed_controls);
158 if (ret->data == NULL) {
159 Py_DECREF(ret);
160 PyErr_NoMemory();
161 talloc_free(mem_ctx);
162 return NULL;
165 return (PyObject *)ret;
168 static PyGetSetDef py_ldb_control_getset[] = {
169 { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
170 { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
171 { NULL }
174 static PyTypeObject PyLdbControl = {
175 .tp_name = "ldb.control",
176 .tp_dealloc = (destructor)py_ldb_control_dealloc,
177 .tp_getattro = PyObject_GenericGetAttr,
178 .tp_basicsize = sizeof(PyLdbControlObject),
179 .tp_getset = py_ldb_control_getset,
180 .tp_doc = "LDB control.",
181 .tp_str = (reprfunc)py_ldb_control_str,
182 .tp_new = py_ldb_control_new,
183 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
186 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
188 if (ret == LDB_ERR_PYTHON_EXCEPTION)
189 return; /* Python exception should already be set, just keep that */
191 PyErr_SetObject(error,
192 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
193 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
196 static PyObject *PyObject_FromLdbValue(struct ldb_val *val)
198 return PyString_FromStringAndSize((const char *)val->data, val->length);
202 * Create a Python object from a ldb_result.
204 * @param result LDB result to convert
205 * @return Python object with converted result (a list object)
207 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
209 TALLOC_CTX *ctl_ctx = talloc_new(NULL);
210 PyLdbControlObject *ctrl;
211 if (ctl_ctx == NULL) {
212 PyErr_NoMemory();
213 return NULL;
216 ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
217 if (ctrl == NULL) {
218 talloc_free(ctl_ctx);
219 PyErr_NoMemory();
220 return NULL;
222 ctrl->mem_ctx = ctl_ctx;
223 ctrl->data = talloc_steal(ctrl->mem_ctx, control);
224 if (ctrl->data == NULL) {
225 Py_DECREF(ctrl);
226 PyErr_NoMemory();
227 return NULL;
229 return (PyObject*) ctrl;
233 * Create a Python object from a ldb_result.
235 * @param result LDB result to convert
236 * @return Python object with converted result (a list object)
238 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
240 PyLdbResultObject *ret;
241 PyObject *list, *controls, *referals;
242 Py_ssize_t i;
244 if (result == NULL) {
245 Py_RETURN_NONE;
248 ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
249 if (ret == NULL) {
250 PyErr_NoMemory();
251 return NULL;
254 list = PyList_New(result->count);
255 if (list == NULL) {
256 PyErr_NoMemory();
257 Py_DECREF(ret);
258 return NULL;
261 for (i = 0; i < result->count; i++) {
262 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
265 ret->mem_ctx = talloc_new(NULL);
266 if (ret->mem_ctx == NULL) {
267 Py_DECREF(list);
268 Py_DECREF(ret);
269 PyErr_NoMemory();
270 return NULL;
273 ret->msgs = list;
275 if (result->controls) {
276 controls = PyList_New(1);
277 if (controls == NULL) {
278 Py_DECREF(ret);
279 PyErr_NoMemory();
280 return NULL;
282 for (i=0; result->controls[i]; i++) {
283 PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
284 if (ctrl == NULL) {
285 Py_DECREF(ret);
286 Py_DECREF(controls);
287 PyErr_NoMemory();
288 return NULL;
290 PyList_SetItem(controls, i, ctrl);
292 } else {
294 * No controls so we keep an empty list
296 controls = PyList_New(0);
297 if (controls == NULL) {
298 Py_DECREF(ret);
299 PyErr_NoMemory();
300 return NULL;
304 ret->controls = controls;
306 i = 0;
308 while (result->refs && result->refs[i]) {
309 i++;
312 referals = PyList_New(i);
313 if (referals == NULL) {
314 Py_DECREF(ret);
315 PyErr_NoMemory();
316 return NULL;
319 for (i = 0;result->refs && result->refs[i]; i++) {
320 PyList_SetItem(referals, i, PyString_FromString(result->refs[i]));
322 ret->referals = referals;
323 return (PyObject *)ret;
327 * Create a LDB Result from a Python object.
328 * If conversion fails, NULL will be returned and a Python exception set.
330 * Note: the result object only includes the messages at the moment; extended
331 * result, controls and referrals are ignored.
333 * @param mem_ctx Memory context in which to allocate the LDB Result
334 * @param obj Python object to convert
335 * @return a ldb_result, or NULL if the conversion failed
337 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
338 PyObject *obj)
340 struct ldb_result *res;
341 Py_ssize_t i;
343 if (obj == Py_None)
344 return NULL;
346 res = talloc_zero(mem_ctx, struct ldb_result);
347 res->count = PyList_Size(obj);
348 res->msgs = talloc_array(res, struct ldb_message *, res->count);
349 for (i = 0; i < res->count; i++) {
350 PyObject *item = PyList_GetItem(obj, i);
351 res->msgs[i] = pyldb_Message_AsMessage(item);
353 return res;
356 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
358 return PyBool_FromLong(ldb_dn_validate(self->dn));
361 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
363 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
366 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
368 return PyBool_FromLong(ldb_dn_is_special(self->dn));
371 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
373 return PyBool_FromLong(ldb_dn_is_null(self->dn));
376 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
378 return PyString_FromString(ldb_dn_get_casefold(self->dn));
381 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
383 return PyString_FromString(ldb_dn_get_linearized(self->dn));
386 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
388 return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
391 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
393 return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
396 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
398 const char * const kwnames[] = { "mode", NULL };
399 int mode = 1;
400 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
401 discard_const_p(char *, kwnames),
402 &mode))
403 return NULL;
404 return PyString_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
407 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
409 char *name;
410 const struct ldb_val *val;
412 if (!PyArg_ParseTuple(args, "s", &name))
413 return NULL;
414 val = ldb_dn_get_extended_component(self->dn, name);
415 if (val == NULL) {
416 Py_RETURN_NONE;
419 return PyString_FromStringAndSize((const char *)val->data, val->length);
422 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
424 char *name;
425 PyObject *value;
426 int err;
428 if (!PyArg_ParseTuple(args, "sO", &name, &value))
429 return NULL;
431 if (value == Py_None) {
432 err = ldb_dn_set_extended_component(self->dn, name, NULL);
433 } else {
434 struct ldb_val val;
435 if (!PyString_Check(value)) {
436 PyErr_SetString(PyExc_TypeError, "Expected a string argument");
437 return NULL;
439 val.data = (uint8_t *)PyString_AsString(value);
440 val.length = PyString_Size(value);
441 err = ldb_dn_set_extended_component(self->dn, name, &val);
444 if (err != LDB_SUCCESS) {
445 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
446 return NULL;
449 Py_RETURN_NONE;
452 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
454 return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
457 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
459 char *name;
461 if (!PyArg_ParseTuple(args, "s", &name))
462 return NULL;
464 return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
467 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
469 int ret;
470 ret = ldb_dn_compare(dn1->dn, dn2->dn);
471 if (ret < 0) ret = -1;
472 if (ret > 0) ret = 1;
473 return ret;
476 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
478 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
479 struct ldb_dn *parent;
480 PyLdbDnObject *py_ret;
481 TALLOC_CTX *mem_ctx = talloc_new(NULL);
483 parent = ldb_dn_get_parent(mem_ctx, dn);
484 if (parent == NULL) {
485 talloc_free(mem_ctx);
486 Py_RETURN_NONE;
489 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
490 if (py_ret == NULL) {
491 PyErr_NoMemory();
492 talloc_free(mem_ctx);
493 return NULL;
495 py_ret->mem_ctx = mem_ctx;
496 py_ret->dn = parent;
497 return (PyObject *)py_ret;
500 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
502 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
504 PyObject *py_other;
505 struct ldb_dn *dn, *other;
506 if (!PyArg_ParseTuple(args, "O", &py_other))
507 return NULL;
509 dn = pyldb_Dn_AsDn((PyObject *)self);
511 if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
512 return NULL;
514 return ldb_dn_add_child(dn, other)?Py_True:Py_False;
517 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
519 PyObject *py_other;
520 struct ldb_dn *other, *dn;
521 if (!PyArg_ParseTuple(args, "O", &py_other))
522 return NULL;
524 dn = pyldb_Dn_AsDn((PyObject *)self);
526 if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
527 return NULL;
529 return ldb_dn_add_base(dn, other)?Py_True:Py_False;
532 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
534 struct ldb_dn *dn;
535 int i;
536 if (!PyArg_ParseTuple(args, "i", &i))
537 return NULL;
539 dn = pyldb_Dn_AsDn((PyObject *)self);
541 return ldb_dn_remove_base_components(dn, i)?Py_True:Py_False;
544 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
546 PyObject *py_base;
547 struct ldb_dn *dn, *base;
548 if (!PyArg_ParseTuple(args, "O", &py_base))
549 return NULL;
551 dn = pyldb_Dn_AsDn((PyObject *)self);
553 if (!pyldb_Object_AsDn(NULL, py_base, dn_ldb_ctx(dn), &base))
554 return NULL;
556 return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
559 static PyMethodDef py_ldb_dn_methods[] = {
560 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
561 "S.validate() -> bool\n"
562 "Validate DN is correct." },
563 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
564 "S.is_valid() -> bool\n" },
565 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
566 "S.is_special() -> bool\n"
567 "Check whether this is a special LDB DN." },
568 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
569 "Check whether this is a null DN." },
570 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
571 NULL },
572 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
573 NULL },
574 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
575 "S.canonical_str() -> string\n"
576 "Canonical version of this DN (like a posix path)." },
577 { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
578 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
579 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
580 "S.canonical_ex_str() -> string\n"
581 "Canonical version of this DN (like a posix path, with terminating newline)." },
582 { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
583 "S.extended_str(mode=1) -> string\n"
584 "Extended version of this DN" },
585 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
586 "S.parent() -> dn\n"
587 "Get the parent for this DN." },
588 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
589 "S.add_child(dn) -> None\n"
590 "Add a child DN to this DN." },
591 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
592 "S.add_base(dn) -> None\n"
593 "Add a base DN to this DN." },
594 { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
595 "S.remove_base_components(int) -> bool\n"
596 "Remove a number of DN components from the base of this DN." },
597 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
598 "S.check_special(name) -> bool\n\n"
599 "Check if name is a special DN name"},
600 { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
601 "S.get_extended_component(name) -> string\n\n"
602 "returns a DN extended component as a binary string"},
603 { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
604 "S.set_extended_component(name, value) -> string\n\n"
605 "set a DN extended component as a binary string"},
606 { NULL }
609 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
611 return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
615 copy a DN as a python object
617 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
619 PyLdbDnObject *py_ret;
621 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
622 if (py_ret == NULL) {
623 PyErr_NoMemory();
624 return NULL;
626 py_ret->mem_ctx = talloc_new(NULL);
627 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
628 return (PyObject *)py_ret;
631 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
633 struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self),
634 *other;
635 PyLdbDnObject *py_ret;
637 if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
638 return NULL;
640 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
641 if (py_ret == NULL) {
642 PyErr_NoMemory();
643 return NULL;
645 py_ret->mem_ctx = talloc_new(NULL);
646 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
647 ldb_dn_add_base(py_ret->dn, other);
648 return (PyObject *)py_ret;
651 static PySequenceMethods py_ldb_dn_seq = {
652 .sq_length = (lenfunc)py_ldb_dn_len,
653 .sq_concat = (binaryfunc)py_ldb_dn_concat,
656 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
658 struct ldb_dn *ret;
659 char *str;
660 PyObject *py_ldb;
661 struct ldb_context *ldb_ctx;
662 TALLOC_CTX *mem_ctx;
663 PyLdbDnObject *py_ret;
664 const char * const kwnames[] = { "ldb", "dn", NULL };
666 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
667 discard_const_p(char *, kwnames),
668 &py_ldb, &str))
669 return NULL;
671 if (!PyLdb_Check(py_ldb)) {
672 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
673 return NULL;
676 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
678 mem_ctx = talloc_new(NULL);
679 if (mem_ctx == NULL) {
680 PyErr_NoMemory();
681 return NULL;
684 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
685 if (!ldb_dn_validate(ret)) {
686 talloc_free(mem_ctx);
687 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
688 return NULL;
691 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
692 if (ret == NULL) {
693 talloc_free(mem_ctx);
694 PyErr_NoMemory();
695 return NULL;
697 py_ret->mem_ctx = mem_ctx;
698 py_ret->dn = ret;
699 return (PyObject *)py_ret;
702 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
704 talloc_free(self->mem_ctx);
705 PyObject_Del(self);
708 static PyTypeObject PyLdbDn = {
709 .tp_name = "ldb.Dn",
710 .tp_methods = py_ldb_dn_methods,
711 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
712 .tp_repr = (reprfunc)py_ldb_dn_repr,
713 .tp_compare = (cmpfunc)py_ldb_dn_compare,
714 .tp_as_sequence = &py_ldb_dn_seq,
715 .tp_doc = "A LDB distinguished name.",
716 .tp_new = py_ldb_dn_new,
717 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
718 .tp_basicsize = sizeof(PyLdbDnObject),
719 .tp_flags = Py_TPFLAGS_DEFAULT,
722 /* Debug */
723 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
724 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
726 PyObject *fn = (PyObject *)context;
727 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
730 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
732 PyObject *cb;
733 struct ldb_context *ldb_ctx;
735 if (!PyArg_ParseTuple(args, "O", &cb))
736 return NULL;
738 Py_INCREF(cb);
739 /* FIXME: Where do we DECREF cb ? */
740 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
741 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
742 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
743 ldb_ctx);
745 Py_RETURN_NONE;
748 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
750 unsigned int perms;
751 if (!PyArg_ParseTuple(args, "I", &perms))
752 return NULL;
754 ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
756 Py_RETURN_NONE;
759 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
761 char *modules_dir;
762 if (!PyArg_ParseTuple(args, "s", &modules_dir))
763 return NULL;
765 ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
767 Py_RETURN_NONE;
770 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
772 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
773 int ldb_err;
774 ldb_err = ldb_transaction_start(ldb_ctx);
775 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
776 Py_RETURN_NONE;
779 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
781 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
782 int ldb_err;
783 ldb_err = ldb_transaction_commit(ldb_ctx);
784 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
785 Py_RETURN_NONE;
788 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
790 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
791 int ldb_err;
792 ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
793 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
794 Py_RETURN_NONE;
797 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
799 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
800 int ldb_err;
801 ldb_err = ldb_transaction_cancel(ldb_ctx);
802 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
803 Py_RETURN_NONE;
806 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
808 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
809 int ldb_err;
810 ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
811 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
812 Py_RETURN_NONE;
815 static PyObject *py_ldb_repr(PyLdbObject *self)
817 return PyString_FromFormat("<ldb connection>");
820 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
822 struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
823 if (dn == NULL)
824 Py_RETURN_NONE;
825 return py_ldb_dn_copy(dn);
829 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
831 struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
832 if (dn == NULL)
833 Py_RETURN_NONE;
834 return py_ldb_dn_copy(dn);
837 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
839 struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
840 if (dn == NULL)
841 Py_RETURN_NONE;
842 return py_ldb_dn_copy(dn);
845 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
847 struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
848 if (dn == NULL)
849 Py_RETURN_NONE;
850 return py_ldb_dn_copy(dn);
853 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
854 const char *paramname)
856 const char **ret;
857 Py_ssize_t i;
858 if (!PyList_Check(list)) {
859 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
860 return NULL;
862 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
863 if (ret == NULL) {
864 PyErr_NoMemory();
865 return NULL;
868 for (i = 0; i < PyList_Size(list); i++) {
869 PyObject *item = PyList_GetItem(list, i);
870 if (!PyString_Check(item)) {
871 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
872 return NULL;
874 ret[i] = talloc_strndup(ret, PyString_AsString(item),
875 PyString_Size(item));
877 ret[i] = NULL;
878 return ret;
881 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
883 const char * const kwnames[] = { "url", "flags", "options", NULL };
884 char *url = NULL;
885 PyObject *py_options = Py_None;
886 const char **options;
887 unsigned int flags = 0;
888 int ret;
889 struct ldb_context *ldb;
891 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
892 discard_const_p(char *, kwnames),
893 &url, &flags, &py_options))
894 return -1;
896 ldb = pyldb_Ldb_AsLdbContext(self);
898 if (py_options == Py_None) {
899 options = NULL;
900 } else {
901 options = PyList_AsStringList(ldb, py_options, "options");
902 if (options == NULL)
903 return -1;
906 if (url != NULL) {
907 ret = ldb_connect(ldb, url, flags, options);
908 if (ret != LDB_SUCCESS) {
909 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
910 return -1;
914 talloc_free(options);
915 return 0;
918 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
920 PyLdbObject *ret;
921 struct ldb_context *ldb;
922 ret = (PyLdbObject *)type->tp_alloc(type, 0);
923 if (ret == NULL) {
924 PyErr_NoMemory();
925 return NULL;
927 ret->mem_ctx = talloc_new(NULL);
928 ldb = ldb_init(ret->mem_ctx, NULL);
930 if (ldb == NULL) {
931 PyErr_NoMemory();
932 return NULL;
935 ret->ldb_ctx = ldb;
936 return (PyObject *)ret;
939 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
941 char *url;
942 unsigned int flags = 0;
943 PyObject *py_options = Py_None;
944 int ret;
945 const char **options;
946 const char * const kwnames[] = { "url", "flags", "options", NULL };
947 struct ldb_context *ldb_ctx;
949 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
950 discard_const_p(char *, kwnames),
951 &url, &flags, &py_options))
952 return NULL;
954 if (py_options == Py_None) {
955 options = NULL;
956 } else {
957 options = PyList_AsStringList(NULL, py_options, "options");
958 if (options == NULL)
959 return NULL;
962 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
963 ret = ldb_connect(ldb_ctx, url, flags, options);
964 talloc_free(options);
966 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
968 Py_RETURN_NONE;
971 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
973 PyObject *py_msg;
974 PyObject *py_controls = Py_None;
975 struct ldb_context *ldb_ctx;
976 struct ldb_request *req;
977 struct ldb_control **parsed_controls;
978 struct ldb_message *msg;
979 int ret;
980 TALLOC_CTX *mem_ctx;
981 bool validate=true;
982 const char * const kwnames[] = { "message", "controls", "validate", NULL };
984 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
985 discard_const_p(char *, kwnames),
986 &py_msg, &py_controls, &validate))
987 return NULL;
989 mem_ctx = talloc_new(NULL);
990 if (mem_ctx == NULL) {
991 PyErr_NoMemory();
992 return NULL;
994 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
996 if (py_controls == Py_None) {
997 parsed_controls = NULL;
998 } else {
999 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1000 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1001 talloc_free(controls);
1004 if (!PyLdbMessage_Check(py_msg)) {
1005 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1006 talloc_free(mem_ctx);
1007 return NULL;
1009 msg = pyldb_Message_AsMessage(py_msg);
1011 if (validate) {
1012 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1013 if (ret != LDB_SUCCESS) {
1014 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1015 talloc_free(mem_ctx);
1016 return NULL;
1020 ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1021 NULL, ldb_op_default_callback, NULL);
1022 if (ret != LDB_SUCCESS) {
1023 PyErr_SetString(PyExc_TypeError, "failed to build request");
1024 talloc_free(mem_ctx);
1025 return NULL;
1028 /* do request and autostart a transaction */
1029 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1031 ret = ldb_transaction_start(ldb_ctx);
1032 if (ret != LDB_SUCCESS) {
1033 talloc_free(mem_ctx);
1034 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1035 return NULL;
1038 ret = ldb_request(ldb_ctx, req);
1039 if (ret == LDB_SUCCESS) {
1040 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1043 if (ret == LDB_SUCCESS) {
1044 ret = ldb_transaction_commit(ldb_ctx);
1045 } else {
1046 ldb_transaction_cancel(ldb_ctx);
1049 talloc_free(mem_ctx);
1050 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1052 Py_RETURN_NONE;
1057 * Obtain a ldb message from a Python Dictionary object.
1059 * @param mem_ctx Memory context
1060 * @param py_obj Python Dictionary object
1061 * @param ldb_ctx LDB context
1062 * @param mod_flags Flags to be set on every message element
1063 * @return ldb_message on success or NULL on failure
1065 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1066 PyObject *py_obj,
1067 struct ldb_context *ldb_ctx,
1068 unsigned int mod_flags)
1070 struct ldb_message *msg;
1071 unsigned int msg_pos = 0;
1072 Py_ssize_t dict_pos = 0;
1073 PyObject *key, *value;
1074 struct ldb_message_element *msg_el;
1075 PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1077 msg = ldb_msg_new(mem_ctx);
1078 if (msg == NULL) {
1079 PyErr_NoMemory();
1080 return NULL;
1082 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1084 if (dn_value) {
1085 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1086 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1087 return NULL;
1089 if (msg->dn == NULL) {
1090 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1091 return NULL;
1093 } else {
1094 PyErr_SetString(PyExc_TypeError, "no dn set");
1095 return NULL;
1098 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1099 char *key_str = PyString_AsString(key);
1100 if (ldb_attr_cmp(key_str, "dn") != 0) {
1101 msg_el = PyObject_AsMessageElement(msg->elements, value,
1102 mod_flags, key_str);
1103 if (msg_el == NULL) {
1104 PyErr_SetString(PyExc_TypeError, "unable to import element");
1105 return NULL;
1107 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1108 msg_pos++;
1112 msg->num_elements = msg_pos;
1114 return msg;
1117 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1119 PyObject *py_obj;
1120 int ret;
1121 struct ldb_context *ldb_ctx;
1122 struct ldb_request *req;
1123 struct ldb_message *msg = NULL;
1124 PyObject *py_controls = Py_None;
1125 TALLOC_CTX *mem_ctx;
1126 struct ldb_control **parsed_controls;
1127 const char * const kwnames[] = { "message", "controls", NULL };
1129 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1130 discard_const_p(char *, kwnames),
1131 &py_obj, &py_controls))
1132 return NULL;
1134 mem_ctx = talloc_new(NULL);
1135 if (mem_ctx == NULL) {
1136 PyErr_NoMemory();
1137 return NULL;
1139 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1141 if (py_controls == Py_None) {
1142 parsed_controls = NULL;
1143 } else {
1144 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1145 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1146 talloc_free(controls);
1149 if (PyLdbMessage_Check(py_obj)) {
1150 msg = pyldb_Message_AsMessage(py_obj);
1151 } else if (PyDict_Check(py_obj)) {
1152 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1153 } else {
1154 PyErr_SetString(PyExc_TypeError,
1155 "Dictionary or LdbMessage object expected!");
1158 if (!msg) {
1159 /* we should have a PyErr already set */
1160 talloc_free(mem_ctx);
1161 return NULL;
1164 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1165 if (ret != LDB_SUCCESS) {
1166 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1167 talloc_free(mem_ctx);
1168 return NULL;
1171 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1172 NULL, ldb_op_default_callback, NULL);
1173 if (ret != LDB_SUCCESS) {
1174 PyErr_SetString(PyExc_TypeError, "failed to build request");
1175 talloc_free(mem_ctx);
1176 return NULL;
1179 /* do request and autostart a transaction */
1180 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1182 ret = ldb_transaction_start(ldb_ctx);
1183 if (ret != LDB_SUCCESS) {
1184 talloc_free(mem_ctx);
1185 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1186 return NULL;
1189 ret = ldb_request(ldb_ctx, req);
1190 if (ret == LDB_SUCCESS) {
1191 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1194 if (ret == LDB_SUCCESS) {
1195 ret = ldb_transaction_commit(ldb_ctx);
1196 } else {
1197 ldb_transaction_cancel(ldb_ctx);
1200 talloc_free(mem_ctx);
1201 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1203 Py_RETURN_NONE;
1206 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1208 PyObject *py_dn;
1209 struct ldb_dn *dn;
1210 int ret;
1211 struct ldb_context *ldb_ctx;
1212 struct ldb_request *req;
1213 PyObject *py_controls = Py_None;
1214 TALLOC_CTX *mem_ctx;
1215 struct ldb_control **parsed_controls;
1216 const char * const kwnames[] = { "dn", "controls", NULL };
1218 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1219 discard_const_p(char *, kwnames),
1220 &py_dn, &py_controls))
1221 return NULL;
1223 mem_ctx = talloc_new(NULL);
1224 if (mem_ctx == NULL) {
1225 PyErr_NoMemory();
1226 return NULL;
1228 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1230 if (py_controls == Py_None) {
1231 parsed_controls = NULL;
1232 } else {
1233 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1234 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1235 talloc_free(controls);
1238 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1239 talloc_free(mem_ctx);
1240 return NULL;
1243 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1244 NULL, ldb_op_default_callback, NULL);
1245 if (ret != LDB_SUCCESS) {
1246 PyErr_SetString(PyExc_TypeError, "failed to build request");
1247 talloc_free(mem_ctx);
1248 return NULL;
1251 /* do request and autostart a transaction */
1252 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1254 ret = ldb_transaction_start(ldb_ctx);
1255 if (ret != LDB_SUCCESS) {
1256 talloc_free(mem_ctx);
1257 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1258 return NULL;
1261 ret = ldb_request(ldb_ctx, req);
1262 if (ret == LDB_SUCCESS) {
1263 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1266 if (ret == LDB_SUCCESS) {
1267 ret = ldb_transaction_commit(ldb_ctx);
1268 } else {
1269 ldb_transaction_cancel(ldb_ctx);
1272 talloc_free(mem_ctx);
1273 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1275 Py_RETURN_NONE;
1278 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1280 PyObject *py_dn1, *py_dn2;
1281 struct ldb_dn *dn1, *dn2;
1282 int ret;
1283 TALLOC_CTX *mem_ctx;
1284 PyObject *py_controls = Py_None;
1285 struct ldb_control **parsed_controls;
1286 struct ldb_context *ldb_ctx;
1287 struct ldb_request *req;
1288 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1290 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1292 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1293 discard_const_p(char *, kwnames),
1294 &py_dn1, &py_dn2, &py_controls))
1295 return NULL;
1298 mem_ctx = talloc_new(NULL);
1299 if (mem_ctx == NULL) {
1300 PyErr_NoMemory();
1301 return NULL;
1304 if (py_controls == Py_None) {
1305 parsed_controls = NULL;
1306 } else {
1307 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1308 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1309 talloc_free(controls);
1313 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1314 talloc_free(mem_ctx);
1315 return NULL;
1318 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1319 talloc_free(mem_ctx);
1320 return NULL;
1323 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1324 NULL, ldb_op_default_callback, NULL);
1325 if (ret != LDB_SUCCESS) {
1326 PyErr_SetString(PyExc_TypeError, "failed to build request");
1327 talloc_free(mem_ctx);
1328 return NULL;
1331 /* do request and autostart a transaction */
1332 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1334 ret = ldb_transaction_start(ldb_ctx);
1335 if (ret != LDB_SUCCESS) {
1336 talloc_free(mem_ctx);
1337 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1338 return NULL;
1341 ret = ldb_request(ldb_ctx, req);
1342 if (ret == LDB_SUCCESS) {
1343 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1346 if (ret == LDB_SUCCESS) {
1347 ret = ldb_transaction_commit(ldb_ctx);
1348 } else {
1349 ldb_transaction_cancel(ldb_ctx);
1352 talloc_free(mem_ctx);
1353 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1355 Py_RETURN_NONE;
1358 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1360 char *name;
1361 if (!PyArg_ParseTuple(args, "s", &name))
1362 return NULL;
1364 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1366 Py_RETURN_NONE;
1369 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1371 char *attribute, *syntax;
1372 unsigned int flags;
1373 int ret;
1374 struct ldb_context *ldb_ctx;
1376 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1377 return NULL;
1379 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1380 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1382 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1384 Py_RETURN_NONE;
1387 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1389 if (ldif == NULL) {
1390 Py_RETURN_NONE;
1391 } else {
1392 /* We don't want this attached to the 'ldb' any more */
1393 return Py_BuildValue(discard_const_p(char, "(iO)"),
1394 ldif->changetype,
1395 PyLdbMessage_FromMessage(ldif->msg));
1400 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1402 int changetype;
1403 PyObject *py_msg;
1404 struct ldb_ldif ldif;
1405 PyObject *ret;
1406 char *string;
1407 TALLOC_CTX *mem_ctx;
1409 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1410 return NULL;
1412 if (!PyLdbMessage_Check(py_msg)) {
1413 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1414 return NULL;
1417 ldif.msg = pyldb_Message_AsMessage(py_msg);
1418 ldif.changetype = changetype;
1420 mem_ctx = talloc_new(NULL);
1422 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1423 if (!string) {
1424 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1425 return NULL;
1428 ret = PyString_FromString(string);
1430 talloc_free(mem_ctx);
1432 return ret;
1435 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1437 PyObject *list;
1438 struct ldb_ldif *ldif;
1439 const char *s;
1441 TALLOC_CTX *mem_ctx;
1443 if (!PyArg_ParseTuple(args, "s", &s))
1444 return NULL;
1446 mem_ctx = talloc_new(NULL);
1447 if (!mem_ctx) {
1448 Py_RETURN_NONE;
1451 list = PyList_New(0);
1452 while (s && *s != '\0') {
1453 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1454 talloc_steal(mem_ctx, ldif);
1455 if (ldif) {
1456 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1457 } else {
1458 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1459 talloc_free(mem_ctx);
1460 return NULL;
1463 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1464 return PyObject_GetIter(list);
1467 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1469 int ldb_ret;
1470 PyObject *py_msg_old;
1471 PyObject *py_msg_new;
1472 struct ldb_message *diff;
1473 struct ldb_context *ldb;
1474 PyObject *py_ret;
1476 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1477 return NULL;
1479 if (!PyLdbMessage_Check(py_msg_old)) {
1480 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1481 return NULL;
1484 if (!PyLdbMessage_Check(py_msg_new)) {
1485 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1486 return NULL;
1489 ldb = pyldb_Ldb_AsLdbContext(self);
1490 ldb_ret = ldb_msg_difference(ldb, ldb,
1491 pyldb_Message_AsMessage(py_msg_old),
1492 pyldb_Message_AsMessage(py_msg_new),
1493 &diff);
1494 if (ldb_ret != LDB_SUCCESS) {
1495 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1496 return NULL;
1499 py_ret = PyLdbMessage_FromMessage(diff);
1501 talloc_unlink(ldb, diff);
1503 return py_ret;
1506 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1508 const struct ldb_schema_attribute *a;
1509 struct ldb_val old_val;
1510 struct ldb_val new_val;
1511 TALLOC_CTX *mem_ctx;
1512 PyObject *ret;
1513 char *element_name;
1514 PyObject *val;
1516 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1517 return NULL;
1519 mem_ctx = talloc_new(NULL);
1521 old_val.data = (uint8_t *)PyString_AsString(val);
1522 old_val.length = PyString_Size(val);
1524 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1526 if (a == NULL) {
1527 Py_RETURN_NONE;
1530 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1531 talloc_free(mem_ctx);
1532 Py_RETURN_NONE;
1535 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1537 talloc_free(mem_ctx);
1539 return ret;
1542 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1544 PyObject *py_base = Py_None;
1545 int scope = LDB_SCOPE_DEFAULT;
1546 char *expr = NULL;
1547 PyObject *py_attrs = Py_None;
1548 PyObject *py_controls = Py_None;
1549 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1550 int ret;
1551 struct ldb_result *res;
1552 struct ldb_request *req;
1553 const char **attrs;
1554 struct ldb_context *ldb_ctx;
1555 struct ldb_control **parsed_controls;
1556 struct ldb_dn *base;
1557 PyObject *py_ret;
1558 TALLOC_CTX *mem_ctx;
1560 /* type "int" rather than "enum" for "scope" is intentional */
1561 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1562 discard_const_p(char *, kwnames),
1563 &py_base, &scope, &expr, &py_attrs, &py_controls))
1564 return NULL;
1567 mem_ctx = talloc_new(NULL);
1568 if (mem_ctx == NULL) {
1569 PyErr_NoMemory();
1570 return NULL;
1572 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1574 if (py_attrs == Py_None) {
1575 attrs = NULL;
1576 } else {
1577 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1578 if (attrs == NULL) {
1579 talloc_free(mem_ctx);
1580 return NULL;
1584 if (py_base == Py_None) {
1585 base = ldb_get_default_basedn(ldb_ctx);
1586 } else {
1587 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1588 talloc_free(attrs);
1589 return NULL;
1593 if (py_controls == Py_None) {
1594 parsed_controls = NULL;
1595 } else {
1596 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1597 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1598 talloc_free(controls);
1601 res = talloc_zero(mem_ctx, struct ldb_result);
1602 if (res == NULL) {
1603 PyErr_NoMemory();
1604 talloc_free(mem_ctx);
1605 return NULL;
1608 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1609 base,
1610 scope,
1611 expr,
1612 attrs,
1613 parsed_controls,
1614 res,
1615 ldb_search_default_callback,
1616 NULL);
1618 if (ret != LDB_SUCCESS) {
1619 talloc_free(mem_ctx);
1620 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1621 return NULL;
1624 talloc_steal(req, attrs);
1626 ret = ldb_request(ldb_ctx, req);
1628 if (ret == LDB_SUCCESS) {
1629 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1632 if (ret != LDB_SUCCESS) {
1633 talloc_free(mem_ctx);
1634 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1635 return NULL;
1638 py_ret = PyLdbResult_FromResult(res);
1640 talloc_free(mem_ctx);
1642 return py_ret;
1645 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1647 char *name;
1648 void *data;
1650 if (!PyArg_ParseTuple(args, "s", &name))
1651 return NULL;
1653 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1655 if (data == NULL)
1656 Py_RETURN_NONE;
1658 /* FIXME: More interpretation */
1660 return Py_True;
1663 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1665 char *name;
1666 PyObject *data;
1668 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1669 return NULL;
1671 /* FIXME: More interpretation */
1673 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1675 Py_RETURN_NONE;
1678 static PyObject *py_ldb_modules(PyLdbObject *self)
1680 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1681 PyObject *ret = PyList_New(0);
1682 struct ldb_module *mod;
1684 for (mod = ldb->modules; mod; mod = mod->next) {
1685 PyList_Append(ret, PyLdbModule_FromModule(mod));
1688 return ret;
1691 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1693 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1694 int type, ret;
1695 uint64_t value;
1697 if (!PyArg_ParseTuple(args, "i", &type))
1698 return NULL;
1700 /* FIXME: More interpretation */
1702 ret = ldb_sequence_number(ldb, type, &value);
1704 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1706 return PyLong_FromLongLong(value);
1708 static PyMethodDef py_ldb_methods[] = {
1709 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1710 "S.set_debug(callback) -> None\n"
1711 "Set callback for LDB debug messages.\n"
1712 "The callback should accept a debug level and debug text." },
1713 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1714 "S.set_create_perms(mode) -> None\n"
1715 "Set mode to use when creating new LDB files." },
1716 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1717 "S.set_modules_dir(path) -> None\n"
1718 "Set path LDB should search for modules" },
1719 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1720 "S.transaction_start() -> None\n"
1721 "Start a new transaction." },
1722 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1723 "S.transaction_prepare_commit() -> None\n"
1724 "prepare to commit a new transaction (2-stage commit)." },
1725 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1726 "S.transaction_commit() -> None\n"
1727 "commit a new transaction." },
1728 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1729 "S.transaction_cancel() -> None\n"
1730 "cancel a new transaction." },
1731 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1732 NULL },
1733 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1734 NULL },
1735 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1736 NULL },
1737 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1738 NULL },
1739 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1740 NULL },
1741 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1742 "S.connect(url, flags=0, options=None) -> None\n"
1743 "Connect to a LDB URL." },
1744 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1745 "S.modify(message, controls=None, validate=False) -> None\n"
1746 "Modify an entry." },
1747 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1748 "S.add(message, controls=None) -> None\n"
1749 "Add an entry." },
1750 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1751 "S.delete(dn, controls=None) -> None\n"
1752 "Remove an entry." },
1753 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1754 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1755 "Rename an entry." },
1756 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1757 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1758 "Search in a database.\n"
1759 "\n"
1760 ":param base: Optional base DN to search\n"
1761 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1762 ":param expression: Optional search expression\n"
1763 ":param attrs: Attributes to return (defaults to all)\n"
1764 ":param controls: Optional list of controls\n"
1765 ":return: Iterator over Message objects\n"
1767 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1768 NULL },
1769 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1770 NULL },
1771 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1772 NULL },
1773 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1774 "S.parse_ldif(ldif) -> iter(messages)\n"
1775 "Parse a string formatted using LDIF." },
1776 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1777 "S.write_ldif(message, changetype) -> ldif\n"
1778 "Print the message as a string formatted using LDIF." },
1779 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1780 "S.msg_diff(Message) -> Message\n"
1781 "Return an LDB Message of the difference between two Message objects." },
1782 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1783 "S.get_opaque(name) -> value\n"
1784 "Get an opaque value set on this LDB connection. \n"
1785 ":note: The returned value may not be useful in Python."
1787 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1788 "S.set_opaque(name, value) -> None\n"
1789 "Set an opaque value on this LDB connection. \n"
1790 ":note: Passing incorrect values may cause crashes." },
1791 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1792 "S.modules() -> list\n"
1793 "Return the list of modules on this LDB connection " },
1794 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1795 "S.sequence_number(type) -> value\n"
1796 "Return the value of the sequence according to the requested type" },
1797 { NULL },
1800 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1802 PyLdbModuleObject *ret;
1804 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1805 if (ret == NULL) {
1806 PyErr_NoMemory();
1807 return NULL;
1809 ret->mem_ctx = talloc_new(NULL);
1810 ret->mod = talloc_reference(ret->mem_ctx, mod);
1811 return (PyObject *)ret;
1814 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1816 return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1819 static PyGetSetDef py_ldb_getset[] = {
1820 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1821 { NULL }
1824 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1826 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1827 struct ldb_dn *dn;
1828 struct ldb_result *result;
1829 unsigned int count;
1830 int ret;
1832 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1833 return -1;
1836 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1837 NULL);
1838 if (ret != LDB_SUCCESS) {
1839 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1840 return -1;
1843 count = result->count;
1845 talloc_free(result);
1847 if (count > 1) {
1848 PyErr_Format(PyExc_RuntimeError,
1849 "Searching for [%s] dn gave %u results!",
1850 ldb_dn_get_linearized(dn),
1851 count);
1852 return -1;
1855 return count;
1858 static PySequenceMethods py_ldb_seq = {
1859 .sq_contains = (objobjproc)py_ldb_contains,
1862 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1864 PyLdbObject *ret;
1866 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1867 if (ret == NULL) {
1868 PyErr_NoMemory();
1869 return NULL;
1871 ret->mem_ctx = talloc_new(NULL);
1872 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1873 return (PyObject *)ret;
1876 static void py_ldb_dealloc(PyLdbObject *self)
1878 talloc_free(self->mem_ctx);
1879 self->ob_type->tp_free(self);
1882 static PyTypeObject PyLdb = {
1883 .tp_name = "ldb.Ldb",
1884 .tp_methods = py_ldb_methods,
1885 .tp_repr = (reprfunc)py_ldb_repr,
1886 .tp_new = py_ldb_new,
1887 .tp_init = (initproc)py_ldb_init,
1888 .tp_dealloc = (destructor)py_ldb_dealloc,
1889 .tp_getset = py_ldb_getset,
1890 .tp_getattro = PyObject_GenericGetAttr,
1891 .tp_basicsize = sizeof(PyLdbObject),
1892 .tp_doc = "Connection to a LDB database.",
1893 .tp_as_sequence = &py_ldb_seq,
1894 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1897 static void py_ldb_result_dealloc(PyLdbResultObject *self)
1899 talloc_free(self->mem_ctx);
1900 Py_DECREF(self->msgs);
1901 Py_DECREF(self->referals);
1902 Py_DECREF(self->controls);
1903 self->ob_type->tp_free(self);
1906 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
1908 Py_INCREF(self->msgs);
1909 return self->msgs;
1912 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
1914 Py_INCREF(self->controls);
1915 return self->controls;
1918 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
1920 Py_INCREF(self->referals);
1921 return self->referals;
1924 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
1926 Py_ssize_t size;
1927 if (self->msgs == NULL) {
1928 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
1929 return NULL;
1931 size = PyList_Size(self->msgs);
1932 return PyInt_FromLong(size);
1935 static PyGetSetDef py_ldb_result_getset[] = {
1936 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
1937 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
1938 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
1939 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
1940 { NULL }
1943 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
1945 return PyObject_GetIter(self->msgs);
1948 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
1950 return PySequence_Size(self->msgs);
1953 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
1955 return PySequence_GetItem(self->msgs, idx);
1958 static PySequenceMethods py_ldb_result_seq = {
1959 .sq_length = (lenfunc)py_ldb_result_len,
1960 .sq_item = (ssizeargfunc)py_ldb_result_find,
1963 static PyObject *py_ldb_result_repr(PyLdbObject *self)
1965 return PyString_FromFormat("<ldb result>");
1969 static PyTypeObject PyLdbResult = {
1970 .tp_name = "ldb.Result",
1971 .tp_repr = (reprfunc)py_ldb_result_repr,
1972 .tp_dealloc = (destructor)py_ldb_result_dealloc,
1973 .tp_iter = (getiterfunc)py_ldb_result_iter,
1974 .tp_getset = py_ldb_result_getset,
1975 .tp_getattro = PyObject_GenericGetAttr,
1976 .tp_basicsize = sizeof(PyLdbResultObject),
1977 .tp_as_sequence = &py_ldb_result_seq,
1978 .tp_doc = "LDB result.",
1979 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1982 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1984 return PyString_FromFormat("<ldb module '%s'>",
1985 pyldb_Module_AsModule(self)->ops->name);
1988 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1990 return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
1993 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1995 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
1996 Py_RETURN_NONE;
1999 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2001 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2002 Py_RETURN_NONE;
2005 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2007 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2008 Py_RETURN_NONE;
2011 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2013 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2014 int ret, scope;
2015 struct ldb_request *req;
2016 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2017 struct ldb_module *mod;
2018 const char * const*attrs;
2020 /* type "int" rather than "enum" for "scope" is intentional */
2021 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
2022 discard_const_p(char *, kwnames),
2023 &py_base, &scope, &py_tree, &py_attrs))
2024 return NULL;
2026 mod = self->mod;
2028 if (py_attrs == Py_None) {
2029 attrs = NULL;
2030 } else {
2031 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
2032 if (attrs == NULL)
2033 return NULL;
2036 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2037 scope, NULL /* expr */, attrs,
2038 NULL /* controls */, NULL, NULL, NULL);
2040 talloc_steal(req, attrs);
2042 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2044 req->op.search.res = NULL;
2046 ret = mod->ops->search(mod, req);
2048 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2050 py_ret = PyLdbResult_FromResult(req->op.search.res);
2052 talloc_free(req);
2054 return py_ret;
2058 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2060 struct ldb_request *req;
2061 PyObject *py_message;
2062 int ret;
2063 struct ldb_module *mod;
2065 if (!PyArg_ParseTuple(args, "O", &py_message))
2066 return NULL;
2068 req = talloc_zero(NULL, struct ldb_request);
2069 req->operation = LDB_ADD;
2070 req->op.add.message = pyldb_Message_AsMessage(py_message);
2072 mod = pyldb_Module_AsModule(self);
2073 ret = mod->ops->add(mod, req);
2075 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2077 Py_RETURN_NONE;
2080 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2082 int ret;
2083 struct ldb_request *req;
2084 PyObject *py_message;
2085 struct ldb_module *mod;
2087 if (!PyArg_ParseTuple(args, "O", &py_message))
2088 return NULL;
2090 req = talloc_zero(NULL, struct ldb_request);
2091 req->operation = LDB_MODIFY;
2092 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2094 mod = pyldb_Module_AsModule(self);
2095 ret = mod->ops->modify(mod, req);
2097 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2099 Py_RETURN_NONE;
2102 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2104 int ret;
2105 struct ldb_request *req;
2106 PyObject *py_dn;
2108 if (!PyArg_ParseTuple(args, "O", &py_dn))
2109 return NULL;
2111 req = talloc_zero(NULL, struct ldb_request);
2112 req->operation = LDB_DELETE;
2113 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2115 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2117 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2119 Py_RETURN_NONE;
2122 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2124 int ret;
2125 struct ldb_request *req;
2126 PyObject *py_dn1, *py_dn2;
2128 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
2129 return NULL;
2131 req = talloc_zero(NULL, struct ldb_request);
2133 req->operation = LDB_RENAME;
2134 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2135 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2137 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2139 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2141 Py_RETURN_NONE;
2144 static PyMethodDef py_ldb_module_methods[] = {
2145 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2146 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2147 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2148 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2149 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2150 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2151 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2152 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2153 { NULL },
2156 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2158 talloc_free(self->mem_ctx);
2159 PyObject_Del(self);
2162 static PyTypeObject PyLdbModule = {
2163 .tp_name = "ldb.LdbModule",
2164 .tp_methods = py_ldb_module_methods,
2165 .tp_repr = (reprfunc)py_ldb_module_repr,
2166 .tp_str = (reprfunc)py_ldb_module_str,
2167 .tp_basicsize = sizeof(PyLdbModuleObject),
2168 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2169 .tp_flags = Py_TPFLAGS_DEFAULT,
2170 .tp_doc = "LDB module (extension)",
2175 * Create a ldb_message_element from a Python object.
2177 * This will accept any sequence objects that contains strings, or
2178 * a string object.
2180 * A reference to set_obj will be borrowed.
2182 * @param mem_ctx Memory context
2183 * @param set_obj Python object to convert
2184 * @param flags ldb_message_element flags to set
2185 * @param attr_name Name of the attribute
2186 * @return New ldb_message_element, allocated as child of mem_ctx
2188 static struct ldb_message_element *PyObject_AsMessageElement(
2189 TALLOC_CTX *mem_ctx,
2190 PyObject *set_obj,
2191 unsigned int flags,
2192 const char *attr_name)
2194 struct ldb_message_element *me;
2196 if (pyldb_MessageElement_Check(set_obj)) {
2197 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2198 /* We have to talloc_reference() the memory context, not the pointer
2199 * which may not actually be it's own context */
2200 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2201 return pyldb_MessageElement_AsMessageElement(set_obj);
2203 return NULL;
2206 me = talloc(mem_ctx, struct ldb_message_element);
2207 if (me == NULL) {
2208 PyErr_NoMemory();
2209 return NULL;
2212 me->name = talloc_strdup(me, attr_name);
2213 me->flags = flags;
2214 if (PyString_Check(set_obj)) {
2215 me->num_values = 1;
2216 me->values = talloc_array(me, struct ldb_val, me->num_values);
2217 me->values[0].length = PyString_Size(set_obj);
2218 me->values[0].data = talloc_memdup(me,
2219 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2220 } else if (PySequence_Check(set_obj)) {
2221 Py_ssize_t i;
2222 me->num_values = PySequence_Size(set_obj);
2223 me->values = talloc_array(me, struct ldb_val, me->num_values);
2224 for (i = 0; i < me->num_values; i++) {
2225 PyObject *obj = PySequence_GetItem(set_obj, i);
2226 if (!PyString_Check(obj)) {
2227 PyErr_Format(PyExc_TypeError,
2228 "Expected string as element %zd in list", i);
2229 talloc_free(me);
2230 return NULL;
2233 me->values[i].length = PyString_Size(obj);
2234 me->values[i].data = talloc_memdup(me,
2235 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2237 } else {
2238 talloc_free(me);
2239 me = NULL;
2242 return me;
2246 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2247 struct ldb_message_element *me)
2249 Py_ssize_t i;
2250 PyObject *result;
2252 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2253 result = PyList_New(me->num_values);
2255 for (i = 0; i < me->num_values; i++) {
2256 PyList_SetItem(result, i,
2257 PyObject_FromLdbValue(&me->values[i]));
2260 return result;
2263 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2265 unsigned int i;
2266 if (!PyArg_ParseTuple(args, "I", &i))
2267 return NULL;
2268 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2269 Py_RETURN_NONE;
2271 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2274 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2276 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2277 return PyInt_FromLong(el->flags);
2280 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2282 unsigned int flags;
2283 struct ldb_message_element *el;
2284 if (!PyArg_ParseTuple(args, "I", &flags))
2285 return NULL;
2287 el = pyldb_MessageElement_AsMessageElement(self);
2288 el->flags = flags;
2289 Py_RETURN_NONE;
2292 static PyMethodDef py_ldb_msg_element_methods[] = {
2293 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2294 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2295 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2296 { NULL },
2299 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2301 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2304 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2306 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2307 if (idx < 0 || idx >= el->num_values) {
2308 PyErr_SetString(PyExc_IndexError, "Out of range");
2309 return NULL;
2311 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2314 static PySequenceMethods py_ldb_msg_element_seq = {
2315 .sq_length = (lenfunc)py_ldb_msg_element_len,
2316 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2319 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2321 int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2322 pyldb_MessageElement_AsMessageElement(other));
2323 return SIGN(ret);
2326 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2328 PyObject *el = ldb_msg_element_to_set(NULL,
2329 pyldb_MessageElement_AsMessageElement(self));
2330 return PyObject_GetIter(el);
2333 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2335 PyLdbMessageElementObject *ret;
2336 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2337 if (ret == NULL) {
2338 PyErr_NoMemory();
2339 return NULL;
2341 ret->mem_ctx = talloc_new(NULL);
2342 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2343 PyErr_NoMemory();
2344 return NULL;
2346 ret->el = el;
2347 return (PyObject *)ret;
2350 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2352 PyObject *py_elements = NULL;
2353 struct ldb_message_element *el;
2354 unsigned int flags = 0;
2355 char *name = NULL;
2356 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2357 PyLdbMessageElementObject *ret;
2358 TALLOC_CTX *mem_ctx;
2360 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2361 discard_const_p(char *, kwnames),
2362 &py_elements, &flags, &name))
2363 return NULL;
2365 mem_ctx = talloc_new(NULL);
2366 if (mem_ctx == NULL) {
2367 PyErr_NoMemory();
2368 return NULL;
2371 el = talloc_zero(mem_ctx, struct ldb_message_element);
2372 if (el == NULL) {
2373 PyErr_NoMemory();
2374 talloc_free(mem_ctx);
2375 return NULL;
2378 if (py_elements != NULL) {
2379 Py_ssize_t i;
2380 if (PyString_Check(py_elements)) {
2381 el->num_values = 1;
2382 el->values = talloc_array(el, struct ldb_val, 1);
2383 if (el->values == NULL) {
2384 talloc_free(mem_ctx);
2385 PyErr_NoMemory();
2386 return NULL;
2388 el->values[0].length = PyString_Size(py_elements);
2389 el->values[0].data = talloc_memdup(el->values,
2390 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2391 } else if (PySequence_Check(py_elements)) {
2392 el->num_values = PySequence_Size(py_elements);
2393 el->values = talloc_array(el, struct ldb_val, el->num_values);
2394 if (el->values == NULL) {
2395 talloc_free(mem_ctx);
2396 PyErr_NoMemory();
2397 return NULL;
2399 for (i = 0; i < el->num_values; i++) {
2400 PyObject *item = PySequence_GetItem(py_elements, i);
2401 if (item == NULL) {
2402 talloc_free(mem_ctx);
2403 return NULL;
2405 if (!PyString_Check(item)) {
2406 PyErr_Format(PyExc_TypeError,
2407 "Expected string as element %zd in list", i);
2408 talloc_free(mem_ctx);
2409 return NULL;
2411 el->values[i].length = PyString_Size(item);
2412 el->values[i].data = talloc_memdup(el,
2413 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2415 } else {
2416 PyErr_SetString(PyExc_TypeError,
2417 "Expected string or list");
2418 talloc_free(mem_ctx);
2419 return NULL;
2423 el->flags = flags;
2424 el->name = talloc_strdup(el, name);
2426 ret = PyObject_New(PyLdbMessageElementObject, type);
2427 if (ret == NULL) {
2428 talloc_free(mem_ctx);
2429 return NULL;
2432 ret->mem_ctx = mem_ctx;
2433 ret->el = el;
2434 return (PyObject *)ret;
2437 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2439 char *element_str = NULL;
2440 Py_ssize_t i;
2441 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2442 PyObject *ret;
2444 for (i = 0; i < el->num_values; i++) {
2445 PyObject *o = py_ldb_msg_element_find(self, i);
2446 if (element_str == NULL)
2447 element_str = talloc_strdup(NULL, PyObject_REPR(o));
2448 else
2449 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2452 if (element_str != NULL) {
2453 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2454 talloc_free(element_str);
2455 } else {
2456 ret = PyString_FromString("MessageElement([])");
2459 return ret;
2462 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2464 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2466 if (el->num_values == 1)
2467 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2468 else
2469 Py_RETURN_NONE;
2472 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2474 talloc_free(self->mem_ctx);
2475 PyObject_Del(self);
2478 static PyTypeObject PyLdbMessageElement = {
2479 .tp_name = "ldb.MessageElement",
2480 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2481 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2482 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2483 .tp_str = (reprfunc)py_ldb_msg_element_str,
2484 .tp_methods = py_ldb_msg_element_methods,
2485 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2486 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2487 .tp_as_sequence = &py_ldb_msg_element_seq,
2488 .tp_new = py_ldb_msg_element_new,
2489 .tp_flags = Py_TPFLAGS_DEFAULT,
2490 .tp_doc = "An element of a Message",
2494 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2496 PyObject *py_ldb;
2497 PyObject *py_dict;
2498 PyObject *py_ret;
2499 struct ldb_message *msg;
2500 struct ldb_context *ldb_ctx;
2501 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2503 if (!PyArg_ParseTuple(args, "O!O!|I",
2504 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2505 &mod_flags)) {
2506 return NULL;
2509 if (!PyLdb_Check(py_ldb)) {
2510 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
2511 return NULL;
2514 /* mask only flags we are going to use */
2515 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2516 if (!mod_flags) {
2517 PyErr_SetString(PyExc_ValueError,
2518 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2519 " expected as mod_flag value");
2520 return NULL;
2523 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2525 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2526 if (!msg) {
2527 return NULL;
2530 py_ret = PyLdbMessage_FromMessage(msg);
2532 talloc_unlink(ldb_ctx, msg);
2534 return py_ret;
2537 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2539 char *name;
2540 if (!PyArg_ParseTuple(args, "s", &name))
2541 return NULL;
2543 ldb_msg_remove_attr(self->msg, name);
2545 Py_RETURN_NONE;
2548 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2550 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2551 Py_ssize_t i, j = 0;
2552 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2553 if (msg->dn != NULL) {
2554 PyList_SetItem(obj, j, PyString_FromString("dn"));
2555 j++;
2557 for (i = 0; i < msg->num_elements; i++) {
2558 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2559 j++;
2561 return obj;
2564 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2566 struct ldb_message_element *el;
2567 char *name;
2568 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2569 if (!PyString_Check(py_name)) {
2570 PyErr_SetNone(PyExc_TypeError);
2571 return NULL;
2573 name = PyString_AsString(py_name);
2574 if (!ldb_attr_cmp(name, "dn"))
2575 return pyldb_Dn_FromDn(msg->dn);
2576 el = ldb_msg_find_element(msg, name);
2577 if (el == NULL) {
2578 return NULL;
2580 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2583 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2585 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2586 if (ret == NULL) {
2587 PyErr_SetString(PyExc_KeyError, "No such element");
2588 return NULL;
2590 return ret;
2593 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2595 PyObject *def = NULL;
2596 const char *kwnames[] = { "name", "default", "idx", NULL };
2597 const char *name = NULL;
2598 int idx = -1;
2599 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2600 struct ldb_message_element *el;
2602 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2603 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2604 return NULL;
2607 if (strcasecmp(name, "dn") == 0) {
2608 return pyldb_Dn_FromDn(msg->dn);
2611 el = ldb_msg_find_element(msg, name);
2613 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2614 if (def != NULL) {
2615 return def;
2617 Py_RETURN_NONE;
2620 if (idx == -1) {
2621 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2624 return PyObject_FromLdbValue(&el->values[idx]);
2627 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2629 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2630 Py_ssize_t i, j = 0;
2631 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2632 if (msg->dn != NULL) {
2633 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2634 j++;
2636 for (i = 0; i < msg->num_elements; i++, j++) {
2637 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2638 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2639 PyList_SetItem(l, j, value);
2641 return l;
2644 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2646 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2647 Py_ssize_t i = 0;
2648 PyObject *l = PyList_New(msg->num_elements);
2649 for (i = 0; i < msg->num_elements; i++) {
2650 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2652 return l;
2655 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2657 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2658 PyLdbMessageElementObject *py_element;
2659 int ret;
2660 struct ldb_message_element *el;
2662 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2663 return NULL;
2665 el = talloc_reference(msg, py_element->el);
2666 if (el == NULL) {
2667 PyErr_NoMemory();
2668 return NULL;
2671 ret = ldb_msg_add(msg, el, el->flags);
2672 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2674 Py_RETURN_NONE;
2677 static PyMethodDef py_ldb_msg_methods[] = {
2678 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2679 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2680 "Class method to create ldb.Message object from Dictionary.\n"
2681 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2682 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2683 "S.keys() -> list\n\n"
2684 "Return sequence of all attribute names." },
2685 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2686 "S.remove(name)\n\n"
2687 "Remove all entries for attributes with the specified name."},
2688 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2689 "msg.get(name,default=None,idx=None) -> string\n"
2690 "idx is the index into the values array\n"
2691 "if idx is None, then a list is returned\n"
2692 "if idx is not None, then the element with that index is returned\n"
2693 "if you pass the special name 'dn' then the DN object is returned\n"},
2694 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2695 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2696 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2697 "S.append(element)\n\n"
2698 "Add an element to this message." },
2699 { NULL },
2702 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2704 PyObject *list, *iter;
2706 list = py_ldb_msg_keys(self);
2707 iter = PyObject_GetIter(list);
2708 Py_DECREF(list);
2709 return iter;
2712 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2714 char *attr_name;
2716 if (!PyString_Check(name)) {
2717 PyErr_SetNone(PyExc_TypeError);
2718 return -1;
2721 attr_name = PyString_AsString(name);
2722 if (value == NULL) {
2723 /* delitem */
2724 ldb_msg_remove_attr(self->msg, attr_name);
2725 } else {
2726 int ret;
2727 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2728 value, 0, attr_name);
2729 if (el == NULL)
2730 return -1;
2731 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2732 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2733 if (ret != LDB_SUCCESS) {
2734 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
2735 return -1;
2738 return 0;
2741 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2743 return pyldb_Message_AsMessage(self)->num_elements;
2746 static PyMappingMethods py_ldb_msg_mapping = {
2747 .mp_length = (lenfunc)py_ldb_msg_length,
2748 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2749 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2752 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2754 const char * const kwnames[] = { "dn", NULL };
2755 struct ldb_message *ret;
2756 TALLOC_CTX *mem_ctx;
2757 PyObject *pydn = NULL;
2758 PyLdbMessageObject *py_ret;
2760 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2761 discard_const_p(char *, kwnames),
2762 &pydn))
2763 return NULL;
2765 mem_ctx = talloc_new(NULL);
2766 if (mem_ctx == NULL) {
2767 PyErr_NoMemory();
2768 return NULL;
2771 ret = ldb_msg_new(mem_ctx);
2772 if (ret == NULL) {
2773 talloc_free(mem_ctx);
2774 PyErr_NoMemory();
2775 return NULL;
2778 if (pydn != NULL) {
2779 struct ldb_dn *dn;
2780 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2781 talloc_free(mem_ctx);
2782 return NULL;
2784 ret->dn = talloc_reference(ret, dn);
2787 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2788 if (py_ret == NULL) {
2789 PyErr_NoMemory();
2790 talloc_free(mem_ctx);
2791 return NULL;
2794 py_ret->mem_ctx = mem_ctx;
2795 py_ret->msg = ret;
2796 return (PyObject *)py_ret;
2799 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2801 PyLdbMessageObject *ret;
2803 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2804 if (ret == NULL) {
2805 PyErr_NoMemory();
2806 return NULL;
2808 ret->mem_ctx = talloc_new(NULL);
2809 ret->msg = talloc_reference(ret->mem_ctx, msg);
2810 return (PyObject *)ret;
2813 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2815 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2816 return pyldb_Dn_FromDn(msg->dn);
2819 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2821 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2822 if (!pyldb_Dn_Check(value)) {
2823 PyErr_SetNone(PyExc_TypeError);
2824 return -1;
2827 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2828 return 0;
2831 static PyGetSetDef py_ldb_msg_getset[] = {
2832 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2833 { NULL }
2836 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2838 PyObject *dict = PyDict_New(), *ret;
2839 if (PyDict_Update(dict, (PyObject *)self) != 0)
2840 return NULL;
2841 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2842 Py_DECREF(dict);
2843 return ret;
2846 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2848 talloc_free(self->mem_ctx);
2849 PyObject_Del(self);
2852 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2853 PyLdbMessageObject *py_msg2)
2855 struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
2856 *msg2 = pyldb_Message_AsMessage(py_msg2);
2857 unsigned int i;
2858 int ret;
2860 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2861 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2862 if (ret != 0) {
2863 return SIGN(ret);
2867 ret = msg1->num_elements - msg2->num_elements;
2868 if (ret != 0) {
2869 return SIGN(ret);
2872 for (i = 0; i < msg1->num_elements; i++) {
2873 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2874 &msg2->elements[i]);
2875 if (ret != 0) {
2876 return SIGN(ret);
2879 ret = ldb_msg_element_compare(&msg1->elements[i],
2880 &msg2->elements[i]);
2881 if (ret != 0) {
2882 return SIGN(ret);
2886 return 0;
2889 static PyTypeObject PyLdbMessage = {
2890 .tp_name = "ldb.Message",
2891 .tp_methods = py_ldb_msg_methods,
2892 .tp_getset = py_ldb_msg_getset,
2893 .tp_as_mapping = &py_ldb_msg_mapping,
2894 .tp_basicsize = sizeof(PyLdbMessageObject),
2895 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2896 .tp_new = py_ldb_msg_new,
2897 .tp_repr = (reprfunc)py_ldb_msg_repr,
2898 .tp_flags = Py_TPFLAGS_DEFAULT,
2899 .tp_iter = (getiterfunc)py_ldb_msg_iter,
2900 .tp_compare = (cmpfunc)py_ldb_msg_compare,
2901 .tp_doc = "A LDB Message",
2904 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2906 PyLdbTreeObject *ret;
2908 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2909 if (ret == NULL) {
2910 PyErr_NoMemory();
2911 return NULL;
2914 ret->mem_ctx = talloc_new(NULL);
2915 ret->tree = talloc_reference(ret->mem_ctx, tree);
2916 return (PyObject *)ret;
2919 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2921 talloc_free(self->mem_ctx);
2922 PyObject_Del(self);
2925 static PyTypeObject PyLdbTree = {
2926 .tp_name = "ldb.Tree",
2927 .tp_basicsize = sizeof(PyLdbTreeObject),
2928 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2929 .tp_flags = Py_TPFLAGS_DEFAULT,
2930 .tp_doc = "A search tree",
2933 /* Ldb_module */
2934 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2936 PyObject *py_ldb = (PyObject *)mod->private_data;
2937 PyObject *py_result, *py_base, *py_attrs, *py_tree;
2939 py_base = pyldb_Dn_FromDn(req->op.search.base);
2941 if (py_base == NULL)
2942 return LDB_ERR_OPERATIONS_ERROR;
2944 py_tree = PyLdbTree_FromTree(req->op.search.tree);
2946 if (py_tree == NULL)
2947 return LDB_ERR_OPERATIONS_ERROR;
2949 if (req->op.search.attrs == NULL) {
2950 py_attrs = Py_None;
2951 } else {
2952 int i, len;
2953 for (len = 0; req->op.search.attrs[len]; len++);
2954 py_attrs = PyList_New(len);
2955 for (i = 0; i < len; i++)
2956 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2959 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2960 discard_const_p(char, "OiOO"),
2961 py_base, req->op.search.scope, py_tree, py_attrs);
2963 Py_DECREF(py_attrs);
2964 Py_DECREF(py_tree);
2965 Py_DECREF(py_base);
2967 if (py_result == NULL) {
2968 return LDB_ERR_PYTHON_EXCEPTION;
2971 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2972 if (req->op.search.res == NULL) {
2973 return LDB_ERR_PYTHON_EXCEPTION;
2976 Py_DECREF(py_result);
2978 return LDB_SUCCESS;
2981 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2983 PyObject *py_ldb = (PyObject *)mod->private_data;
2984 PyObject *py_result, *py_msg;
2986 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2988 if (py_msg == NULL) {
2989 return LDB_ERR_OPERATIONS_ERROR;
2992 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2993 discard_const_p(char, "O"),
2994 py_msg);
2996 Py_DECREF(py_msg);
2998 if (py_result == NULL) {
2999 return LDB_ERR_PYTHON_EXCEPTION;
3002 Py_DECREF(py_result);
3004 return LDB_SUCCESS;
3007 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3009 PyObject *py_ldb = (PyObject *)mod->private_data;
3010 PyObject *py_result, *py_msg;
3012 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3014 if (py_msg == NULL) {
3015 return LDB_ERR_OPERATIONS_ERROR;
3018 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3019 discard_const_p(char, "O"),
3020 py_msg);
3022 Py_DECREF(py_msg);
3024 if (py_result == NULL) {
3025 return LDB_ERR_PYTHON_EXCEPTION;
3028 Py_DECREF(py_result);
3030 return LDB_SUCCESS;
3033 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3035 PyObject *py_ldb = (PyObject *)mod->private_data;
3036 PyObject *py_result, *py_dn;
3038 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3040 if (py_dn == NULL)
3041 return LDB_ERR_OPERATIONS_ERROR;
3043 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3044 discard_const_p(char, "O"),
3045 py_dn);
3047 if (py_result == NULL) {
3048 return LDB_ERR_PYTHON_EXCEPTION;
3051 Py_DECREF(py_result);
3053 return LDB_SUCCESS;
3056 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3058 PyObject *py_ldb = (PyObject *)mod->private_data;
3059 PyObject *py_result, *py_olddn, *py_newdn;
3061 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3063 if (py_olddn == NULL)
3064 return LDB_ERR_OPERATIONS_ERROR;
3066 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3068 if (py_newdn == NULL)
3069 return LDB_ERR_OPERATIONS_ERROR;
3071 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3072 discard_const_p(char, "OO"),
3073 py_olddn, py_newdn);
3075 Py_DECREF(py_olddn);
3076 Py_DECREF(py_newdn);
3078 if (py_result == NULL) {
3079 return LDB_ERR_PYTHON_EXCEPTION;
3082 Py_DECREF(py_result);
3084 return LDB_SUCCESS;
3087 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3089 PyObject *py_ldb = (PyObject *)mod->private_data;
3090 PyObject *py_result;
3092 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3093 discard_const_p(char, ""));
3095 Py_XDECREF(py_result);
3097 return LDB_ERR_OPERATIONS_ERROR;
3100 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3102 PyObject *py_ldb = (PyObject *)mod->private_data;
3103 PyObject *py_result;
3105 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3106 discard_const_p(char, ""));
3108 Py_XDECREF(py_result);
3110 return LDB_ERR_OPERATIONS_ERROR;
3113 static int py_module_start_transaction(struct ldb_module *mod)
3115 PyObject *py_ldb = (PyObject *)mod->private_data;
3116 PyObject *py_result;
3118 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3119 discard_const_p(char, ""));
3121 if (py_result == NULL) {
3122 return LDB_ERR_PYTHON_EXCEPTION;
3125 Py_DECREF(py_result);
3127 return LDB_SUCCESS;
3130 static int py_module_end_transaction(struct ldb_module *mod)
3132 PyObject *py_ldb = (PyObject *)mod->private_data;
3133 PyObject *py_result;
3135 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3136 discard_const_p(char, ""));
3138 if (py_result == NULL) {
3139 return LDB_ERR_PYTHON_EXCEPTION;
3142 Py_DECREF(py_result);
3144 return LDB_SUCCESS;
3147 static int py_module_del_transaction(struct ldb_module *mod)
3149 PyObject *py_ldb = (PyObject *)mod->private_data;
3150 PyObject *py_result;
3152 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3153 discard_const_p(char, ""));
3155 if (py_result == NULL) {
3156 return LDB_ERR_PYTHON_EXCEPTION;
3159 Py_DECREF(py_result);
3161 return LDB_SUCCESS;
3164 static int py_module_destructor(struct ldb_module *mod)
3166 Py_DECREF((PyObject *)mod->private_data);
3167 return 0;
3170 static int py_module_init(struct ldb_module *mod)
3172 PyObject *py_class = (PyObject *)mod->ops->private_data;
3173 PyObject *py_result, *py_next, *py_ldb;
3175 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3177 if (py_ldb == NULL)
3178 return LDB_ERR_OPERATIONS_ERROR;
3180 py_next = PyLdbModule_FromModule(mod->next);
3182 if (py_next == NULL)
3183 return LDB_ERR_OPERATIONS_ERROR;
3185 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3186 py_ldb, py_next);
3188 if (py_result == NULL) {
3189 return LDB_ERR_PYTHON_EXCEPTION;
3192 mod->private_data = py_result;
3194 talloc_set_destructor(mod, py_module_destructor);
3196 return ldb_next_init(mod);
3199 static PyObject *py_register_module(PyObject *module, PyObject *args)
3201 int ret;
3202 struct ldb_module_ops *ops;
3203 PyObject *input;
3205 if (!PyArg_ParseTuple(args, "O", &input))
3206 return NULL;
3208 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3209 if (ops == NULL) {
3210 PyErr_NoMemory();
3211 return NULL;
3214 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3216 Py_INCREF(input);
3217 ops->private_data = input;
3218 ops->init_context = py_module_init;
3219 ops->search = py_module_search;
3220 ops->add = py_module_add;
3221 ops->modify = py_module_modify;
3222 ops->del = py_module_del;
3223 ops->rename = py_module_rename;
3224 ops->request = py_module_request;
3225 ops->extended = py_module_extended;
3226 ops->start_transaction = py_module_start_transaction;
3227 ops->end_transaction = py_module_end_transaction;
3228 ops->del_transaction = py_module_del_transaction;
3230 ret = ldb_register_module(ops);
3232 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3234 Py_RETURN_NONE;
3237 static PyObject *py_timestring(PyObject *module, PyObject *args)
3239 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3240 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3241 long int t_val;
3242 char *tresult;
3243 PyObject *ret;
3244 if (!PyArg_ParseTuple(args, "l", &t_val))
3245 return NULL;
3246 tresult = ldb_timestring(NULL, (time_t) t_val);
3247 ret = PyString_FromString(tresult);
3248 talloc_free(tresult);
3249 return ret;
3252 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3254 char *str;
3255 if (!PyArg_ParseTuple(args, "s", &str))
3256 return NULL;
3258 return PyInt_FromLong(ldb_string_to_time(str));
3261 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3263 char *name;
3264 if (!PyArg_ParseTuple(args, "s", &name))
3265 return NULL;
3266 return PyBool_FromLong(ldb_valid_attr_name(name));
3270 encode a string using RFC2254 rules
3272 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3274 char *str, *encoded;
3275 int size = 0;
3276 struct ldb_val val;
3277 PyObject *ret;
3279 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3280 return NULL;
3281 val.data = (uint8_t *)str;
3282 val.length = size;
3284 encoded = ldb_binary_encode(NULL, val);
3285 if (encoded == NULL) {
3286 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3287 return NULL;
3289 ret = PyString_FromString(encoded);
3290 talloc_free(encoded);
3291 return ret;
3295 decode a string using RFC2254 rules
3297 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3299 char *str;
3300 struct ldb_val val;
3301 PyObject *ret;
3303 if (!PyArg_ParseTuple(args, "s", &str))
3304 return NULL;
3306 val = ldb_binary_decode(NULL, str);
3307 if (val.data == NULL) {
3308 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3309 return NULL;
3311 ret = Py_BuildValue("s#", val.data, val.length);
3312 talloc_free(val.data);
3313 return ret;
3316 static PyMethodDef py_ldb_global_methods[] = {
3317 { "register_module", py_register_module, METH_VARARGS,
3318 "S.register_module(module) -> None\n\n"
3319 "Register a LDB module."},
3320 { "timestring", py_timestring, METH_VARARGS,
3321 "S.timestring(int) -> string\n\n"
3322 "Generate a LDAP time string from a UNIX timestamp" },
3323 { "string_to_time", py_string_to_time, METH_VARARGS,
3324 "S.string_to_time(string) -> int\n\n"
3325 "Parse a LDAP time string into a UNIX timestamp." },
3326 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3327 "S.valid_attr_name(name) -> bool\n\nn"
3328 "Check whether the supplied name is a valid attribute name." },
3329 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3330 "S.open() -> Ldb\n\n"
3331 "Open a new LDB context." },
3332 { "binary_encode", py_binary_encode, METH_VARARGS,
3333 "S.binary_encode(string) -> string\n\n"
3334 "Perform a RFC2254 binary encoding on a string" },
3335 { "binary_decode", py_binary_decode, METH_VARARGS,
3336 "S.binary_decode(string) -> string\n\n"
3337 "Perform a RFC2254 binary decode on a string" },
3338 { NULL }
3341 void initldb(void)
3343 PyObject *m;
3345 if (PyType_Ready(&PyLdbDn) < 0)
3346 return;
3348 if (PyType_Ready(&PyLdbMessage) < 0)
3349 return;
3351 if (PyType_Ready(&PyLdbMessageElement) < 0)
3352 return;
3354 if (PyType_Ready(&PyLdb) < 0)
3355 return;
3357 if (PyType_Ready(&PyLdbModule) < 0)
3358 return;
3360 if (PyType_Ready(&PyLdbTree) < 0)
3361 return;
3363 if (PyType_Ready(&PyLdbResult) < 0)
3364 return;
3366 if (PyType_Ready(&PyLdbControl) < 0)
3367 return;
3369 m = Py_InitModule3("ldb", py_ldb_global_methods,
3370 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3371 if (m == NULL)
3372 return;
3374 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3375 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3376 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3377 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3378 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3379 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3380 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3382 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3383 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3384 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3385 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3387 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3388 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3389 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3391 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3392 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3393 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3394 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3395 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3396 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3397 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3398 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3399 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3400 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3401 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3402 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3403 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3404 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3405 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3406 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3407 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3408 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3409 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3410 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3411 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3412 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3413 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3414 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3415 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3416 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3417 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3418 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3419 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3420 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3421 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3422 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3423 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3424 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3425 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3426 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3427 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3428 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3429 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3431 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3432 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3433 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3434 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3436 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3438 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3439 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3441 Py_INCREF(&PyLdb);
3442 Py_INCREF(&PyLdbDn);
3443 Py_INCREF(&PyLdbModule);
3444 Py_INCREF(&PyLdbMessage);
3445 Py_INCREF(&PyLdbMessageElement);
3446 Py_INCREF(&PyLdbTree);
3447 Py_INCREF(&PyLdbResult);
3448 Py_INCREF(&PyLdbControl);
3450 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3451 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3452 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3453 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3454 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3455 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3456 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3458 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3460 #define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3462 ADD_LDB_STRING(SYNTAX_DN);
3463 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3464 ADD_LDB_STRING(SYNTAX_INTEGER);
3465 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3466 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3467 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3468 ADD_LDB_STRING(OID_COMPARATOR_AND);
3469 ADD_LDB_STRING(OID_COMPARATOR_OR);