pyldb: Fix memory leak in Dn.concat.
[Samba.git] / source4 / lib / ldb / pyldb.c
blob0f666a35f339967fc91b599f409dcc7a3cec6db7
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-2009 Jelmer Vernooij <jelmer@samba.org>
10 ** NOTE! The following LGPL license applies to the ldb
11 ** library. This does NOT imply that all of Samba is released
12 ** under the LGPL
14 This library is free software; you can redistribute it and/or
15 modify it under the terms of the GNU Lesser General Public
16 License as published by the Free Software Foundation; either
17 version 3 of the License, or (at your option) any later version.
19 This library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Lesser General Public License for more details.
24 You should have received a copy of the GNU Lesser General Public
25 License along with this library; if not, see <http://www.gnu.org/licenses/>.
28 #include "replace.h"
29 #include "ldb_private.h"
30 #include <Python.h>
31 #include "pyldb.h"
33 /* There's no Py_ssize_t in 2.4, apparently */
34 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
35 typedef int Py_ssize_t;
36 typedef inquiry lenfunc;
37 typedef intargfunc ssizeargfunc;
38 #endif
40 #ifndef Py_RETURN_NONE
41 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
42 #endif
44 static PyObject *PyExc_LdbError;
46 PyAPI_DATA(PyTypeObject) PyLdbMessage;
47 PyAPI_DATA(PyTypeObject) PyLdbModule;
48 PyAPI_DATA(PyTypeObject) PyLdbDn;
49 PyAPI_DATA(PyTypeObject) PyLdb;
50 PyAPI_DATA(PyTypeObject) PyLdbMessageElement;
51 PyAPI_DATA(PyTypeObject) PyLdbTree;
53 static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx,
54 struct ldb_message_element *el,
55 struct ldb_val *val)
57 struct ldb_val new_val;
58 TALLOC_CTX *mem_ctx = talloc_new(NULL);
59 PyObject *ret;
61 new_val = *val;
63 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
65 talloc_free(mem_ctx);
67 return ret;
70 /**
71 * Obtain a ldb DN from a Python object.
73 * @param mem_ctx Memory context
74 * @param object Python object
75 * @param ldb_ctx LDB context
76 * @return Whether or not the conversion succeeded
78 bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object,
79 struct ldb_context *ldb_ctx, struct ldb_dn **dn)
81 struct ldb_dn *odn;
83 if (ldb_ctx != NULL && PyString_Check(object)) {
84 odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
85 *dn = odn;
86 return true;
89 if (PyLdbDn_Check(object)) {
90 *dn = PyLdbDn_AsDn(object);
91 return true;
94 PyErr_SetString(PyExc_TypeError, "Expected DN");
95 return false;
98 /**
99 * Create a Python object from a ldb_result.
101 * @param result LDB result to convert
102 * @return Python object with converted result (a list object)
104 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
106 PyObject *ret;
107 int i;
108 if (result == NULL) {
109 Py_RETURN_NONE;
111 ret = PyList_New(result->count);
112 for (i = 0; i < result->count; i++) {
113 PyList_SetItem(ret, i, PyLdbMessage_FromMessage(result->msgs[i])
116 return ret;
120 * Create a LDB Result from a Python object.
121 * If conversion fails, NULL will be returned and a Python exception set.
123 * @param mem_ctx Memory context in which to allocate the LDB Result
124 * @param obj Python object to convert
125 * @return a ldb_result, or NULL if the conversion failed
127 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
128 PyObject *obj)
130 struct ldb_result *res;
131 int i;
133 if (obj == Py_None)
134 return NULL;
136 res = talloc_zero(mem_ctx, struct ldb_result);
137 res->count = PyList_Size(obj);
138 res->msgs = talloc_array(res, struct ldb_message *, res->count);
139 for (i = 0; i < res->count; i++) {
140 PyObject *item = PyList_GetItem(obj, i);
141 res->msgs[i] = PyLdbMessage_AsMessage(item);
143 return res;
146 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
148 return PyBool_FromLong(ldb_dn_validate(self->dn));
151 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
153 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
156 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
158 return PyBool_FromLong(ldb_dn_is_special(self->dn));
161 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
163 return PyBool_FromLong(ldb_dn_is_null(self->dn));
166 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
168 return PyString_FromString(ldb_dn_get_casefold(self->dn));
171 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
173 return PyString_FromString(ldb_dn_get_linearized(self->dn));
176 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
178 return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
181 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
183 return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
186 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
188 return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
191 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
193 char *name;
195 if (!PyArg_ParseTuple(args, "s", &name))
196 return NULL;
198 return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
201 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
203 return ldb_dn_compare(dn1->dn, dn2->dn);
206 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
208 struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self);
209 struct ldb_dn *parent;
211 parent = ldb_dn_get_parent(NULL, dn);
213 return PyLdbDn_FromDn(parent);
216 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
218 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
220 PyObject *py_other;
221 struct ldb_dn *dn, *other;
222 if (!PyArg_ParseTuple(args, "O", &py_other))
223 return NULL;
225 dn = PyLdbDn_AsDn((PyObject *)self);
227 if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
228 return NULL;
230 return ldb_dn_add_child(dn, other)?Py_True:Py_False;
233 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
235 PyObject *py_other;
236 struct ldb_dn *other, *dn;
237 if (!PyArg_ParseTuple(args, "O", &py_other))
238 return NULL;
240 dn = PyLdbDn_AsDn((PyObject *)self);
242 if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
243 return NULL;
245 return ldb_dn_add_base(dn, other)?Py_True:Py_False;
248 static PyMethodDef py_ldb_dn_methods[] = {
249 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
250 "S.validate() -> bool\n"
251 "Validate DN is correct." },
252 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
253 "S.is_valid() -> bool\n" },
254 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
255 "S.is_special() -> bool\n"
256 "Check whether this is a special LDB DN." },
257 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
258 "Check whether this is a null DN." },
259 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
260 NULL },
261 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
262 NULL },
263 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
264 "S.canonical_str() -> string\n"
265 "Canonical version of this DN (like a posix path)." },
266 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
267 "S.canonical_ex_str() -> string\n"
268 "Canonical version of this DN (like a posix path, with terminating newline)." },
269 { "check_special", (PyCFunction)py_ldb_dn_is_special, METH_VARARGS,
270 NULL },
271 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
272 "S.parent() -> dn\n"
273 "Get the parent for this DN." },
274 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
275 "S.add_child(dn) -> None\n"
276 "Add a child DN to this DN." },
277 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
278 "S.add_base(dn) -> None\n"
279 "Add a base DN to this DN." },
280 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
281 NULL },
282 { NULL }
285 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
287 return ldb_dn_get_comp_num(PyLdbDn_AsDn((PyObject *)self));
290 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
292 struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self),
293 *other;
294 PyLdbDnObject *py_ret;
296 if (!PyObject_AsDn(NULL, py_other, NULL, &other))
297 return NULL;
299 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
300 if (py_ret == NULL) {
301 PyErr_NoMemory();
302 return NULL;
304 py_ret->mem_ctx = talloc_new(NULL);
305 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
306 ldb_dn_add_child(py_ret->dn, other);
307 return (PyObject *)py_ret;
310 static PySequenceMethods py_ldb_dn_seq = {
311 .sq_length = (lenfunc)py_ldb_dn_len,
312 .sq_concat = (binaryfunc)py_ldb_dn_concat,
315 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
317 struct ldb_dn *ret;
318 char *str;
319 PyObject *py_ldb;
320 struct ldb_context *ldb_ctx;
321 TALLOC_CTX *mem_ctx;
322 PyLdbDnObject *py_ret;
323 const char * const kwnames[] = { "ldb", "dn", NULL };
325 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
326 discard_const_p(char *, kwnames),
327 &py_ldb, &str))
328 return NULL;
330 ldb_ctx = PyLdb_AsLdbContext(py_ldb);
332 mem_ctx = talloc_new(NULL);
333 if (mem_ctx == NULL) {
334 PyErr_NoMemory();
335 return NULL;
338 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
340 if (ret == NULL || !ldb_dn_validate(ret)) {
341 talloc_free(mem_ctx);
342 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
343 return NULL;
346 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
347 if (ret == NULL) {
348 talloc_free(mem_ctx);
349 PyErr_NoMemory();
350 return NULL;
352 py_ret->mem_ctx = mem_ctx;
353 py_ret->dn = ret;
354 return (PyObject *)py_ret;
357 PyObject *PyLdbDn_FromDn(struct ldb_dn *dn)
359 PyLdbDnObject *py_ret;
361 if (dn == NULL) {
362 Py_RETURN_NONE;
365 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
366 if (py_ret == NULL) {
367 PyErr_NoMemory();
368 return NULL;
370 py_ret->mem_ctx = talloc_new(NULL);
371 py_ret->dn = talloc_reference(py_ret->mem_ctx, dn);
372 return (PyObject *)py_ret;
375 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
377 talloc_free(self->mem_ctx);
378 self->ob_type->tp_free(self);
381 PyTypeObject PyLdbDn = {
382 .tp_name = "Dn",
383 .tp_methods = py_ldb_dn_methods,
384 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
385 .tp_repr = (reprfunc)py_ldb_dn_repr,
386 .tp_compare = (cmpfunc)py_ldb_dn_compare,
387 .tp_as_sequence = &py_ldb_dn_seq,
388 .tp_doc = "A LDB distinguished name.",
389 .tp_new = py_ldb_dn_new,
390 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
391 .tp_basicsize = sizeof(PyLdbObject),
392 .tp_flags = Py_TPFLAGS_DEFAULT,
395 /* Debug */
396 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
397 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
399 PyObject *fn = (PyObject *)context;
400 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
403 static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args)
405 PyObject *cb;
407 if (!PyArg_ParseTuple(args, "O", &cb))
408 return NULL;
410 Py_INCREF(cb);
411 /* FIXME: Where do we DECREF cb ? */
412 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), PyLdb_AsLdbContext(self));
414 Py_RETURN_NONE;
417 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
419 unsigned int perms;
420 if (!PyArg_ParseTuple(args, "I", &perms))
421 return NULL;
423 ldb_set_create_perms(PyLdb_AsLdbContext(self), perms);
425 Py_RETURN_NONE;
428 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
430 char *modules_dir;
431 if (!PyArg_ParseTuple(args, "s", &modules_dir))
432 return NULL;
434 ldb_set_modules_dir(PyLdb_AsLdbContext(self), modules_dir);
436 Py_RETURN_NONE;
439 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
441 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_start(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
442 Py_RETURN_NONE;
445 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
447 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
448 Py_RETURN_NONE;
451 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
453 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_cancel(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
454 Py_RETURN_NONE;
457 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
459 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_setup_wellknown_attributes(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
460 Py_RETURN_NONE;
463 static PyObject *py_ldb_repr(PyLdbObject *self)
465 return PyString_FromFormat("<ldb connection>");
468 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
470 struct ldb_dn *dn = ldb_get_root_basedn(PyLdb_AsLdbContext(self));
471 if (dn == NULL)
472 Py_RETURN_NONE;
473 return PyLdbDn_FromDn(dn);
477 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
479 struct ldb_dn *dn = ldb_get_schema_basedn(PyLdb_AsLdbContext(self));
480 if (dn == NULL)
481 Py_RETURN_NONE;
482 return PyLdbDn_FromDn(dn);
485 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
487 struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self));
488 if (dn == NULL)
489 Py_RETURN_NONE;
490 return PyLdbDn_FromDn(dn);
493 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
495 struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self));
496 if (dn == NULL)
497 Py_RETURN_NONE;
498 return PyLdbDn_FromDn(dn);
501 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
502 const char *paramname)
504 const char **ret;
505 int i;
506 if (!PyList_Check(list)) {
507 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
508 return NULL;
510 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
511 for (i = 0; i < PyList_Size(list); i++) {
512 PyObject *item = PyList_GetItem(list, i);
513 if (!PyString_Check(item)) {
514 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
515 return NULL;
517 ret[i] = PyString_AsString(item);
519 ret[i] = NULL;
520 return ret;
523 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
525 const char * const kwnames[] = { "url", "flags", "options", NULL };
526 char *url = NULL;
527 PyObject *py_options = Py_None;
528 const char **options;
529 int flags = 0;
530 int ret;
531 struct ldb_context *ldb;
533 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO:Ldb.__init__",
534 discard_const_p(char *, kwnames),
535 &url, &flags, &py_options))
536 return -1;
538 ldb = PyLdb_AsLdbContext(self);
540 if (py_options == Py_None) {
541 options = NULL;
542 } else {
543 options = PyList_AsStringList(ldb, py_options, "options");
544 if (options == NULL)
545 return -1;
548 if (url != NULL) {
549 ret = ldb_connect(ldb, url, flags, options);
550 if (ret != LDB_SUCCESS) {
551 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
552 return -1;
556 talloc_free(options);
557 return 0;
560 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
562 PyLdbObject *ret;
563 struct ldb_context *ldb;
564 ldb = ldb_init(NULL, NULL);
565 if (ldb == NULL) {
566 PyErr_NoMemory();
567 return NULL;
570 ret = (PyLdbObject *)type->tp_alloc(type, 0);
571 if (ret == NULL) {
572 PyErr_NoMemory();
573 return NULL;
575 ret->ldb_ctx = ldb;
576 return (PyObject *)ret;
579 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
581 char *url;
582 int flags = 0;
583 PyObject *py_options = Py_None;
584 int ret;
585 const char **options;
586 const char * const kwnames[] = { "url", "flags", "options", NULL };
588 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iO",
589 discard_const_p(char *, kwnames),
590 &url, &flags, &py_options))
591 return NULL;
593 if (py_options == Py_None) {
594 options = NULL;
595 } else {
596 options = PyList_AsStringList(NULL, py_options, "options");
597 if (options == NULL)
598 return NULL;
601 ret = ldb_connect(PyLdb_AsLdbContext(self), url, flags, options);
602 talloc_free(options);
604 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
606 Py_RETURN_NONE;
609 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args)
611 PyObject *py_msg;
612 int ret;
613 if (!PyArg_ParseTuple(args, "O", &py_msg))
614 return NULL;
616 if (!PyLdbMessage_Check(py_msg)) {
617 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
618 return NULL;
621 ret = ldb_modify(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg));
622 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
624 Py_RETURN_NONE;
627 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
629 PyObject *py_msg;
630 int ret;
631 Py_ssize_t dict_pos, msg_pos;
632 struct ldb_message_element *msgel;
633 struct ldb_message *msg;
634 PyObject *key, *value;
636 if (!PyArg_ParseTuple(args, "O", &py_msg))
637 return NULL;
639 if (PyDict_Check(py_msg)) {
640 PyObject *dn_value = PyDict_GetItemString(py_msg, "dn");
641 msg = ldb_msg_new(NULL);
642 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg));
643 msg_pos = dict_pos = 0;
644 if (dn_value) {
645 if (!PyObject_AsDn(msg, dn_value, PyLdb_AsLdbContext(self), &msg->dn)) {
646 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
647 return NULL;
649 if (msg->dn == NULL) {
650 PyErr_SetString(PyExc_TypeError, "dn set but not found");
651 return NULL;
655 while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
656 char *key_str = PyString_AsString(key);
657 if (strcmp(key_str, "dn") != 0) {
658 msgel = PyObject_AsMessageElement(msg->elements, value, 0, key_str);
659 if (msgel == NULL) {
660 PyErr_SetString(PyExc_TypeError, "unable to import element");
661 return NULL;
663 memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
664 msg_pos++;
668 if (msg->dn == NULL) {
669 PyErr_SetString(PyExc_TypeError, "no dn set");
670 return NULL;
673 msg->num_elements = msg_pos;
674 } else {
675 msg = PyLdbMessage_AsMessage(py_msg);
678 ret = ldb_add(PyLdb_AsLdbContext(self), msg);
679 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
681 Py_RETURN_NONE;
684 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args)
686 PyObject *py_dn;
687 struct ldb_dn *dn;
688 int ret;
689 struct ldb_context *ldb;
690 if (!PyArg_ParseTuple(args, "O", &py_dn))
691 return NULL;
693 ldb = PyLdb_AsLdbContext(self);
695 if (!PyObject_AsDn(NULL, py_dn, ldb, &dn))
696 return NULL;
698 ret = ldb_delete(ldb, dn);
699 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
701 Py_RETURN_NONE;
704 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args)
706 PyObject *py_dn1, *py_dn2;
707 struct ldb_dn *dn1, *dn2;
708 int ret;
709 struct ldb_context *ldb;
710 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
711 return NULL;
713 ldb = PyLdb_AsLdbContext(self);
714 if (!PyObject_AsDn(NULL, py_dn1, ldb, &dn1))
715 return NULL;
717 if (!PyObject_AsDn(NULL, py_dn2, ldb, &dn2))
718 return NULL;
720 ret = ldb_rename(ldb, dn1, dn2);
721 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
723 Py_RETURN_NONE;
726 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
728 char *name;
729 if (!PyArg_ParseTuple(args, "s", &name))
730 return NULL;
732 ldb_schema_attribute_remove(PyLdb_AsLdbContext(self), name);
734 Py_RETURN_NONE;
737 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
739 char *attribute, *syntax;
740 unsigned int flags;
741 int ret;
742 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
743 return NULL;
745 ret = ldb_schema_attribute_add(PyLdb_AsLdbContext(self), attribute, flags, syntax);
747 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
749 Py_RETURN_NONE;
752 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
754 if (ldif == NULL) {
755 Py_RETURN_NONE;
756 } else {
757 /* We don't want this attached to the 'ldb' any more */
758 talloc_steal(NULL, ldif);
759 return Py_BuildValue(discard_const_p(char, "(iO)"),
760 ldif->changetype,
761 PyLdbMessage_FromMessage(ldif->msg));
766 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
768 PyObject *list;
769 struct ldb_ldif *ldif;
770 const char *s;
772 if (!PyArg_ParseTuple(args, "s", &s))
773 return NULL;
775 list = PyList_New(0);
776 while ((ldif = ldb_ldif_read_string(self->ldb_ctx, &s)) != NULL) {
777 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
779 return PyObject_GetIter(list);
782 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
784 const struct ldb_schema_attribute *a;
785 struct ldb_val old_val;
786 struct ldb_val new_val;
787 TALLOC_CTX *mem_ctx;
788 PyObject *ret;
789 char *element_name;
790 PyObject *val;
792 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
793 return NULL;
795 mem_ctx = talloc_new(NULL);
797 old_val.data = (uint8_t *)PyString_AsString(val);
798 old_val.length = PyString_Size(val);
800 a = ldb_schema_attribute_by_name(PyLdb_AsLdbContext(self), element_name);
802 if (a == NULL) {
803 Py_RETURN_NONE;
806 if (a->syntax->ldif_write_fn(PyLdb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
807 talloc_free(mem_ctx);
808 Py_RETURN_NONE;
811 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
813 talloc_free(mem_ctx);
815 return ret;
818 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
820 PyObject *py_base = Py_None;
821 enum ldb_scope scope = LDB_SCOPE_DEFAULT;
822 char *expr = NULL;
823 PyObject *py_attrs = Py_None;
824 PyObject *py_controls = Py_None;
825 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
826 int ret;
827 struct ldb_result *res;
828 struct ldb_request *req;
829 const char **attrs;
830 struct ldb_context *ldb_ctx;
831 struct ldb_control **parsed_controls;
832 struct ldb_dn *base;
833 PyObject *py_ret;
835 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
836 discard_const_p(char *, kwnames),
837 &py_base, &scope, &expr, &py_attrs, &py_controls))
838 return NULL;
840 ldb_ctx = PyLdb_AsLdbContext(self);
842 if (py_attrs == Py_None) {
843 attrs = NULL;
844 } else {
845 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
846 if (attrs == NULL)
847 return NULL;
850 if (py_base == Py_None) {
851 base = ldb_get_default_basedn(ldb_ctx);
852 } else {
853 if (!PyObject_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
854 talloc_free(attrs);
855 return NULL;
859 if (py_controls == Py_None) {
860 parsed_controls = NULL;
861 } else {
862 const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
863 parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
864 talloc_free(controls);
867 res = talloc_zero(ldb_ctx, struct ldb_result);
868 if (res == NULL) {
869 PyErr_NoMemory();
870 talloc_free(attrs);
871 return NULL;
874 ret = ldb_build_search_req(&req, ldb_ctx, ldb_ctx,
875 base,
876 scope,
877 expr,
878 attrs,
879 parsed_controls,
880 res,
881 ldb_search_default_callback,
882 NULL);
884 talloc_steal(req, attrs);
886 if (ret != LDB_SUCCESS) {
887 talloc_free(res);
888 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
889 return NULL;
892 ret = ldb_request(ldb_ctx, req);
894 if (ret == LDB_SUCCESS) {
895 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
898 talloc_free(req);
900 if (ret != LDB_SUCCESS) {
901 talloc_free(res);
902 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
903 return NULL;
906 py_ret = PyLdbResult_FromResult(res);
908 talloc_free(res);
910 return py_ret;
913 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
915 char *name;
916 void *data;
918 if (!PyArg_ParseTuple(args, "s", &name))
919 return NULL;
921 data = ldb_get_opaque(PyLdb_AsLdbContext(self), name);
923 if (data == NULL)
924 Py_RETURN_NONE;
926 /* FIXME: More interpretation */
928 return Py_True;
931 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
933 char *name;
934 PyObject *data;
936 if (!PyArg_ParseTuple(args, "sO", &name, &data))
937 return NULL;
939 /* FIXME: More interpretation */
941 ldb_set_opaque(PyLdb_AsLdbContext(self), name, data);
943 Py_RETURN_NONE;
946 static PyObject *py_ldb_modules(PyLdbObject *self)
948 struct ldb_context *ldb = PyLdb_AsLdbContext(self);
949 PyObject *ret = PyList_New(0);
950 struct ldb_module *mod;
952 for (mod = ldb->modules; mod; mod = mod->next) {
953 PyList_Append(ret, PyLdbModule_FromModule(mod));
956 return ret;
959 static PyMethodDef py_ldb_methods[] = {
960 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
961 "S.set_debug(callback) -> None\n"
962 "Set callback for LDB debug messages.\n"
963 "The callback should accept a debug level and debug text." },
964 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
965 "S.set_create_perms(mode) -> None\n"
966 "Set mode to use when creating new LDB files." },
967 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
968 "S.set_modules_dir(path) -> None\n"
969 "Set path LDB should search for modules" },
970 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
971 "S.transaction_start() -> None\n"
972 "Start a new transaction." },
973 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
974 "S.transaction_commit() -> None\n"
975 "commit a new transaction." },
976 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
977 "S.transaction_cancel() -> None\n"
978 "cancel a new transaction." },
979 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
980 NULL },
981 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
982 NULL },
983 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
984 NULL },
985 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
986 NULL },
987 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
988 NULL },
989 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
990 "S.connect(url, flags=0, options=None) -> None\n"
991 "Connect to a LDB URL." },
992 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS,
993 "S.modify(message) -> None\n"
994 "Modify an entry." },
995 { "add", (PyCFunction)py_ldb_add, METH_VARARGS,
996 "S.add(message) -> None\n"
997 "Add an entry." },
998 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS,
999 "S.delete(dn) -> None\n"
1000 "Remove an entry." },
1001 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS,
1002 "S.rename(old_dn, new_dn) -> None\n"
1003 "Rename an entry." },
1004 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1005 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1006 "Search in a database.\n"
1007 "\n"
1008 ":param base: Optional base DN to search\n"
1009 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1010 ":param expression: Optional search expression\n"
1011 ":param attrs: Attributes to return (defaults to all)\n"
1012 ":param controls: Optional list of controls\n"
1013 ":return: Iterator over Message objects\n"
1015 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1016 NULL },
1017 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1018 NULL },
1019 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1020 NULL },
1021 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1022 "S.parse_ldif(ldif) -> iter(messages)\n"
1023 "Parse a string formatted using LDIF." },
1024 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1025 "S.get_opaque(name) -> value\n"
1026 "Get an opaque value set on this LDB connection. \n"
1027 ":note: The returned value may not be useful in Python."
1029 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1030 "S.set_opaque(name, value) -> None\n"
1031 "Set an opaque value on this LDB connection. \n"
1032 ":note: Passing incorrect values may cause crashes." },
1033 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1034 "S.modules() -> list\n"
1035 "Return the list of modules on this LDB connection " },
1036 { NULL },
1039 PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1041 PyLdbModuleObject *ret;
1043 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1044 if (ret == NULL) {
1045 PyErr_NoMemory();
1046 return NULL;
1048 ret->mem_ctx = talloc_new(NULL);
1049 ret->mod = talloc_reference(ret->mem_ctx, mod);
1050 return (PyObject *)ret;
1053 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1055 return PyLdbModule_FromModule(PyLdb_AsLdbContext(self)->modules);
1058 static PyGetSetDef py_ldb_getset[] = {
1059 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1060 { NULL }
1063 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1065 struct ldb_context *ldb_ctx = PyLdb_AsLdbContext(self);
1066 struct ldb_dn *dn;
1067 struct ldb_result *result;
1068 int ret;
1069 int count;
1071 if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn))
1072 return -1;
1074 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, NULL);
1075 if (ret != LDB_SUCCESS) {
1076 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1077 return -1;
1080 count = result->count;
1082 talloc_free(result);
1084 return count;
1087 static PySequenceMethods py_ldb_seq = {
1088 .sq_contains = (objobjproc)py_ldb_contains,
1091 PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1093 PyLdbObject *ret;
1095 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1096 if (ret == NULL) {
1097 PyErr_NoMemory();
1098 return NULL;
1100 ret->mem_ctx = talloc_new(NULL);
1101 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1102 return (PyObject *)ret;
1105 static void py_ldb_dealloc(PyLdbObject *self)
1107 talloc_free(self->mem_ctx);
1108 self->ob_type->tp_free(self);
1111 PyTypeObject PyLdb = {
1112 .tp_name = "Ldb",
1113 .tp_methods = py_ldb_methods,
1114 .tp_repr = (reprfunc)py_ldb_repr,
1115 .tp_new = py_ldb_new,
1116 .tp_init = (initproc)py_ldb_init,
1117 .tp_dealloc = (destructor)py_ldb_dealloc,
1118 .tp_getset = py_ldb_getset,
1119 .tp_getattro = PyObject_GenericGetAttr,
1120 .tp_basicsize = sizeof(PyLdbObject),
1121 .tp_doc = "Connection to a LDB database.",
1122 .tp_as_sequence = &py_ldb_seq,
1123 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1126 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1128 return PyString_FromFormat("<ldb module '%s'>", PyLdbModule_AsModule(self)->ops->name);
1131 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1133 return PyString_FromString(PyLdbModule_AsModule(self)->ops->name);
1136 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1138 PyLdbModule_AsModule(self)->ops->start_transaction(PyLdbModule_AsModule(self));
1139 Py_RETURN_NONE;
1142 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1144 PyLdbModule_AsModule(self)->ops->end_transaction(PyLdbModule_AsModule(self));
1145 Py_RETURN_NONE;
1148 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
1150 PyLdbModule_AsModule(self)->ops->del_transaction(PyLdbModule_AsModule(self));
1151 Py_RETURN_NONE;
1154 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
1156 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
1157 int ret, scope;
1158 struct ldb_request *req;
1159 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
1160 struct ldb_module *mod;
1161 const char * const*attrs;
1163 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
1164 discard_const_p(char *, kwnames),
1165 &py_base, &scope, &py_tree, &py_attrs))
1166 return NULL;
1168 mod = self->mod;
1170 if (py_attrs == Py_None) {
1171 attrs = NULL;
1172 } else {
1173 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
1174 if (attrs == NULL)
1175 return NULL;
1178 ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base),
1179 scope, NULL /* expr */, attrs,
1180 NULL /* controls */, NULL, NULL, NULL);
1182 talloc_steal(req, attrs);
1184 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1186 req->op.search.res = NULL;
1188 ret = mod->ops->search(mod, req);
1190 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1192 py_ret = PyLdbResult_FromResult(req->op.search.res);
1194 talloc_free(req);
1196 return py_ret;
1200 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
1202 struct ldb_request *req;
1203 PyObject *py_message;
1204 int ret;
1205 struct ldb_module *mod;
1207 if (!PyArg_ParseTuple(args, "O", &py_message))
1208 return NULL;
1210 req = talloc_zero(NULL, struct ldb_request);
1211 req->operation = LDB_ADD;
1212 req->op.add.message = PyLdbMessage_AsMessage(py_message);
1214 mod = PyLdbModule_AsModule(self);
1215 ret = mod->ops->add(mod, req);
1217 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1219 Py_RETURN_NONE;
1222 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
1224 int ret;
1225 struct ldb_request *req;
1226 PyObject *py_message;
1227 struct ldb_module *mod;
1229 if (!PyArg_ParseTuple(args, "O", &py_message))
1230 return NULL;
1232 req = talloc_zero(NULL, struct ldb_request);
1233 req->operation = LDB_MODIFY;
1234 req->op.mod.message = PyLdbMessage_AsMessage(py_message);
1236 mod = PyLdbModule_AsModule(self);
1237 ret = mod->ops->modify(mod, req);
1239 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1241 Py_RETURN_NONE;
1244 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
1246 int ret;
1247 struct ldb_request *req;
1248 PyObject *py_dn;
1250 if (!PyArg_ParseTuple(args, "O", &py_dn))
1251 return NULL;
1253 req = talloc_zero(NULL, struct ldb_request);
1254 req->operation = LDB_DELETE;
1255 req->op.del.dn = PyLdbDn_AsDn(py_dn);
1257 ret = PyLdbModule_AsModule(self)->ops->del(PyLdbModule_AsModule(self), req);
1259 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1261 Py_RETURN_NONE;
1264 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
1266 int ret;
1267 struct ldb_request *req;
1268 PyObject *py_dn1, *py_dn2;
1270 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
1271 return NULL;
1273 req = talloc_zero(NULL, struct ldb_request);
1275 req->operation = LDB_RENAME;
1276 req->op.rename.olddn = PyLdbDn_AsDn(py_dn1);
1277 req->op.rename.newdn = PyLdbDn_AsDn(py_dn2);
1279 ret = PyLdbModule_AsModule(self)->ops->rename(PyLdbModule_AsModule(self), req);
1281 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1283 Py_RETURN_NONE;
1286 static PyMethodDef py_ldb_module_methods[] = {
1287 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
1288 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
1289 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
1290 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
1291 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
1292 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
1293 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
1294 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
1295 { NULL },
1298 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
1300 talloc_free(self->mem_ctx);
1301 self->ob_type->tp_free(self);
1304 PyTypeObject PyLdbModule = {
1305 .tp_name = "LdbModule",
1306 .tp_methods = py_ldb_module_methods,
1307 .tp_repr = (reprfunc)py_ldb_module_repr,
1308 .tp_str = (reprfunc)py_ldb_module_str,
1309 .tp_basicsize = sizeof(PyLdbModuleObject),
1310 .tp_dealloc = (destructor)py_ldb_module_dealloc,
1311 .tp_flags = Py_TPFLAGS_DEFAULT,
1316 * Create a ldb_message_element from a Python object.
1318 * This will accept any sequence objects that contains strings, or
1319 * a string object.
1321 * A reference to set_obj will be borrowed.
1323 * @param mem_ctx Memory context
1324 * @param set_obj Python object to convert
1325 * @param flags ldb_message_element flags to set
1326 * @param attr_name Name of the attribute
1327 * @return New ldb_message_element, allocated as child of mem_ctx
1329 struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
1330 PyObject *set_obj, int flags,
1331 const char *attr_name)
1333 struct ldb_message_element *me;
1335 if (PyLdbMessageElement_Check(set_obj))
1336 return PyLdbMessageElement_AsMessageElement(set_obj);
1338 me = talloc(mem_ctx, struct ldb_message_element);
1340 me->name = attr_name;
1341 me->flags = flags;
1342 if (PyString_Check(set_obj)) {
1343 me->num_values = 1;
1344 me->values = talloc_array(me, struct ldb_val, me->num_values);
1345 me->values[0].length = PyString_Size(set_obj);
1346 me->values[0].data = (uint8_t *)PyString_AsString(set_obj);
1347 } else if (PySequence_Check(set_obj)) {
1348 int i;
1349 me->num_values = PySequence_Size(set_obj);
1350 me->values = talloc_array(me, struct ldb_val, me->num_values);
1351 for (i = 0; i < me->num_values; i++) {
1352 PyObject *obj = PySequence_GetItem(set_obj, i);
1354 me->values[i].length = PyString_Size(obj);
1355 me->values[i].data = (uint8_t *)PyString_AsString(obj);
1357 } else {
1358 talloc_free(me);
1359 me = NULL;
1362 return me;
1366 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
1367 struct ldb_message_element *me)
1369 int i;
1370 PyObject *result;
1372 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
1373 result = PyList_New(me->num_values);
1375 for (i = 0; i < me->num_values; i++) {
1376 PyList_SetItem(result, i,
1377 PyObject_FromLdbValue(ldb_ctx, me, &me->values[i]));
1380 return result;
1383 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
1385 int i;
1386 if (!PyArg_ParseTuple(args, "i", &i))
1387 return NULL;
1388 if (i < 0 || i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
1389 Py_RETURN_NONE;
1391 return PyObject_FromLdbValue(NULL, PyLdbMessageElement_AsMessageElement(self),
1392 &(PyLdbMessageElement_AsMessageElement(self)->values[i]));
1395 static PyMethodDef py_ldb_msg_element_methods[] = {
1396 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
1397 { NULL },
1400 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
1402 return PyLdbMessageElement_AsMessageElement(self)->num_values;
1405 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
1407 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1408 if (idx < 0 || idx >= el->num_values) {
1409 PyErr_SetString(PyExc_IndexError, "Out of range");
1410 return NULL;
1412 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
1415 static PySequenceMethods py_ldb_msg_element_seq = {
1416 .sq_length = (lenfunc)py_ldb_msg_element_len,
1417 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
1420 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
1422 return ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self),
1423 PyLdbMessageElement_AsMessageElement(other));
1426 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
1428 return PyObject_GetIter(ldb_msg_element_to_set(NULL, PyLdbMessageElement_AsMessageElement(self)));
1431 PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
1433 PyLdbMessageElementObject *ret;
1434 ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
1435 if (ret == NULL) {
1436 PyErr_NoMemory();
1437 return NULL;
1439 ret->mem_ctx = talloc_new(NULL);
1440 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
1441 PyErr_NoMemory();
1442 return NULL;
1444 ret->el = el;
1445 return (PyObject *)ret;
1448 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1450 PyObject *py_elements = NULL;
1451 struct ldb_message_element *el;
1452 int flags = 0;
1453 char *name = NULL;
1454 const char * const kwnames[] = { "elements", "flags", "name", NULL };
1455 PyLdbMessageElementObject *ret;
1457 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Ois",
1458 discard_const_p(char *, kwnames),
1459 &py_elements, &flags, &name))
1460 return NULL;
1462 el = talloc_zero(NULL, struct ldb_message_element);
1464 if (py_elements != NULL) {
1465 int i;
1466 if (PyString_Check(py_elements)) {
1467 el->num_values = 1;
1468 el->values = talloc_array(el, struct ldb_val, 1);
1469 el->values[0].data = (uint8_t *)PyString_AsString(py_elements);
1470 el->values[0].length = PyString_Size(py_elements);
1471 } else if (PySequence_Check(py_elements)) {
1472 el->num_values = PySequence_Size(py_elements);
1473 el->values = talloc_array(el, struct ldb_val, el->num_values);
1474 for (i = 0; i < el->num_values; i++) {
1475 PyObject *item = PySequence_GetItem(py_elements, i);
1476 el->values[i].data = (uint8_t *)PyString_AsString(item);
1477 el->values[i].length = PyString_Size(item);
1479 } else {
1480 PyErr_SetString(PyExc_TypeError,
1481 "Expected string or list");
1482 talloc_free(el);
1483 return NULL;
1487 el->flags = flags;
1488 el->name = talloc_strdup(el, name);
1490 ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
1491 if (ret == NULL) {
1492 PyErr_NoMemory();
1493 talloc_free(el);
1494 return NULL;
1497 ret->mem_ctx = talloc_new(NULL);
1498 ret->el = talloc_reference(ret->mem_ctx, el);
1499 return (PyObject *)ret;
1502 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
1504 char *element_str = NULL;
1505 int i;
1506 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1507 PyObject *ret;
1509 for (i = 0; i < el->num_values; i++) {
1510 PyObject *o = py_ldb_msg_element_find(self, i);
1511 if (element_str == NULL)
1512 element_str = talloc_strdup(NULL, PyObject_REPR(o));
1513 else
1514 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
1517 ret = PyString_FromFormat("MessageElement([%s])", element_str);
1519 talloc_free(element_str);
1521 return ret;
1524 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
1526 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1528 if (el->num_values == 1)
1529 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
1530 else
1531 Py_RETURN_NONE;
1534 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
1536 talloc_free(self->mem_ctx);
1537 self->ob_type->tp_free(self);
1540 PyTypeObject PyLdbMessageElement = {
1541 .tp_name = "MessageElement",
1542 .tp_basicsize = sizeof(PyLdbMessageElementObject),
1543 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
1544 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
1545 .tp_str = (reprfunc)py_ldb_msg_element_str,
1546 .tp_methods = py_ldb_msg_element_methods,
1547 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
1548 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
1549 .tp_as_sequence = &py_ldb_msg_element_seq,
1550 .tp_new = py_ldb_msg_element_new,
1551 .tp_flags = Py_TPFLAGS_DEFAULT,
1554 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
1556 char *name;
1557 if (!PyArg_ParseTuple(args, "s", &name))
1558 return NULL;
1560 ldb_msg_remove_attr(self->msg, name);
1562 Py_RETURN_NONE;
1565 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
1567 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1568 int i, j = 0;
1569 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
1570 if (msg->dn != NULL) {
1571 PyList_SetItem(obj, j, PyString_FromString("dn"));
1572 j++;
1574 for (i = 0; i < msg->num_elements; i++) {
1575 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
1576 j++;
1578 return obj;
1581 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
1583 struct ldb_message_element *el;
1584 char *name = PyString_AsString(py_name);
1585 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1586 if (!strcmp(name, "dn"))
1587 return PyLdbDn_FromDn(msg->dn);
1588 el = ldb_msg_find_element(msg, name);
1589 if (el == NULL) {
1590 return NULL;
1592 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg);
1595 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
1597 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
1598 if (ret == NULL) {
1599 PyErr_SetString(PyExc_KeyError, "No such element");
1600 return NULL;
1602 return ret;
1605 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args)
1607 PyObject *name, *ret;
1608 if (!PyArg_ParseTuple(args, "O", &name))
1609 return NULL;
1611 ret = py_ldb_msg_getitem_helper(self, name);
1612 if (ret == NULL)
1613 Py_RETURN_NONE;
1614 return ret;
1617 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
1619 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1620 int i, j;
1621 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
1622 j = 0;
1623 if (msg->dn != NULL) {
1624 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn)));
1625 j++;
1627 for (i = 0; i < msg->num_elements; i++, j++) {
1628 PyList_SetItem(l, j, Py_BuildValue("(sO)", msg->elements[i].name, PyLdbMessageElement_FromMessageElement(&msg->elements[i], self->msg)));
1630 return l;
1633 static PyMethodDef py_ldb_msg_methods[] = {
1634 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, NULL },
1635 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, NULL },
1636 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL },
1637 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
1638 { NULL },
1641 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
1643 PyObject *list, *iter;
1645 list = py_ldb_msg_keys(self);
1646 iter = PyObject_GetIter(list);
1647 Py_DECREF(list);
1648 return iter;
1651 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
1653 char *attr_name = PyString_AsString(name);
1654 if (value == NULL) {
1655 ldb_msg_remove_attr(self->msg, attr_name);
1656 } else {
1657 struct ldb_message_element *el = PyObject_AsMessageElement(NULL,
1658 value, 0, attr_name);
1659 if (el == NULL)
1660 return -1;
1661 talloc_steal(self->msg, el);
1662 ldb_msg_remove_attr(PyLdbMessage_AsMessage(self), attr_name);
1663 ldb_msg_add(PyLdbMessage_AsMessage(self), el, el->flags);
1665 return 0;
1668 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
1670 return PyLdbMessage_AsMessage(self)->num_elements;
1673 static PyMappingMethods py_ldb_msg_mapping = {
1674 .mp_length = (lenfunc)py_ldb_msg_length,
1675 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
1676 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
1679 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1681 const char * const kwnames[] = { "dn", NULL };
1682 struct ldb_message *ret;
1683 PyObject *pydn = NULL;
1684 PyLdbMessageObject *py_ret;
1686 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
1687 discard_const_p(char *, kwnames),
1688 &pydn))
1689 return NULL;
1691 ret = ldb_msg_new(NULL);
1692 if (ret == NULL) {
1693 PyErr_NoMemory();
1694 return NULL;
1697 if (pydn != NULL) {
1698 struct ldb_dn *dn;
1699 if (!PyObject_AsDn(NULL, pydn, NULL, &dn)) {
1700 talloc_free(ret);
1701 return NULL;
1703 ret->dn = talloc_reference(ret, dn);
1706 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
1707 if (py_ret == NULL) {
1708 PyErr_NoMemory();
1709 talloc_free(ret);
1710 return NULL;
1713 py_ret->mem_ctx = talloc_new(NULL);
1714 py_ret->msg = talloc_steal(py_ret->mem_ctx, ret);
1715 return (PyObject *)py_ret;
1718 PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
1720 PyLdbMessageObject *ret;
1722 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
1723 if (ret == NULL) {
1724 PyErr_NoMemory();
1725 return NULL;
1727 ret->mem_ctx = talloc_new(NULL);
1728 ret->msg = talloc_reference(ret->mem_ctx, msg);
1729 return (PyObject *)ret;
1732 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
1734 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1735 return PyLdbDn_FromDn(msg->dn);
1738 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
1740 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1741 msg->dn = talloc_reference(msg, PyLdbDn_AsDn(value));
1742 return 0;
1745 static PyGetSetDef py_ldb_msg_getset[] = {
1746 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
1747 { NULL }
1750 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
1752 PyObject *dict = PyDict_New(), *ret;
1753 if (PyDict_Update(dict, (PyObject *)self) != 0)
1754 return NULL;
1755 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
1756 Py_DECREF(dict);
1757 return ret;
1760 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
1762 talloc_free(self->mem_ctx);
1763 self->ob_type->tp_free(self);
1766 PyTypeObject PyLdbMessage = {
1767 .tp_name = "Message",
1768 .tp_methods = py_ldb_msg_methods,
1769 .tp_getset = py_ldb_msg_getset,
1770 .tp_as_mapping = &py_ldb_msg_mapping,
1771 .tp_basicsize = sizeof(PyLdbMessageObject),
1772 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
1773 .tp_new = py_ldb_msg_new,
1774 .tp_repr = (reprfunc)py_ldb_msg_repr,
1775 .tp_flags = Py_TPFLAGS_DEFAULT,
1776 .tp_iter = (getiterfunc)py_ldb_msg_iter,
1779 PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
1781 PyLdbTreeObject *ret;
1783 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
1784 if (ret == NULL) {
1785 PyErr_NoMemory();
1786 return NULL;
1789 ret->mem_ctx = talloc_new(NULL);
1790 ret->tree = talloc_reference(ret->mem_ctx, tree);
1791 return (PyObject *)ret;
1794 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
1796 talloc_free(self->mem_ctx);
1797 self->ob_type->tp_free(self);
1800 PyTypeObject PyLdbTree = {
1801 .tp_name = "Tree",
1802 .tp_basicsize = sizeof(PyLdbTreeObject),
1803 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
1804 .tp_flags = Py_TPFLAGS_DEFAULT,
1807 /* Ldb_module */
1808 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
1810 PyObject *py_ldb = (PyObject *)mod->private_data;
1811 PyObject *py_result, *py_base, *py_attrs, *py_tree;
1813 py_base = PyLdbDn_FromDn(req->op.search.base);
1815 if (py_base == NULL)
1816 return LDB_ERR_OPERATIONS_ERROR;
1818 py_tree = PyLdbTree_FromTree(req->op.search.tree);
1820 if (py_tree == NULL)
1821 return LDB_ERR_OPERATIONS_ERROR;
1823 if (req->op.search.attrs == NULL) {
1824 py_attrs = Py_None;
1825 } else {
1826 int i, len;
1827 for (len = 0; req->op.search.attrs[len]; len++);
1828 py_attrs = PyList_New(len);
1829 for (i = 0; i < len; i++)
1830 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
1833 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
1834 discard_const_p(char, "OiOO"),
1835 py_base, req->op.search.scope, py_tree, py_attrs);
1837 Py_DECREF(py_attrs);
1838 Py_DECREF(py_tree);
1839 Py_DECREF(py_base);
1841 if (py_result == NULL) {
1842 return LDB_ERR_PYTHON_EXCEPTION;
1845 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
1846 if (req->op.search.res == NULL) {
1847 return LDB_ERR_PYTHON_EXCEPTION;
1850 Py_DECREF(py_result);
1852 return LDB_SUCCESS;
1855 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
1857 PyObject *py_ldb = (PyObject *)mod->private_data;
1858 PyObject *py_result, *py_msg;
1860 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
1862 if (py_msg == NULL) {
1863 return LDB_ERR_OPERATIONS_ERROR;
1866 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
1867 discard_const_p(char, "O"),
1868 py_msg);
1870 Py_DECREF(py_msg);
1872 if (py_result == NULL) {
1873 return LDB_ERR_PYTHON_EXCEPTION;
1876 Py_DECREF(py_result);
1878 return LDB_SUCCESS;
1881 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
1883 PyObject *py_ldb = (PyObject *)mod->private_data;
1884 PyObject *py_result, *py_msg;
1886 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
1888 if (py_msg == NULL) {
1889 return LDB_ERR_OPERATIONS_ERROR;
1892 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
1893 discard_const_p(char, "O"),
1894 py_msg);
1896 Py_DECREF(py_msg);
1898 if (py_result == NULL) {
1899 return LDB_ERR_PYTHON_EXCEPTION;
1902 Py_DECREF(py_result);
1904 return LDB_SUCCESS;
1907 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
1909 PyObject *py_ldb = (PyObject *)mod->private_data;
1910 PyObject *py_result, *py_dn;
1912 py_dn = PyLdbDn_FromDn(req->op.del.dn);
1914 if (py_dn == NULL)
1915 return LDB_ERR_OPERATIONS_ERROR;
1917 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
1918 discard_const_p(char, "O"),
1919 py_dn);
1921 if (py_result == NULL) {
1922 return LDB_ERR_PYTHON_EXCEPTION;
1925 Py_DECREF(py_result);
1927 return LDB_SUCCESS;
1930 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
1932 PyObject *py_ldb = (PyObject *)mod->private_data;
1933 PyObject *py_result, *py_olddn, *py_newdn;
1935 py_olddn = PyLdbDn_FromDn(req->op.rename.olddn);
1937 if (py_olddn == NULL)
1938 return LDB_ERR_OPERATIONS_ERROR;
1940 py_newdn = PyLdbDn_FromDn(req->op.rename.newdn);
1942 if (py_newdn == NULL)
1943 return LDB_ERR_OPERATIONS_ERROR;
1945 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
1946 discard_const_p(char, "OO"),
1947 py_olddn, py_newdn);
1949 Py_DECREF(py_olddn);
1950 Py_DECREF(py_newdn);
1952 if (py_result == NULL) {
1953 return LDB_ERR_PYTHON_EXCEPTION;
1956 Py_DECREF(py_result);
1958 return LDB_SUCCESS;
1961 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
1963 PyObject *py_ldb = (PyObject *)mod->private_data;
1964 PyObject *py_result;
1966 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
1967 discard_const_p(char, ""));
1969 return LDB_ERR_OPERATIONS_ERROR;
1972 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
1974 PyObject *py_ldb = (PyObject *)mod->private_data;
1975 PyObject *py_result;
1977 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
1978 discard_const_p(char, ""));
1980 return LDB_ERR_OPERATIONS_ERROR;
1983 static int py_module_start_transaction(struct ldb_module *mod)
1985 PyObject *py_ldb = (PyObject *)mod->private_data;
1986 PyObject *py_result;
1988 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
1989 discard_const_p(char, ""));
1991 if (py_result == NULL) {
1992 return LDB_ERR_PYTHON_EXCEPTION;
1995 Py_DECREF(py_result);
1997 return LDB_SUCCESS;
2000 static int py_module_end_transaction(struct ldb_module *mod)
2002 PyObject *py_ldb = (PyObject *)mod->private_data;
2003 PyObject *py_result;
2005 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
2006 discard_const_p(char, ""));
2008 if (py_result == NULL) {
2009 return LDB_ERR_PYTHON_EXCEPTION;
2012 Py_DECREF(py_result);
2014 return LDB_SUCCESS;
2017 static int py_module_del_transaction(struct ldb_module *mod)
2019 PyObject *py_ldb = (PyObject *)mod->private_data;
2020 PyObject *py_result;
2022 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
2023 discard_const_p(char, ""));
2025 if (py_result == NULL) {
2026 return LDB_ERR_PYTHON_EXCEPTION;
2029 Py_DECREF(py_result);
2031 return LDB_SUCCESS;
2034 static int py_module_destructor(struct ldb_module *mod)
2036 Py_DECREF((PyObject *)mod->private_data);
2037 return 0;
2040 static int py_module_init(struct ldb_module *mod)
2042 PyObject *py_class = (PyObject *)mod->ops->private_data;
2043 PyObject *py_result, *py_next, *py_ldb;
2045 py_ldb = PyLdb_FromLdbContext(mod->ldb);
2047 if (py_ldb == NULL)
2048 return LDB_ERR_OPERATIONS_ERROR;
2050 py_next = PyLdbModule_FromModule(mod->next);
2052 if (py_next == NULL)
2053 return LDB_ERR_OPERATIONS_ERROR;
2055 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
2056 py_ldb, py_next);
2058 if (py_result == NULL) {
2059 return LDB_ERR_PYTHON_EXCEPTION;
2062 mod->private_data = py_result;
2064 talloc_set_destructor(mod, py_module_destructor);
2066 return ldb_next_init(mod);
2069 static PyObject *py_register_module(PyObject *module, PyObject *args)
2071 int ret;
2072 struct ldb_module_ops *ops;
2073 PyObject *input;
2075 if (!PyArg_ParseTuple(args, "O", &input))
2076 return NULL;
2078 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
2079 if (ops == NULL) {
2080 PyErr_NoMemory();
2081 return NULL;
2084 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
2086 Py_INCREF(input);
2087 ops->private_data = input;
2088 ops->init_context = py_module_init;
2089 ops->search = py_module_search;
2090 ops->add = py_module_add;
2091 ops->modify = py_module_modify;
2092 ops->del = py_module_del;
2093 ops->rename = py_module_rename;
2094 ops->request = py_module_request;
2095 ops->extended = py_module_extended;
2096 ops->start_transaction = py_module_start_transaction;
2097 ops->end_transaction = py_module_end_transaction;
2098 ops->del_transaction = py_module_del_transaction;
2100 ret = ldb_register_module(ops);
2102 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2104 Py_RETURN_NONE;
2107 static PyObject *py_timestring(PyObject *module, PyObject *args)
2109 time_t t;
2110 char *tresult;
2111 PyObject *ret;
2112 if (!PyArg_ParseTuple(args, "L", &t))
2113 return NULL;
2114 tresult = ldb_timestring(NULL, t);
2115 ret = PyString_FromString(tresult);
2116 talloc_free(tresult);
2117 return ret;
2120 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
2122 char *str;
2123 if (!PyArg_ParseTuple(args, "s", &str))
2124 return NULL;
2126 return PyInt_FromLong(ldb_string_to_time(str));
2129 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
2131 char *name;
2132 if (!PyArg_ParseTuple(args, "s", &name))
2133 return NULL;
2134 return PyBool_FromLong(ldb_valid_attr_name(name));
2137 static PyMethodDef py_ldb_global_methods[] = {
2138 { "register_module", py_register_module, METH_VARARGS,
2139 "S.register_module(module) -> None\n"
2140 "Register a LDB module."},
2141 { "timestring", py_timestring, METH_VARARGS,
2142 "S.timestring(int) -> string\n"
2143 "Generate a LDAP time string from a UNIX timestamp" },
2144 { "string_to_time", py_string_to_time, METH_VARARGS,
2145 "S.string_to_time(string) -> int\n"
2146 "Parse a LDAP time string into a UNIX timestamp." },
2147 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
2148 "S.valid_attr_name(name) -> bool\n"
2149 "Check whether the supplied name is a valid attribute name." },
2150 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
2151 NULL },
2152 { NULL }
2155 void initldb(void)
2157 PyObject *m;
2159 if (PyType_Ready(&PyLdbDn) < 0)
2160 return;
2162 if (PyType_Ready(&PyLdbMessage) < 0)
2163 return;
2165 if (PyType_Ready(&PyLdbMessageElement) < 0)
2166 return;
2168 if (PyType_Ready(&PyLdb) < 0)
2169 return;
2171 if (PyType_Ready(&PyLdbModule) < 0)
2172 return;
2174 if (PyType_Ready(&PyLdbTree) < 0)
2175 return;
2177 m = Py_InitModule3("ldb", py_ldb_global_methods,
2178 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
2179 if (m == NULL)
2180 return;
2182 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
2183 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
2184 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
2185 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
2187 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
2188 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
2189 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
2190 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
2192 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
2193 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
2194 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
2195 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
2196 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
2197 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
2198 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
2199 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
2200 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
2201 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
2202 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
2203 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
2204 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
2205 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
2206 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
2207 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
2208 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
2209 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
2210 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
2211 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
2212 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
2213 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
2214 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
2215 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
2216 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
2217 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
2218 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
2219 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
2220 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
2221 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
2222 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
2223 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
2224 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
2225 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
2226 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
2227 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
2228 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
2229 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
2231 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
2233 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
2235 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
2236 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
2238 Py_INCREF(&PyLdb);
2239 Py_INCREF(&PyLdbDn);
2240 Py_INCREF(&PyLdbModule);
2241 Py_INCREF(&PyLdbMessage);
2242 Py_INCREF(&PyLdbMessageElement);
2243 Py_INCREF(&PyLdbTree);
2245 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
2246 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
2247 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
2248 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
2249 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
2250 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);