s3:lib/ctdbd_conn: let release_ip_handler return bool
[Samba.git] / lib / ldb / pyldb.c
blob8c9d6b9599bacd510119fa6dbdd8d0d412f3a172
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 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1080 if (dn_value) {
1081 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1082 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1083 return NULL;
1085 if (msg->dn == NULL) {
1086 PyErr_SetString(PyExc_TypeError, "dn set but not found");
1087 return NULL;
1089 } else {
1090 PyErr_SetString(PyExc_TypeError, "no dn set");
1091 return NULL;
1094 while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1095 char *key_str = PyString_AsString(key);
1096 if (ldb_attr_cmp(key_str, "dn") != 0) {
1097 msg_el = PyObject_AsMessageElement(msg->elements, value,
1098 mod_flags, key_str);
1099 if (msg_el == NULL) {
1100 PyErr_SetString(PyExc_TypeError, "unable to import element");
1101 return NULL;
1103 memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1104 msg_pos++;
1108 msg->num_elements = msg_pos;
1110 return msg;
1113 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1115 PyObject *py_obj;
1116 int ret;
1117 struct ldb_context *ldb_ctx;
1118 struct ldb_request *req;
1119 struct ldb_message *msg = NULL;
1120 PyObject *py_controls = Py_None;
1121 TALLOC_CTX *mem_ctx;
1122 struct ldb_control **parsed_controls;
1123 const char * const kwnames[] = { "message", "controls", NULL };
1125 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1126 discard_const_p(char *, kwnames),
1127 &py_obj, &py_controls))
1128 return NULL;
1130 mem_ctx = talloc_new(NULL);
1131 if (mem_ctx == NULL) {
1132 PyErr_NoMemory();
1133 return NULL;
1135 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1137 if (py_controls == Py_None) {
1138 parsed_controls = NULL;
1139 } else {
1140 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1141 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1142 talloc_free(controls);
1145 if (PyLdbMessage_Check(py_obj)) {
1146 msg = pyldb_Message_AsMessage(py_obj);
1147 } else if (PyDict_Check(py_obj)) {
1148 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1149 } else {
1150 PyErr_SetString(PyExc_TypeError,
1151 "Dictionary or LdbMessage object expected!");
1154 if (!msg) {
1155 /* we should have a PyErr already set */
1156 talloc_free(mem_ctx);
1157 return NULL;
1160 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1161 if (ret != LDB_SUCCESS) {
1162 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1163 talloc_free(mem_ctx);
1164 return NULL;
1167 ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1168 NULL, ldb_op_default_callback, NULL);
1169 if (ret != LDB_SUCCESS) {
1170 PyErr_SetString(PyExc_TypeError, "failed to build request");
1171 talloc_free(mem_ctx);
1172 return NULL;
1175 /* do request and autostart a transaction */
1176 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1178 ret = ldb_transaction_start(ldb_ctx);
1179 if (ret != LDB_SUCCESS) {
1180 talloc_free(mem_ctx);
1181 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1182 return NULL;
1185 ret = ldb_request(ldb_ctx, req);
1186 if (ret == LDB_SUCCESS) {
1187 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1190 if (ret == LDB_SUCCESS) {
1191 ret = ldb_transaction_commit(ldb_ctx);
1192 } else {
1193 ldb_transaction_cancel(ldb_ctx);
1196 talloc_free(mem_ctx);
1197 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1199 Py_RETURN_NONE;
1202 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1204 PyObject *py_dn;
1205 struct ldb_dn *dn;
1206 int ret;
1207 struct ldb_context *ldb_ctx;
1208 struct ldb_request *req;
1209 PyObject *py_controls = Py_None;
1210 TALLOC_CTX *mem_ctx;
1211 struct ldb_control **parsed_controls;
1212 const char * const kwnames[] = { "dn", "controls", NULL };
1214 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1215 discard_const_p(char *, kwnames),
1216 &py_dn, &py_controls))
1217 return NULL;
1219 mem_ctx = talloc_new(NULL);
1220 if (mem_ctx == NULL) {
1221 PyErr_NoMemory();
1222 return NULL;
1224 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1226 if (py_controls == Py_None) {
1227 parsed_controls = NULL;
1228 } else {
1229 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1230 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1231 talloc_free(controls);
1234 if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1235 talloc_free(mem_ctx);
1236 return NULL;
1239 ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1240 NULL, ldb_op_default_callback, NULL);
1241 if (ret != LDB_SUCCESS) {
1242 PyErr_SetString(PyExc_TypeError, "failed to build request");
1243 talloc_free(mem_ctx);
1244 return NULL;
1247 /* do request and autostart a transaction */
1248 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1250 ret = ldb_transaction_start(ldb_ctx);
1251 if (ret != LDB_SUCCESS) {
1252 talloc_free(mem_ctx);
1253 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1254 return NULL;
1257 ret = ldb_request(ldb_ctx, req);
1258 if (ret == LDB_SUCCESS) {
1259 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1262 if (ret == LDB_SUCCESS) {
1263 ret = ldb_transaction_commit(ldb_ctx);
1264 } else {
1265 ldb_transaction_cancel(ldb_ctx);
1268 talloc_free(mem_ctx);
1269 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1271 Py_RETURN_NONE;
1274 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1276 PyObject *py_dn1, *py_dn2;
1277 struct ldb_dn *dn1, *dn2;
1278 int ret;
1279 TALLOC_CTX *mem_ctx;
1280 PyObject *py_controls = Py_None;
1281 struct ldb_control **parsed_controls;
1282 struct ldb_context *ldb_ctx;
1283 struct ldb_request *req;
1284 const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1286 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1288 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1289 discard_const_p(char *, kwnames),
1290 &py_dn1, &py_dn2, &py_controls))
1291 return NULL;
1294 mem_ctx = talloc_new(NULL);
1295 if (mem_ctx == NULL) {
1296 PyErr_NoMemory();
1297 return NULL;
1300 if (py_controls == Py_None) {
1301 parsed_controls = NULL;
1302 } else {
1303 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1304 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1305 talloc_free(controls);
1309 if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1310 talloc_free(mem_ctx);
1311 return NULL;
1314 if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1315 talloc_free(mem_ctx);
1316 return NULL;
1319 ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1320 NULL, ldb_op_default_callback, NULL);
1321 if (ret != LDB_SUCCESS) {
1322 PyErr_SetString(PyExc_TypeError, "failed to build request");
1323 talloc_free(mem_ctx);
1324 return NULL;
1327 /* do request and autostart a transaction */
1328 /* Then let's LDB handle the message error in case of pb as they are meaningful */
1330 ret = ldb_transaction_start(ldb_ctx);
1331 if (ret != LDB_SUCCESS) {
1332 talloc_free(mem_ctx);
1333 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1334 return NULL;
1337 ret = ldb_request(ldb_ctx, req);
1338 if (ret == LDB_SUCCESS) {
1339 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1342 if (ret == LDB_SUCCESS) {
1343 ret = ldb_transaction_commit(ldb_ctx);
1344 } else {
1345 ldb_transaction_cancel(ldb_ctx);
1348 talloc_free(mem_ctx);
1349 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1351 Py_RETURN_NONE;
1354 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1356 char *name;
1357 if (!PyArg_ParseTuple(args, "s", &name))
1358 return NULL;
1360 ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1362 Py_RETURN_NONE;
1365 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1367 char *attribute, *syntax;
1368 unsigned int flags;
1369 int ret;
1370 struct ldb_context *ldb_ctx;
1372 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1373 return NULL;
1375 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1376 ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1378 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1380 Py_RETURN_NONE;
1383 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1385 if (ldif == NULL) {
1386 Py_RETURN_NONE;
1387 } else {
1388 /* We don't want this attached to the 'ldb' any more */
1389 return Py_BuildValue(discard_const_p(char, "(iO)"),
1390 ldif->changetype,
1391 PyLdbMessage_FromMessage(ldif->msg));
1396 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1398 int changetype;
1399 PyObject *py_msg;
1400 struct ldb_ldif ldif;
1401 PyObject *ret;
1402 char *string;
1403 TALLOC_CTX *mem_ctx;
1405 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1406 return NULL;
1408 if (!PyLdbMessage_Check(py_msg)) {
1409 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1410 return NULL;
1413 ldif.msg = pyldb_Message_AsMessage(py_msg);
1414 ldif.changetype = changetype;
1416 mem_ctx = talloc_new(NULL);
1418 string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1419 if (!string) {
1420 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1421 return NULL;
1424 ret = PyString_FromString(string);
1426 talloc_free(mem_ctx);
1428 return ret;
1431 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1433 PyObject *list;
1434 struct ldb_ldif *ldif;
1435 const char *s;
1437 TALLOC_CTX *mem_ctx;
1439 if (!PyArg_ParseTuple(args, "s", &s))
1440 return NULL;
1442 mem_ctx = talloc_new(NULL);
1443 if (!mem_ctx) {
1444 Py_RETURN_NONE;
1447 list = PyList_New(0);
1448 while (s && *s != '\0') {
1449 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1450 talloc_steal(mem_ctx, ldif);
1451 if (ldif) {
1452 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1453 } else {
1454 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1455 talloc_free(mem_ctx);
1456 return NULL;
1459 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1460 return PyObject_GetIter(list);
1463 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1465 int ldb_ret;
1466 PyObject *py_msg_old;
1467 PyObject *py_msg_new;
1468 struct ldb_message *diff;
1469 struct ldb_context *ldb;
1470 PyObject *py_ret;
1472 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1473 return NULL;
1475 if (!PyLdbMessage_Check(py_msg_old)) {
1476 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1477 return NULL;
1480 if (!PyLdbMessage_Check(py_msg_new)) {
1481 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1482 return NULL;
1485 ldb = pyldb_Ldb_AsLdbContext(self);
1486 ldb_ret = ldb_msg_difference(ldb, ldb,
1487 pyldb_Message_AsMessage(py_msg_old),
1488 pyldb_Message_AsMessage(py_msg_new),
1489 &diff);
1490 if (ldb_ret != LDB_SUCCESS) {
1491 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1492 return NULL;
1495 py_ret = PyLdbMessage_FromMessage(diff);
1497 talloc_unlink(ldb, diff);
1499 return py_ret;
1502 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1504 const struct ldb_schema_attribute *a;
1505 struct ldb_val old_val;
1506 struct ldb_val new_val;
1507 TALLOC_CTX *mem_ctx;
1508 PyObject *ret;
1509 char *element_name;
1510 PyObject *val;
1512 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1513 return NULL;
1515 mem_ctx = talloc_new(NULL);
1517 old_val.data = (uint8_t *)PyString_AsString(val);
1518 old_val.length = PyString_Size(val);
1520 a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1522 if (a == NULL) {
1523 Py_RETURN_NONE;
1526 if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1527 talloc_free(mem_ctx);
1528 Py_RETURN_NONE;
1531 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1533 talloc_free(mem_ctx);
1535 return ret;
1538 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1540 PyObject *py_base = Py_None;
1541 int scope = LDB_SCOPE_DEFAULT;
1542 char *expr = NULL;
1543 PyObject *py_attrs = Py_None;
1544 PyObject *py_controls = Py_None;
1545 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1546 int ret;
1547 struct ldb_result *res;
1548 struct ldb_request *req;
1549 const char **attrs;
1550 struct ldb_context *ldb_ctx;
1551 struct ldb_control **parsed_controls;
1552 struct ldb_dn *base;
1553 PyObject *py_ret;
1554 TALLOC_CTX *mem_ctx;
1556 /* type "int" rather than "enum" for "scope" is intentional */
1557 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1558 discard_const_p(char *, kwnames),
1559 &py_base, &scope, &expr, &py_attrs, &py_controls))
1560 return NULL;
1563 mem_ctx = talloc_new(NULL);
1564 if (mem_ctx == NULL) {
1565 PyErr_NoMemory();
1566 return NULL;
1568 ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1570 if (py_attrs == Py_None) {
1571 attrs = NULL;
1572 } else {
1573 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1574 if (attrs == NULL) {
1575 talloc_free(mem_ctx);
1576 return NULL;
1580 if (py_base == Py_None) {
1581 base = ldb_get_default_basedn(ldb_ctx);
1582 } else {
1583 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1584 talloc_free(attrs);
1585 return NULL;
1589 if (py_controls == Py_None) {
1590 parsed_controls = NULL;
1591 } else {
1592 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1593 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1594 talloc_free(controls);
1597 res = talloc_zero(mem_ctx, struct ldb_result);
1598 if (res == NULL) {
1599 PyErr_NoMemory();
1600 talloc_free(mem_ctx);
1601 return NULL;
1604 ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1605 base,
1606 scope,
1607 expr,
1608 attrs,
1609 parsed_controls,
1610 res,
1611 ldb_search_default_callback,
1612 NULL);
1614 if (ret != LDB_SUCCESS) {
1615 talloc_free(mem_ctx);
1616 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1617 return NULL;
1620 talloc_steal(req, attrs);
1622 ret = ldb_request(ldb_ctx, req);
1624 if (ret == LDB_SUCCESS) {
1625 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1628 if (ret != LDB_SUCCESS) {
1629 talloc_free(mem_ctx);
1630 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1631 return NULL;
1634 py_ret = PyLdbResult_FromResult(res);
1636 talloc_free(mem_ctx);
1638 return py_ret;
1641 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1643 char *name;
1644 void *data;
1646 if (!PyArg_ParseTuple(args, "s", &name))
1647 return NULL;
1649 data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1651 if (data == NULL)
1652 Py_RETURN_NONE;
1654 /* FIXME: More interpretation */
1656 return Py_True;
1659 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1661 char *name;
1662 PyObject *data;
1664 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1665 return NULL;
1667 /* FIXME: More interpretation */
1669 ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1671 Py_RETURN_NONE;
1674 static PyObject *py_ldb_modules(PyLdbObject *self)
1676 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1677 PyObject *ret = PyList_New(0);
1678 struct ldb_module *mod;
1680 for (mod = ldb->modules; mod; mod = mod->next) {
1681 PyList_Append(ret, PyLdbModule_FromModule(mod));
1684 return ret;
1687 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1689 struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1690 int type, ret;
1691 uint64_t value;
1693 if (!PyArg_ParseTuple(args, "i", &type))
1694 return NULL;
1696 /* FIXME: More interpretation */
1698 ret = ldb_sequence_number(ldb, type, &value);
1700 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1702 return PyLong_FromLongLong(value);
1704 static PyMethodDef py_ldb_methods[] = {
1705 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1706 "S.set_debug(callback) -> None\n"
1707 "Set callback for LDB debug messages.\n"
1708 "The callback should accept a debug level and debug text." },
1709 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1710 "S.set_create_perms(mode) -> None\n"
1711 "Set mode to use when creating new LDB files." },
1712 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1713 "S.set_modules_dir(path) -> None\n"
1714 "Set path LDB should search for modules" },
1715 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1716 "S.transaction_start() -> None\n"
1717 "Start a new transaction." },
1718 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1719 "S.transaction_prepare_commit() -> None\n"
1720 "prepare to commit a new transaction (2-stage commit)." },
1721 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1722 "S.transaction_commit() -> None\n"
1723 "commit a new transaction." },
1724 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1725 "S.transaction_cancel() -> None\n"
1726 "cancel a new transaction." },
1727 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1728 NULL },
1729 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1730 NULL },
1731 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1732 NULL },
1733 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1734 NULL },
1735 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1736 NULL },
1737 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1738 "S.connect(url, flags=0, options=None) -> None\n"
1739 "Connect to a LDB URL." },
1740 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1741 "S.modify(message, controls=None, validate=False) -> None\n"
1742 "Modify an entry." },
1743 { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1744 "S.add(message, controls=None) -> None\n"
1745 "Add an entry." },
1746 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1747 "S.delete(dn, controls=None) -> None\n"
1748 "Remove an entry." },
1749 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1750 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1751 "Rename an entry." },
1752 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1753 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1754 "Search in a database.\n"
1755 "\n"
1756 ":param base: Optional base DN to search\n"
1757 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1758 ":param expression: Optional search expression\n"
1759 ":param attrs: Attributes to return (defaults to all)\n"
1760 ":param controls: Optional list of controls\n"
1761 ":return: Iterator over Message objects\n"
1763 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1764 NULL },
1765 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1766 NULL },
1767 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1768 NULL },
1769 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1770 "S.parse_ldif(ldif) -> iter(messages)\n"
1771 "Parse a string formatted using LDIF." },
1772 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1773 "S.write_ldif(message, changetype) -> ldif\n"
1774 "Print the message as a string formatted using LDIF." },
1775 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1776 "S.msg_diff(Message) -> Message\n"
1777 "Return an LDB Message of the difference between two Message objects." },
1778 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1779 "S.get_opaque(name) -> value\n"
1780 "Get an opaque value set on this LDB connection. \n"
1781 ":note: The returned value may not be useful in Python."
1783 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1784 "S.set_opaque(name, value) -> None\n"
1785 "Set an opaque value on this LDB connection. \n"
1786 ":note: Passing incorrect values may cause crashes." },
1787 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1788 "S.modules() -> list\n"
1789 "Return the list of modules on this LDB connection " },
1790 { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1791 "S.sequence_number(type) -> value\n"
1792 "Return the value of the sequence according to the requested type" },
1793 { NULL },
1796 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1798 PyLdbModuleObject *ret;
1800 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1801 if (ret == NULL) {
1802 PyErr_NoMemory();
1803 return NULL;
1805 ret->mem_ctx = talloc_new(NULL);
1806 ret->mod = talloc_reference(ret->mem_ctx, mod);
1807 return (PyObject *)ret;
1810 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1812 return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1815 static PyGetSetDef py_ldb_getset[] = {
1816 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1817 { NULL }
1820 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1822 struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1823 struct ldb_dn *dn;
1824 struct ldb_result *result;
1825 unsigned int count;
1826 int ret;
1828 if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1829 return -1;
1832 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1833 NULL);
1834 if (ret != LDB_SUCCESS) {
1835 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1836 return -1;
1839 count = result->count;
1841 talloc_free(result);
1843 if (count > 1) {
1844 PyErr_Format(PyExc_RuntimeError,
1845 "Searching for [%s] dn gave %u results!",
1846 ldb_dn_get_linearized(dn),
1847 count);
1848 return -1;
1851 return count;
1854 static PySequenceMethods py_ldb_seq = {
1855 .sq_contains = (objobjproc)py_ldb_contains,
1858 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1860 PyLdbObject *ret;
1862 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1863 if (ret == NULL) {
1864 PyErr_NoMemory();
1865 return NULL;
1867 ret->mem_ctx = talloc_new(NULL);
1868 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1869 return (PyObject *)ret;
1872 static void py_ldb_dealloc(PyLdbObject *self)
1874 talloc_free(self->mem_ctx);
1875 self->ob_type->tp_free(self);
1878 static PyTypeObject PyLdb = {
1879 .tp_name = "ldb.Ldb",
1880 .tp_methods = py_ldb_methods,
1881 .tp_repr = (reprfunc)py_ldb_repr,
1882 .tp_new = py_ldb_new,
1883 .tp_init = (initproc)py_ldb_init,
1884 .tp_dealloc = (destructor)py_ldb_dealloc,
1885 .tp_getset = py_ldb_getset,
1886 .tp_getattro = PyObject_GenericGetAttr,
1887 .tp_basicsize = sizeof(PyLdbObject),
1888 .tp_doc = "Connection to a LDB database.",
1889 .tp_as_sequence = &py_ldb_seq,
1890 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1893 static void py_ldb_result_dealloc(PyLdbResultObject *self)
1895 talloc_free(self->mem_ctx);
1896 Py_DECREF(self->msgs);
1897 Py_DECREF(self->referals);
1898 Py_DECREF(self->controls);
1899 self->ob_type->tp_free(self);
1902 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
1904 Py_INCREF(self->msgs);
1905 return self->msgs;
1908 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
1910 Py_INCREF(self->controls);
1911 return self->controls;
1914 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
1916 Py_INCREF(self->referals);
1917 return self->referals;
1920 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
1922 Py_ssize_t size;
1923 if (self->msgs == NULL) {
1924 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
1925 return NULL;
1927 size = PyList_Size(self->msgs);
1928 return PyInt_FromLong(size);
1931 static PyGetSetDef py_ldb_result_getset[] = {
1932 { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
1933 { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
1934 { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
1935 { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
1936 { NULL }
1939 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
1941 return PyObject_GetIter(self->msgs);
1944 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
1946 return PySequence_Size(self->msgs);
1949 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
1951 return PySequence_GetItem(self->msgs, idx);
1954 static PySequenceMethods py_ldb_result_seq = {
1955 .sq_length = (lenfunc)py_ldb_result_len,
1956 .sq_item = (ssizeargfunc)py_ldb_result_find,
1959 static PyObject *py_ldb_result_repr(PyLdbObject *self)
1961 return PyString_FromFormat("<ldb result>");
1965 static PyTypeObject PyLdbResult = {
1966 .tp_name = "ldb.Result",
1967 .tp_repr = (reprfunc)py_ldb_result_repr,
1968 .tp_dealloc = (destructor)py_ldb_result_dealloc,
1969 .tp_iter = (getiterfunc)py_ldb_result_iter,
1970 .tp_getset = py_ldb_result_getset,
1971 .tp_getattro = PyObject_GenericGetAttr,
1972 .tp_basicsize = sizeof(PyLdbResultObject),
1973 .tp_as_sequence = &py_ldb_result_seq,
1974 .tp_doc = "LDB result.",
1975 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1978 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1980 return PyString_FromFormat("<ldb module '%s'>",
1981 pyldb_Module_AsModule(self)->ops->name);
1984 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1986 return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
1989 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1991 pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
1992 Py_RETURN_NONE;
1995 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1997 pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
1998 Py_RETURN_NONE;
2001 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2003 pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2004 Py_RETURN_NONE;
2007 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2009 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2010 int ret, scope;
2011 struct ldb_request *req;
2012 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2013 struct ldb_module *mod;
2014 const char * const*attrs;
2016 /* type "int" rather than "enum" for "scope" is intentional */
2017 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
2018 discard_const_p(char *, kwnames),
2019 &py_base, &scope, &py_tree, &py_attrs))
2020 return NULL;
2022 mod = self->mod;
2024 if (py_attrs == Py_None) {
2025 attrs = NULL;
2026 } else {
2027 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
2028 if (attrs == NULL)
2029 return NULL;
2032 ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base),
2033 scope, NULL /* expr */, attrs,
2034 NULL /* controls */, NULL, NULL, NULL);
2036 talloc_steal(req, attrs);
2038 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2040 req->op.search.res = NULL;
2042 ret = mod->ops->search(mod, req);
2044 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2046 py_ret = PyLdbResult_FromResult(req->op.search.res);
2048 talloc_free(req);
2050 return py_ret;
2054 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2056 struct ldb_request *req;
2057 PyObject *py_message;
2058 int ret;
2059 struct ldb_module *mod;
2061 if (!PyArg_ParseTuple(args, "O", &py_message))
2062 return NULL;
2064 req = talloc_zero(NULL, struct ldb_request);
2065 req->operation = LDB_ADD;
2066 req->op.add.message = pyldb_Message_AsMessage(py_message);
2068 mod = pyldb_Module_AsModule(self);
2069 ret = mod->ops->add(mod, req);
2071 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2073 Py_RETURN_NONE;
2076 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
2078 int ret;
2079 struct ldb_request *req;
2080 PyObject *py_message;
2081 struct ldb_module *mod;
2083 if (!PyArg_ParseTuple(args, "O", &py_message))
2084 return NULL;
2086 req = talloc_zero(NULL, struct ldb_request);
2087 req->operation = LDB_MODIFY;
2088 req->op.mod.message = pyldb_Message_AsMessage(py_message);
2090 mod = pyldb_Module_AsModule(self);
2091 ret = mod->ops->modify(mod, req);
2093 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2095 Py_RETURN_NONE;
2098 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
2100 int ret;
2101 struct ldb_request *req;
2102 PyObject *py_dn;
2104 if (!PyArg_ParseTuple(args, "O", &py_dn))
2105 return NULL;
2107 req = talloc_zero(NULL, struct ldb_request);
2108 req->operation = LDB_DELETE;
2109 req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2111 ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2113 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2115 Py_RETURN_NONE;
2118 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2120 int ret;
2121 struct ldb_request *req;
2122 PyObject *py_dn1, *py_dn2;
2124 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
2125 return NULL;
2127 req = talloc_zero(NULL, struct ldb_request);
2129 req->operation = LDB_RENAME;
2130 req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2131 req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2133 ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2135 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2137 Py_RETURN_NONE;
2140 static PyMethodDef py_ldb_module_methods[] = {
2141 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2142 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2143 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2144 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2145 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2146 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2147 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2148 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2149 { NULL },
2152 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2154 talloc_free(self->mem_ctx);
2155 PyObject_Del(self);
2158 static PyTypeObject PyLdbModule = {
2159 .tp_name = "ldb.LdbModule",
2160 .tp_methods = py_ldb_module_methods,
2161 .tp_repr = (reprfunc)py_ldb_module_repr,
2162 .tp_str = (reprfunc)py_ldb_module_str,
2163 .tp_basicsize = sizeof(PyLdbModuleObject),
2164 .tp_dealloc = (destructor)py_ldb_module_dealloc,
2165 .tp_flags = Py_TPFLAGS_DEFAULT,
2166 .tp_doc = "LDB module (extension)",
2171 * Create a ldb_message_element from a Python object.
2173 * This will accept any sequence objects that contains strings, or
2174 * a string object.
2176 * A reference to set_obj will be borrowed.
2178 * @param mem_ctx Memory context
2179 * @param set_obj Python object to convert
2180 * @param flags ldb_message_element flags to set
2181 * @param attr_name Name of the attribute
2182 * @return New ldb_message_element, allocated as child of mem_ctx
2184 static struct ldb_message_element *PyObject_AsMessageElement(
2185 TALLOC_CTX *mem_ctx,
2186 PyObject *set_obj,
2187 unsigned int flags,
2188 const char *attr_name)
2190 struct ldb_message_element *me;
2192 if (pyldb_MessageElement_Check(set_obj)) {
2193 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2194 /* We have to talloc_reference() the memory context, not the pointer
2195 * which may not actually be it's own context */
2196 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2197 return pyldb_MessageElement_AsMessageElement(set_obj);
2199 return NULL;
2202 me = talloc(mem_ctx, struct ldb_message_element);
2203 if (me == NULL) {
2204 PyErr_NoMemory();
2205 return NULL;
2208 me->name = talloc_strdup(me, attr_name);
2209 me->flags = flags;
2210 if (PyString_Check(set_obj)) {
2211 me->num_values = 1;
2212 me->values = talloc_array(me, struct ldb_val, me->num_values);
2213 me->values[0].length = PyString_Size(set_obj);
2214 me->values[0].data = talloc_memdup(me,
2215 (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2216 } else if (PySequence_Check(set_obj)) {
2217 Py_ssize_t i;
2218 me->num_values = PySequence_Size(set_obj);
2219 me->values = talloc_array(me, struct ldb_val, me->num_values);
2220 for (i = 0; i < me->num_values; i++) {
2221 PyObject *obj = PySequence_GetItem(set_obj, i);
2222 if (!PyString_Check(obj)) {
2223 PyErr_Format(PyExc_TypeError,
2224 "Expected string as element %zd in list", i);
2225 talloc_free(me);
2226 return NULL;
2229 me->values[i].length = PyString_Size(obj);
2230 me->values[i].data = talloc_memdup(me,
2231 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2233 } else {
2234 talloc_free(me);
2235 me = NULL;
2238 return me;
2242 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2243 struct ldb_message_element *me)
2245 Py_ssize_t i;
2246 PyObject *result;
2248 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2249 result = PyList_New(me->num_values);
2251 for (i = 0; i < me->num_values; i++) {
2252 PyList_SetItem(result, i,
2253 PyObject_FromLdbValue(&me->values[i]));
2256 return result;
2259 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2261 unsigned int i;
2262 if (!PyArg_ParseTuple(args, "I", &i))
2263 return NULL;
2264 if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2265 Py_RETURN_NONE;
2267 return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2270 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2272 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2273 return PyInt_FromLong(el->flags);
2276 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2278 unsigned int flags;
2279 struct ldb_message_element *el;
2280 if (!PyArg_ParseTuple(args, "I", &flags))
2281 return NULL;
2283 el = pyldb_MessageElement_AsMessageElement(self);
2284 el->flags = flags;
2285 Py_RETURN_NONE;
2288 static PyMethodDef py_ldb_msg_element_methods[] = {
2289 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2290 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2291 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2292 { NULL },
2295 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2297 return pyldb_MessageElement_AsMessageElement(self)->num_values;
2300 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2302 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2303 if (idx < 0 || idx >= el->num_values) {
2304 PyErr_SetString(PyExc_IndexError, "Out of range");
2305 return NULL;
2307 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2310 static PySequenceMethods py_ldb_msg_element_seq = {
2311 .sq_length = (lenfunc)py_ldb_msg_element_len,
2312 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2315 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2317 int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2318 pyldb_MessageElement_AsMessageElement(other));
2319 return SIGN(ret);
2322 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2324 PyObject *el = ldb_msg_element_to_set(NULL,
2325 pyldb_MessageElement_AsMessageElement(self));
2326 return PyObject_GetIter(el);
2329 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2331 PyLdbMessageElementObject *ret;
2332 ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2333 if (ret == NULL) {
2334 PyErr_NoMemory();
2335 return NULL;
2337 ret->mem_ctx = talloc_new(NULL);
2338 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2339 PyErr_NoMemory();
2340 return NULL;
2342 ret->el = el;
2343 return (PyObject *)ret;
2346 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2348 PyObject *py_elements = NULL;
2349 struct ldb_message_element *el;
2350 unsigned int flags = 0;
2351 char *name = NULL;
2352 const char * const kwnames[] = { "elements", "flags", "name", NULL };
2353 PyLdbMessageElementObject *ret;
2354 TALLOC_CTX *mem_ctx;
2356 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2357 discard_const_p(char *, kwnames),
2358 &py_elements, &flags, &name))
2359 return NULL;
2361 mem_ctx = talloc_new(NULL);
2362 if (mem_ctx == NULL) {
2363 PyErr_NoMemory();
2364 return NULL;
2367 el = talloc_zero(mem_ctx, struct ldb_message_element);
2368 if (el == NULL) {
2369 PyErr_NoMemory();
2370 talloc_free(mem_ctx);
2371 return NULL;
2374 if (py_elements != NULL) {
2375 Py_ssize_t i;
2376 if (PyString_Check(py_elements)) {
2377 el->num_values = 1;
2378 el->values = talloc_array(el, struct ldb_val, 1);
2379 if (el->values == NULL) {
2380 talloc_free(mem_ctx);
2381 PyErr_NoMemory();
2382 return NULL;
2384 el->values[0].length = PyString_Size(py_elements);
2385 el->values[0].data = talloc_memdup(el->values,
2386 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2387 } else if (PySequence_Check(py_elements)) {
2388 el->num_values = PySequence_Size(py_elements);
2389 el->values = talloc_array(el, struct ldb_val, el->num_values);
2390 if (el->values == NULL) {
2391 talloc_free(mem_ctx);
2392 PyErr_NoMemory();
2393 return NULL;
2395 for (i = 0; i < el->num_values; i++) {
2396 PyObject *item = PySequence_GetItem(py_elements, i);
2397 if (item == NULL) {
2398 talloc_free(mem_ctx);
2399 return NULL;
2401 if (!PyString_Check(item)) {
2402 PyErr_Format(PyExc_TypeError,
2403 "Expected string as element %zd in list", i);
2404 talloc_free(mem_ctx);
2405 return NULL;
2407 el->values[i].length = PyString_Size(item);
2408 el->values[i].data = talloc_memdup(el,
2409 (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2411 } else {
2412 PyErr_SetString(PyExc_TypeError,
2413 "Expected string or list");
2414 talloc_free(mem_ctx);
2415 return NULL;
2419 el->flags = flags;
2420 el->name = talloc_strdup(el, name);
2422 ret = PyObject_New(PyLdbMessageElementObject, type);
2423 if (ret == NULL) {
2424 talloc_free(mem_ctx);
2425 return NULL;
2428 ret->mem_ctx = mem_ctx;
2429 ret->el = el;
2430 return (PyObject *)ret;
2433 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2435 char *element_str = NULL;
2436 Py_ssize_t i;
2437 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2438 PyObject *ret;
2440 for (i = 0; i < el->num_values; i++) {
2441 PyObject *o = py_ldb_msg_element_find(self, i);
2442 if (element_str == NULL)
2443 element_str = talloc_strdup(NULL, PyObject_REPR(o));
2444 else
2445 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2448 if (element_str != NULL) {
2449 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2450 talloc_free(element_str);
2451 } else {
2452 ret = PyString_FromString("MessageElement([])");
2455 return ret;
2458 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2460 struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2462 if (el->num_values == 1)
2463 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2464 else
2465 Py_RETURN_NONE;
2468 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2470 talloc_free(self->mem_ctx);
2471 PyObject_Del(self);
2474 static PyTypeObject PyLdbMessageElement = {
2475 .tp_name = "ldb.MessageElement",
2476 .tp_basicsize = sizeof(PyLdbMessageElementObject),
2477 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2478 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2479 .tp_str = (reprfunc)py_ldb_msg_element_str,
2480 .tp_methods = py_ldb_msg_element_methods,
2481 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2482 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2483 .tp_as_sequence = &py_ldb_msg_element_seq,
2484 .tp_new = py_ldb_msg_element_new,
2485 .tp_flags = Py_TPFLAGS_DEFAULT,
2486 .tp_doc = "An element of a Message",
2490 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2492 PyObject *py_ldb;
2493 PyObject *py_dict;
2494 PyObject *py_ret;
2495 struct ldb_message *msg;
2496 struct ldb_context *ldb_ctx;
2497 unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2499 if (!PyArg_ParseTuple(args, "O!O!|I",
2500 &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2501 &mod_flags)) {
2502 return NULL;
2505 if (!PyLdb_Check(py_ldb)) {
2506 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
2507 return NULL;
2510 /* mask only flags we are going to use */
2511 mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2512 if (!mod_flags) {
2513 PyErr_SetString(PyExc_ValueError,
2514 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2515 " expected as mod_flag value");
2516 return NULL;
2519 ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2521 msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2522 if (!msg) {
2523 return NULL;
2526 py_ret = PyLdbMessage_FromMessage(msg);
2528 talloc_unlink(ldb_ctx, msg);
2530 return py_ret;
2533 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2535 char *name;
2536 if (!PyArg_ParseTuple(args, "s", &name))
2537 return NULL;
2539 ldb_msg_remove_attr(self->msg, name);
2541 Py_RETURN_NONE;
2544 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2546 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2547 Py_ssize_t i, j = 0;
2548 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2549 if (msg->dn != NULL) {
2550 PyList_SetItem(obj, j, PyString_FromString("dn"));
2551 j++;
2553 for (i = 0; i < msg->num_elements; i++) {
2554 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2555 j++;
2557 return obj;
2560 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2562 struct ldb_message_element *el;
2563 char *name;
2564 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2565 if (!PyString_Check(py_name)) {
2566 PyErr_SetNone(PyExc_TypeError);
2567 return NULL;
2569 name = PyString_AsString(py_name);
2570 if (!ldb_attr_cmp(name, "dn"))
2571 return pyldb_Dn_FromDn(msg->dn);
2572 el = ldb_msg_find_element(msg, name);
2573 if (el == NULL) {
2574 return NULL;
2576 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2579 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2581 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2582 if (ret == NULL) {
2583 PyErr_SetString(PyExc_KeyError, "No such element");
2584 return NULL;
2586 return ret;
2589 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2591 PyObject *def = NULL;
2592 const char *kwnames[] = { "name", "default", "idx", NULL };
2593 const char *name = NULL;
2594 int idx = -1;
2595 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2596 struct ldb_message_element *el;
2598 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2599 discard_const_p(char *, kwnames), &name, &def, &idx)) {
2600 return NULL;
2603 if (strcasecmp(name, "dn") == 0) {
2604 return pyldb_Dn_FromDn(msg->dn);
2607 el = ldb_msg_find_element(msg, name);
2609 if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2610 if (def != NULL) {
2611 return def;
2613 Py_RETURN_NONE;
2616 if (idx == -1) {
2617 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2620 return PyObject_FromLdbValue(&el->values[idx]);
2623 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2625 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2626 Py_ssize_t i, j = 0;
2627 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2628 if (msg->dn != NULL) {
2629 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2630 j++;
2632 for (i = 0; i < msg->num_elements; i++, j++) {
2633 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2634 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2635 PyList_SetItem(l, j, value);
2637 return l;
2640 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2642 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2643 Py_ssize_t i = 0;
2644 PyObject *l = PyList_New(msg->num_elements);
2645 for (i = 0; i < msg->num_elements; i++) {
2646 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2648 return l;
2651 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2653 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2654 PyLdbMessageElementObject *py_element;
2655 int ret;
2656 struct ldb_message_element *el;
2658 if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2659 return NULL;
2661 el = talloc_reference(msg, py_element->el);
2662 if (el == NULL) {
2663 PyErr_NoMemory();
2664 return NULL;
2667 ret = ldb_msg_add(msg, el, el->flags);
2668 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2670 Py_RETURN_NONE;
2673 static PyMethodDef py_ldb_msg_methods[] = {
2674 { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2675 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2676 "Class method to create ldb.Message object from Dictionary.\n"
2677 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2678 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS,
2679 "S.keys() -> list\n\n"
2680 "Return sequence of all attribute names." },
2681 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS,
2682 "S.remove(name)\n\n"
2683 "Remove all entries for attributes with the specified name."},
2684 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2685 "msg.get(name,default=None,idx=None) -> string\n"
2686 "idx is the index into the values array\n"
2687 "if idx is None, then a list is returned\n"
2688 "if idx is not None, then the element with that index is returned\n"
2689 "if you pass the special name 'dn' then the DN object is returned\n"},
2690 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2691 { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2692 { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2693 "S.append(element)\n\n"
2694 "Add an element to this message." },
2695 { NULL },
2698 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2700 PyObject *list, *iter;
2702 list = py_ldb_msg_keys(self);
2703 iter = PyObject_GetIter(list);
2704 Py_DECREF(list);
2705 return iter;
2708 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2710 char *attr_name;
2712 if (!PyString_Check(name)) {
2713 PyErr_SetNone(PyExc_TypeError);
2714 return -1;
2717 attr_name = PyString_AsString(name);
2718 if (value == NULL) {
2719 /* delitem */
2720 ldb_msg_remove_attr(self->msg, attr_name);
2721 } else {
2722 int ret;
2723 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2724 value, 0, attr_name);
2725 if (el == NULL)
2726 return -1;
2727 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2728 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2729 if (ret != LDB_SUCCESS) {
2730 PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
2731 return -1;
2734 return 0;
2737 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2739 return pyldb_Message_AsMessage(self)->num_elements;
2742 static PyMappingMethods py_ldb_msg_mapping = {
2743 .mp_length = (lenfunc)py_ldb_msg_length,
2744 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2745 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2748 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2750 const char * const kwnames[] = { "dn", NULL };
2751 struct ldb_message *ret;
2752 TALLOC_CTX *mem_ctx;
2753 PyObject *pydn = NULL;
2754 PyLdbMessageObject *py_ret;
2756 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2757 discard_const_p(char *, kwnames),
2758 &pydn))
2759 return NULL;
2761 mem_ctx = talloc_new(NULL);
2762 if (mem_ctx == NULL) {
2763 PyErr_NoMemory();
2764 return NULL;
2767 ret = ldb_msg_new(mem_ctx);
2768 if (ret == NULL) {
2769 talloc_free(mem_ctx);
2770 PyErr_NoMemory();
2771 return NULL;
2774 if (pydn != NULL) {
2775 struct ldb_dn *dn;
2776 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2777 talloc_free(mem_ctx);
2778 return NULL;
2780 ret->dn = talloc_reference(ret, dn);
2783 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2784 if (py_ret == NULL) {
2785 PyErr_NoMemory();
2786 talloc_free(mem_ctx);
2787 return NULL;
2790 py_ret->mem_ctx = mem_ctx;
2791 py_ret->msg = ret;
2792 return (PyObject *)py_ret;
2795 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2797 PyLdbMessageObject *ret;
2799 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2800 if (ret == NULL) {
2801 PyErr_NoMemory();
2802 return NULL;
2804 ret->mem_ctx = talloc_new(NULL);
2805 ret->msg = talloc_reference(ret->mem_ctx, msg);
2806 return (PyObject *)ret;
2809 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2811 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2812 return pyldb_Dn_FromDn(msg->dn);
2815 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2817 struct ldb_message *msg = pyldb_Message_AsMessage(self);
2818 if (!pyldb_Dn_Check(value)) {
2819 PyErr_SetNone(PyExc_TypeError);
2820 return -1;
2823 msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2824 return 0;
2827 static PyGetSetDef py_ldb_msg_getset[] = {
2828 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2829 { NULL }
2832 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2834 PyObject *dict = PyDict_New(), *ret;
2835 if (PyDict_Update(dict, (PyObject *)self) != 0)
2836 return NULL;
2837 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2838 Py_DECREF(dict);
2839 return ret;
2842 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2844 talloc_free(self->mem_ctx);
2845 PyObject_Del(self);
2848 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2849 PyLdbMessageObject *py_msg2)
2851 struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
2852 *msg2 = pyldb_Message_AsMessage(py_msg2);
2853 unsigned int i;
2854 int ret;
2856 if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2857 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2858 if (ret != 0) {
2859 return SIGN(ret);
2863 ret = msg1->num_elements - msg2->num_elements;
2864 if (ret != 0) {
2865 return SIGN(ret);
2868 for (i = 0; i < msg1->num_elements; i++) {
2869 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2870 &msg2->elements[i]);
2871 if (ret != 0) {
2872 return SIGN(ret);
2875 ret = ldb_msg_element_compare(&msg1->elements[i],
2876 &msg2->elements[i]);
2877 if (ret != 0) {
2878 return SIGN(ret);
2882 return 0;
2885 static PyTypeObject PyLdbMessage = {
2886 .tp_name = "ldb.Message",
2887 .tp_methods = py_ldb_msg_methods,
2888 .tp_getset = py_ldb_msg_getset,
2889 .tp_as_mapping = &py_ldb_msg_mapping,
2890 .tp_basicsize = sizeof(PyLdbMessageObject),
2891 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2892 .tp_new = py_ldb_msg_new,
2893 .tp_repr = (reprfunc)py_ldb_msg_repr,
2894 .tp_flags = Py_TPFLAGS_DEFAULT,
2895 .tp_iter = (getiterfunc)py_ldb_msg_iter,
2896 .tp_compare = (cmpfunc)py_ldb_msg_compare,
2897 .tp_doc = "A LDB Message",
2900 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2902 PyLdbTreeObject *ret;
2904 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2905 if (ret == NULL) {
2906 PyErr_NoMemory();
2907 return NULL;
2910 ret->mem_ctx = talloc_new(NULL);
2911 ret->tree = talloc_reference(ret->mem_ctx, tree);
2912 return (PyObject *)ret;
2915 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2917 talloc_free(self->mem_ctx);
2918 PyObject_Del(self);
2921 static PyTypeObject PyLdbTree = {
2922 .tp_name = "ldb.Tree",
2923 .tp_basicsize = sizeof(PyLdbTreeObject),
2924 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2925 .tp_flags = Py_TPFLAGS_DEFAULT,
2926 .tp_doc = "A search tree",
2929 /* Ldb_module */
2930 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2932 PyObject *py_ldb = (PyObject *)mod->private_data;
2933 PyObject *py_result, *py_base, *py_attrs, *py_tree;
2935 py_base = pyldb_Dn_FromDn(req->op.search.base);
2937 if (py_base == NULL)
2938 return LDB_ERR_OPERATIONS_ERROR;
2940 py_tree = PyLdbTree_FromTree(req->op.search.tree);
2942 if (py_tree == NULL)
2943 return LDB_ERR_OPERATIONS_ERROR;
2945 if (req->op.search.attrs == NULL) {
2946 py_attrs = Py_None;
2947 } else {
2948 int i, len;
2949 for (len = 0; req->op.search.attrs[len]; len++);
2950 py_attrs = PyList_New(len);
2951 for (i = 0; i < len; i++)
2952 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2955 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2956 discard_const_p(char, "OiOO"),
2957 py_base, req->op.search.scope, py_tree, py_attrs);
2959 Py_DECREF(py_attrs);
2960 Py_DECREF(py_tree);
2961 Py_DECREF(py_base);
2963 if (py_result == NULL) {
2964 return LDB_ERR_PYTHON_EXCEPTION;
2967 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2968 if (req->op.search.res == NULL) {
2969 return LDB_ERR_PYTHON_EXCEPTION;
2972 Py_DECREF(py_result);
2974 return LDB_SUCCESS;
2977 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2979 PyObject *py_ldb = (PyObject *)mod->private_data;
2980 PyObject *py_result, *py_msg;
2982 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2984 if (py_msg == NULL) {
2985 return LDB_ERR_OPERATIONS_ERROR;
2988 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2989 discard_const_p(char, "O"),
2990 py_msg);
2992 Py_DECREF(py_msg);
2994 if (py_result == NULL) {
2995 return LDB_ERR_PYTHON_EXCEPTION;
2998 Py_DECREF(py_result);
3000 return LDB_SUCCESS;
3003 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3005 PyObject *py_ldb = (PyObject *)mod->private_data;
3006 PyObject *py_result, *py_msg;
3008 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3010 if (py_msg == NULL) {
3011 return LDB_ERR_OPERATIONS_ERROR;
3014 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3015 discard_const_p(char, "O"),
3016 py_msg);
3018 Py_DECREF(py_msg);
3020 if (py_result == NULL) {
3021 return LDB_ERR_PYTHON_EXCEPTION;
3024 Py_DECREF(py_result);
3026 return LDB_SUCCESS;
3029 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3031 PyObject *py_ldb = (PyObject *)mod->private_data;
3032 PyObject *py_result, *py_dn;
3034 py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3036 if (py_dn == NULL)
3037 return LDB_ERR_OPERATIONS_ERROR;
3039 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3040 discard_const_p(char, "O"),
3041 py_dn);
3043 if (py_result == NULL) {
3044 return LDB_ERR_PYTHON_EXCEPTION;
3047 Py_DECREF(py_result);
3049 return LDB_SUCCESS;
3052 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3054 PyObject *py_ldb = (PyObject *)mod->private_data;
3055 PyObject *py_result, *py_olddn, *py_newdn;
3057 py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3059 if (py_olddn == NULL)
3060 return LDB_ERR_OPERATIONS_ERROR;
3062 py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3064 if (py_newdn == NULL)
3065 return LDB_ERR_OPERATIONS_ERROR;
3067 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3068 discard_const_p(char, "OO"),
3069 py_olddn, py_newdn);
3071 Py_DECREF(py_olddn);
3072 Py_DECREF(py_newdn);
3074 if (py_result == NULL) {
3075 return LDB_ERR_PYTHON_EXCEPTION;
3078 Py_DECREF(py_result);
3080 return LDB_SUCCESS;
3083 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3085 PyObject *py_ldb = (PyObject *)mod->private_data;
3086 PyObject *py_result;
3088 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3089 discard_const_p(char, ""));
3091 return LDB_ERR_OPERATIONS_ERROR;
3094 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3096 PyObject *py_ldb = (PyObject *)mod->private_data;
3097 PyObject *py_result;
3099 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3100 discard_const_p(char, ""));
3102 return LDB_ERR_OPERATIONS_ERROR;
3105 static int py_module_start_transaction(struct ldb_module *mod)
3107 PyObject *py_ldb = (PyObject *)mod->private_data;
3108 PyObject *py_result;
3110 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3111 discard_const_p(char, ""));
3113 if (py_result == NULL) {
3114 return LDB_ERR_PYTHON_EXCEPTION;
3117 Py_DECREF(py_result);
3119 return LDB_SUCCESS;
3122 static int py_module_end_transaction(struct ldb_module *mod)
3124 PyObject *py_ldb = (PyObject *)mod->private_data;
3125 PyObject *py_result;
3127 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3128 discard_const_p(char, ""));
3130 if (py_result == NULL) {
3131 return LDB_ERR_PYTHON_EXCEPTION;
3134 Py_DECREF(py_result);
3136 return LDB_SUCCESS;
3139 static int py_module_del_transaction(struct ldb_module *mod)
3141 PyObject *py_ldb = (PyObject *)mod->private_data;
3142 PyObject *py_result;
3144 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3145 discard_const_p(char, ""));
3147 if (py_result == NULL) {
3148 return LDB_ERR_PYTHON_EXCEPTION;
3151 Py_DECREF(py_result);
3153 return LDB_SUCCESS;
3156 static int py_module_destructor(struct ldb_module *mod)
3158 Py_DECREF((PyObject *)mod->private_data);
3159 return 0;
3162 static int py_module_init(struct ldb_module *mod)
3164 PyObject *py_class = (PyObject *)mod->ops->private_data;
3165 PyObject *py_result, *py_next, *py_ldb;
3167 py_ldb = PyLdb_FromLdbContext(mod->ldb);
3169 if (py_ldb == NULL)
3170 return LDB_ERR_OPERATIONS_ERROR;
3172 py_next = PyLdbModule_FromModule(mod->next);
3174 if (py_next == NULL)
3175 return LDB_ERR_OPERATIONS_ERROR;
3177 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3178 py_ldb, py_next);
3180 if (py_result == NULL) {
3181 return LDB_ERR_PYTHON_EXCEPTION;
3184 mod->private_data = py_result;
3186 talloc_set_destructor(mod, py_module_destructor);
3188 return ldb_next_init(mod);
3191 static PyObject *py_register_module(PyObject *module, PyObject *args)
3193 int ret;
3194 struct ldb_module_ops *ops;
3195 PyObject *input;
3197 if (!PyArg_ParseTuple(args, "O", &input))
3198 return NULL;
3200 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3201 if (ops == NULL) {
3202 PyErr_NoMemory();
3203 return NULL;
3206 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3208 Py_INCREF(input);
3209 ops->private_data = input;
3210 ops->init_context = py_module_init;
3211 ops->search = py_module_search;
3212 ops->add = py_module_add;
3213 ops->modify = py_module_modify;
3214 ops->del = py_module_del;
3215 ops->rename = py_module_rename;
3216 ops->request = py_module_request;
3217 ops->extended = py_module_extended;
3218 ops->start_transaction = py_module_start_transaction;
3219 ops->end_transaction = py_module_end_transaction;
3220 ops->del_transaction = py_module_del_transaction;
3222 ret = ldb_register_module(ops);
3224 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3226 Py_RETURN_NONE;
3229 static PyObject *py_timestring(PyObject *module, PyObject *args)
3231 /* most times "time_t" is a signed integer type with 32 or 64 bit:
3232 * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3233 long int t_val;
3234 char *tresult;
3235 PyObject *ret;
3236 if (!PyArg_ParseTuple(args, "l", &t_val))
3237 return NULL;
3238 tresult = ldb_timestring(NULL, (time_t) t_val);
3239 ret = PyString_FromString(tresult);
3240 talloc_free(tresult);
3241 return ret;
3244 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3246 char *str;
3247 if (!PyArg_ParseTuple(args, "s", &str))
3248 return NULL;
3250 return PyInt_FromLong(ldb_string_to_time(str));
3253 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3255 char *name;
3256 if (!PyArg_ParseTuple(args, "s", &name))
3257 return NULL;
3258 return PyBool_FromLong(ldb_valid_attr_name(name));
3262 encode a string using RFC2254 rules
3264 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3266 char *str, *encoded;
3267 int size = 0;
3268 struct ldb_val val;
3269 PyObject *ret;
3271 if (!PyArg_ParseTuple(args, "s#", &str, &size))
3272 return NULL;
3273 val.data = (uint8_t *)str;
3274 val.length = size;
3276 encoded = ldb_binary_encode(NULL, val);
3277 if (encoded == NULL) {
3278 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3279 return NULL;
3281 ret = PyString_FromString(encoded);
3282 talloc_free(encoded);
3283 return ret;
3287 decode a string using RFC2254 rules
3289 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3291 char *str;
3292 struct ldb_val val;
3293 PyObject *ret;
3295 if (!PyArg_ParseTuple(args, "s", &str))
3296 return NULL;
3298 val = ldb_binary_decode(NULL, str);
3299 if (val.data == NULL) {
3300 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3301 return NULL;
3303 ret = Py_BuildValue("s#", val.data, val.length);
3304 talloc_free(val.data);
3305 return ret;
3308 static PyMethodDef py_ldb_global_methods[] = {
3309 { "register_module", py_register_module, METH_VARARGS,
3310 "S.register_module(module) -> None\n\n"
3311 "Register a LDB module."},
3312 { "timestring", py_timestring, METH_VARARGS,
3313 "S.timestring(int) -> string\n\n"
3314 "Generate a LDAP time string from a UNIX timestamp" },
3315 { "string_to_time", py_string_to_time, METH_VARARGS,
3316 "S.string_to_time(string) -> int\n\n"
3317 "Parse a LDAP time string into a UNIX timestamp." },
3318 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3319 "S.valid_attr_name(name) -> bool\n\nn"
3320 "Check whether the supplied name is a valid attribute name." },
3321 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3322 "S.open() -> Ldb\n\n"
3323 "Open a new LDB context." },
3324 { "binary_encode", py_binary_encode, METH_VARARGS,
3325 "S.binary_encode(string) -> string\n\n"
3326 "Perform a RFC2254 binary encoding on a string" },
3327 { "binary_decode", py_binary_decode, METH_VARARGS,
3328 "S.binary_decode(string) -> string\n\n"
3329 "Perform a RFC2254 binary decode on a string" },
3330 { NULL }
3333 void initldb(void)
3335 PyObject *m;
3337 if (PyType_Ready(&PyLdbDn) < 0)
3338 return;
3340 if (PyType_Ready(&PyLdbMessage) < 0)
3341 return;
3343 if (PyType_Ready(&PyLdbMessageElement) < 0)
3344 return;
3346 if (PyType_Ready(&PyLdb) < 0)
3347 return;
3349 if (PyType_Ready(&PyLdbModule) < 0)
3350 return;
3352 if (PyType_Ready(&PyLdbTree) < 0)
3353 return;
3355 if (PyType_Ready(&PyLdbResult) < 0)
3356 return;
3358 if (PyType_Ready(&PyLdbControl) < 0)
3359 return;
3361 m = Py_InitModule3("ldb", py_ldb_global_methods,
3362 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3363 if (m == NULL)
3364 return;
3366 PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3367 PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3368 PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3369 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3370 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3371 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3372 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3374 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3375 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3376 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3377 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3379 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3380 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3381 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3383 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3384 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3385 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3386 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3387 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3388 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3389 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3390 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3391 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3392 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3393 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3394 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3395 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3396 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3397 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3398 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3399 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3400 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3401 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3402 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3403 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3404 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3405 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3406 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3407 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3408 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3409 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3410 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3411 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3412 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3413 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3414 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3415 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3416 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3417 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3418 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3419 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3420 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3421 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3423 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3424 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3425 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3426 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3428 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3430 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3431 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3433 Py_INCREF(&PyLdb);
3434 Py_INCREF(&PyLdbDn);
3435 Py_INCREF(&PyLdbModule);
3436 Py_INCREF(&PyLdbMessage);
3437 Py_INCREF(&PyLdbMessageElement);
3438 Py_INCREF(&PyLdbTree);
3439 Py_INCREF(&PyLdbResult);
3440 Py_INCREF(&PyLdbControl);
3442 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3443 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3444 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3445 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3446 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3447 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3448 PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3450 PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3452 #define ADD_LDB_STRING(val) PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3454 ADD_LDB_STRING(SYNTAX_DN);
3455 ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3456 ADD_LDB_STRING(SYNTAX_INTEGER);
3457 ADD_LDB_STRING(SYNTAX_BOOLEAN);
3458 ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3459 ADD_LDB_STRING(SYNTAX_UTC_TIME);
3460 ADD_LDB_STRING(OID_COMPARATOR_AND);
3461 ADD_LDB_STRING(OID_COMPARATOR_OR);