s4:ldb python bindings: Handle the parameters of the connect call in the right way
[Samba/aatanasov.git] / source4 / lib / ldb / pyldb.c
blob5825f8853077848dd37f1d6c3c89eb6b6da92e32
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>
9 Copyright (C) 2009 Matthias Dieter Wallnöfer
11 ** NOTE! The following LGPL license applies to the ldb
12 ** library. This does NOT imply that all of Samba is released
13 ** under the LGPL
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 3 of the License, or (at your option) any later version.
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Lesser General Public License for more details.
25 You should have received a copy of the GNU Lesser General Public
26 License along with this library; if not, see <http://www.gnu.org/licenses/>.
29 #include "replace.h"
30 #include "ldb_private.h"
31 #include <Python.h>
32 #include "pyldb.h"
34 /* There's no Py_ssize_t in 2.4, apparently */
35 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
36 typedef int Py_ssize_t;
37 typedef inquiry lenfunc;
38 typedef intargfunc ssizeargfunc;
39 #endif
41 #ifndef Py_RETURN_NONE
42 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
43 #endif
45 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
47 if (ret == LDB_ERR_PYTHON_EXCEPTION)
48 return; /* Python exception should already be set, just keep that */
50 PyErr_SetObject(error,
51 Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
52 ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
55 static PyObject *PyExc_LdbError;
57 PyAPI_DATA(PyTypeObject) PyLdbMessage;
58 PyAPI_DATA(PyTypeObject) PyLdbModule;
59 PyAPI_DATA(PyTypeObject) PyLdbDn;
60 PyAPI_DATA(PyTypeObject) PyLdb;
61 PyAPI_DATA(PyTypeObject) PyLdbMessageElement;
62 PyAPI_DATA(PyTypeObject) PyLdbTree;
64 static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx,
65 struct ldb_message_element *el,
66 struct ldb_val *val)
68 struct ldb_val new_val;
69 TALLOC_CTX *mem_ctx = talloc_new(NULL);
70 PyObject *ret;
72 new_val = *val;
74 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
76 talloc_free(mem_ctx);
78 return ret;
81 /**
82 * Obtain a ldb DN from a Python object.
84 * @param mem_ctx Memory context
85 * @param object Python object
86 * @param ldb_ctx LDB context
87 * @return Whether or not the conversion succeeded
89 bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object,
90 struct ldb_context *ldb_ctx, struct ldb_dn **dn)
92 struct ldb_dn *odn;
94 if (ldb_ctx != NULL && PyString_Check(object)) {
95 odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
96 *dn = odn;
97 return true;
100 if (PyLdbDn_Check(object)) {
101 *dn = PyLdbDn_AsDn(object);
102 return true;
105 PyErr_SetString(PyExc_TypeError, "Expected DN");
106 return false;
110 * Create a Python object from a ldb_result.
112 * @param result LDB result to convert
113 * @return Python object with converted result (a list object)
115 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
117 PyObject *ret;
118 int i;
119 if (result == NULL) {
120 Py_RETURN_NONE;
122 ret = PyList_New(result->count);
123 for (i = 0; i < result->count; i++) {
124 PyList_SetItem(ret, i, PyLdbMessage_FromMessage(result->msgs[i])
127 return ret;
131 * Create a LDB Result from a Python object.
132 * If conversion fails, NULL will be returned and a Python exception set.
134 * @param mem_ctx Memory context in which to allocate the LDB Result
135 * @param obj Python object to convert
136 * @return a ldb_result, or NULL if the conversion failed
138 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
139 PyObject *obj)
141 struct ldb_result *res;
142 int i;
144 if (obj == Py_None)
145 return NULL;
147 res = talloc_zero(mem_ctx, struct ldb_result);
148 res->count = PyList_Size(obj);
149 res->msgs = talloc_array(res, struct ldb_message *, res->count);
150 for (i = 0; i < res->count; i++) {
151 PyObject *item = PyList_GetItem(obj, i);
152 res->msgs[i] = PyLdbMessage_AsMessage(item);
154 return res;
157 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
159 return PyBool_FromLong(ldb_dn_validate(self->dn));
162 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
164 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
167 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
169 return PyBool_FromLong(ldb_dn_is_special(self->dn));
172 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
174 return PyBool_FromLong(ldb_dn_is_null(self->dn));
177 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
179 return PyString_FromString(ldb_dn_get_casefold(self->dn));
182 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
184 return PyString_FromString(ldb_dn_get_linearized(self->dn));
187 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
189 return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
192 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
194 return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
197 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
199 return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
202 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
204 char *name;
206 if (!PyArg_ParseTuple(args, "s", &name))
207 return NULL;
209 return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
212 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
214 return ldb_dn_compare(dn1->dn, dn2->dn);
217 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
219 struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self);
220 struct ldb_dn *parent;
221 PyLdbDnObject *py_ret;
222 TALLOC_CTX *mem_ctx = talloc_new(NULL);
224 parent = ldb_dn_get_parent(mem_ctx, dn);
225 if (parent == NULL) {
226 talloc_free(mem_ctx);
227 Py_RETURN_NONE;
230 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
231 if (py_ret == NULL) {
232 PyErr_NoMemory();
233 talloc_free(mem_ctx);
234 return NULL;
236 py_ret->mem_ctx = mem_ctx;
237 py_ret->dn = parent;
238 return (PyObject *)py_ret;
241 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
243 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
245 PyObject *py_other;
246 struct ldb_dn *dn, *other;
247 if (!PyArg_ParseTuple(args, "O", &py_other))
248 return NULL;
250 dn = PyLdbDn_AsDn((PyObject *)self);
252 if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
253 return NULL;
255 return ldb_dn_add_child(dn, other)?Py_True:Py_False;
258 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
260 PyObject *py_other;
261 struct ldb_dn *other, *dn;
262 if (!PyArg_ParseTuple(args, "O", &py_other))
263 return NULL;
265 dn = PyLdbDn_AsDn((PyObject *)self);
267 if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
268 return NULL;
270 return ldb_dn_add_base(dn, other)?Py_True:Py_False;
273 static PyMethodDef py_ldb_dn_methods[] = {
274 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
275 "S.validate() -> bool\n"
276 "Validate DN is correct." },
277 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
278 "S.is_valid() -> bool\n" },
279 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
280 "S.is_special() -> bool\n"
281 "Check whether this is a special LDB DN." },
282 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
283 "Check whether this is a null DN." },
284 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
285 NULL },
286 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
287 NULL },
288 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
289 "S.canonical_str() -> string\n"
290 "Canonical version of this DN (like a posix path)." },
291 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
292 "S.canonical_ex_str() -> string\n"
293 "Canonical version of this DN (like a posix path, with terminating newline)." },
294 { "check_special", (PyCFunction)py_ldb_dn_is_special, METH_VARARGS,
295 NULL },
296 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
297 "S.parent() -> dn\n"
298 "Get the parent for this DN." },
299 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
300 "S.add_child(dn) -> None\n"
301 "Add a child DN to this DN." },
302 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
303 "S.add_base(dn) -> None\n"
304 "Add a base DN to this DN." },
305 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
306 NULL },
307 { NULL }
310 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
312 return ldb_dn_get_comp_num(PyLdbDn_AsDn((PyObject *)self));
315 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
317 struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self),
318 *other;
319 PyLdbDnObject *py_ret;
321 if (!PyObject_AsDn(NULL, py_other, NULL, &other))
322 return NULL;
324 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
325 if (py_ret == NULL) {
326 PyErr_NoMemory();
327 return NULL;
329 py_ret->mem_ctx = talloc_new(NULL);
330 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
331 ldb_dn_add_child(py_ret->dn, other);
332 return (PyObject *)py_ret;
335 static PySequenceMethods py_ldb_dn_seq = {
336 .sq_length = (lenfunc)py_ldb_dn_len,
337 .sq_concat = (binaryfunc)py_ldb_dn_concat,
340 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
342 struct ldb_dn *ret;
343 char *str;
344 PyObject *py_ldb;
345 struct ldb_context *ldb_ctx;
346 TALLOC_CTX *mem_ctx;
347 PyLdbDnObject *py_ret;
348 const char * const kwnames[] = { "ldb", "dn", NULL };
350 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
351 discard_const_p(char *, kwnames),
352 &py_ldb, &str))
353 return NULL;
355 ldb_ctx = PyLdb_AsLdbContext(py_ldb);
357 mem_ctx = talloc_new(NULL);
358 if (mem_ctx == NULL) {
359 PyErr_NoMemory();
360 return NULL;
363 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
365 if (ret == NULL || !ldb_dn_validate(ret)) {
366 talloc_free(mem_ctx);
367 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
368 return NULL;
371 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
372 if (ret == NULL) {
373 talloc_free(mem_ctx);
374 PyErr_NoMemory();
375 return NULL;
377 py_ret->mem_ctx = mem_ctx;
378 py_ret->dn = ret;
379 return (PyObject *)py_ret;
382 PyObject *PyLdbDn_FromDn(struct ldb_dn *dn)
384 PyLdbDnObject *py_ret;
386 if (dn == NULL) {
387 Py_RETURN_NONE;
390 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
391 if (py_ret == NULL) {
392 PyErr_NoMemory();
393 return NULL;
395 py_ret->mem_ctx = talloc_new(NULL);
396 py_ret->dn = talloc_reference(py_ret->mem_ctx, dn);
397 return (PyObject *)py_ret;
400 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
402 talloc_free(self->mem_ctx);
403 self->ob_type->tp_free(self);
406 PyTypeObject PyLdbDn = {
407 .tp_name = "Dn",
408 .tp_methods = py_ldb_dn_methods,
409 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
410 .tp_repr = (reprfunc)py_ldb_dn_repr,
411 .tp_compare = (cmpfunc)py_ldb_dn_compare,
412 .tp_as_sequence = &py_ldb_dn_seq,
413 .tp_doc = "A LDB distinguished name.",
414 .tp_new = py_ldb_dn_new,
415 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
416 .tp_basicsize = sizeof(PyLdbObject),
417 .tp_flags = Py_TPFLAGS_DEFAULT,
420 /* Debug */
421 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
422 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
424 PyObject *fn = (PyObject *)context;
425 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
428 static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args)
430 PyObject *cb;
432 if (!PyArg_ParseTuple(args, "O", &cb))
433 return NULL;
435 Py_INCREF(cb);
436 /* FIXME: Where do we DECREF cb ? */
437 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), PyLdb_AsLdbContext(self));
439 Py_RETURN_NONE;
442 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
444 unsigned int perms;
445 if (!PyArg_ParseTuple(args, "I", &perms))
446 return NULL;
448 ldb_set_create_perms(PyLdb_AsLdbContext(self), perms);
450 Py_RETURN_NONE;
453 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
455 char *modules_dir;
456 if (!PyArg_ParseTuple(args, "s", &modules_dir))
457 return NULL;
459 ldb_set_modules_dir(PyLdb_AsLdbContext(self), modules_dir);
461 Py_RETURN_NONE;
464 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
466 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_start(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
467 Py_RETURN_NONE;
470 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
472 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
473 Py_RETURN_NONE;
476 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
478 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_cancel(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
479 Py_RETURN_NONE;
482 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
484 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_setup_wellknown_attributes(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
485 Py_RETURN_NONE;
488 static PyObject *py_ldb_repr(PyLdbObject *self)
490 return PyString_FromFormat("<ldb connection>");
493 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
495 struct ldb_dn *dn = ldb_get_root_basedn(PyLdb_AsLdbContext(self));
496 if (dn == NULL)
497 Py_RETURN_NONE;
498 return PyLdbDn_FromDn(dn);
502 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
504 struct ldb_dn *dn = ldb_get_schema_basedn(PyLdb_AsLdbContext(self));
505 if (dn == NULL)
506 Py_RETURN_NONE;
507 return PyLdbDn_FromDn(dn);
510 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
512 struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self));
513 if (dn == NULL)
514 Py_RETURN_NONE;
515 return PyLdbDn_FromDn(dn);
518 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
520 struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self));
521 if (dn == NULL)
522 Py_RETURN_NONE;
523 return PyLdbDn_FromDn(dn);
526 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
527 const char *paramname)
529 const char **ret;
530 int i;
531 if (!PyList_Check(list)) {
532 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
533 return NULL;
535 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
536 for (i = 0; i < PyList_Size(list); i++) {
537 PyObject *item = PyList_GetItem(list, i);
538 if (!PyString_Check(item)) {
539 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
540 return NULL;
542 ret[i] = talloc_strndup(ret, PyString_AsString(item),
543 PyString_Size(item));
545 ret[i] = NULL;
546 return ret;
549 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
551 const char * const kwnames[] = { "url", "flags", "options", NULL };
552 char *url = NULL;
553 PyObject *py_options = Py_None;
554 const char **options;
555 int flags = 0;
556 int ret;
557 struct ldb_context *ldb;
559 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO:Ldb.__init__",
560 discard_const_p(char *, kwnames),
561 &url, &flags, &py_options))
562 return -1;
564 ldb = PyLdb_AsLdbContext(self);
566 if (py_options == Py_None) {
567 options = NULL;
568 } else {
569 options = PyList_AsStringList(ldb, py_options, "options");
570 if (options == NULL)
571 return -1;
574 if (url != NULL) {
575 ret = ldb_connect(ldb, url, flags, options);
576 if (ret != LDB_SUCCESS) {
577 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
578 return -1;
582 talloc_free(options);
583 return 0;
586 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
588 PyLdbObject *ret;
589 struct ldb_context *ldb;
590 ret = (PyLdbObject *)type->tp_alloc(type, 0);
591 if (ret == NULL) {
592 PyErr_NoMemory();
593 return NULL;
595 ret->mem_ctx = talloc_new(NULL);
596 ldb = ldb_init(ret->mem_ctx, NULL);
598 if (ldb == NULL) {
599 PyErr_NoMemory();
600 return NULL;
603 ret->ldb_ctx = ldb;
604 return (PyObject *)ret;
607 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
609 char *url;
610 int flags = 0;
611 PyObject *py_options = Py_None;
612 int ret;
613 const char **options;
614 const char * const kwnames[] = { "url", "flags", "options", NULL };
616 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO",
617 discard_const_p(char *, kwnames),
618 &url, &flags, &py_options))
619 return NULL;
621 if (py_options == Py_None) {
622 options = NULL;
623 } else {
624 options = PyList_AsStringList(NULL, py_options, "options");
625 if (options == NULL)
626 return NULL;
629 ret = ldb_connect(PyLdb_AsLdbContext(self), url, flags, options);
630 talloc_free(options);
632 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
634 Py_RETURN_NONE;
637 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args)
639 PyObject *py_msg;
640 int ret;
641 if (!PyArg_ParseTuple(args, "O", &py_msg))
642 return NULL;
644 if (!PyLdbMessage_Check(py_msg)) {
645 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
646 return NULL;
649 ret = ldb_modify(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg));
650 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
652 Py_RETURN_NONE;
655 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
657 PyObject *py_msg;
658 int ret;
659 Py_ssize_t dict_pos, msg_pos;
660 struct ldb_message_element *msgel;
661 struct ldb_message *msg;
662 PyObject *key, *value;
663 TALLOC_CTX *mem_ctx;
665 if (!PyArg_ParseTuple(args, "O", &py_msg))
666 return NULL;
668 mem_ctx = talloc_new(NULL);
670 if (PyDict_Check(py_msg)) {
671 PyObject *dn_value = PyDict_GetItemString(py_msg, "dn");
672 msg = ldb_msg_new(mem_ctx);
673 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg));
674 msg_pos = dict_pos = 0;
675 if (dn_value) {
676 if (!PyObject_AsDn(msg, dn_value, PyLdb_AsLdbContext(self), &msg->dn)) {
677 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
678 talloc_free(mem_ctx);
679 return NULL;
681 if (msg->dn == NULL) {
682 PyErr_SetString(PyExc_TypeError, "dn set but not found");
683 talloc_free(mem_ctx);
684 return NULL;
688 while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
689 char *key_str = PyString_AsString(key);
690 if (strcmp(key_str, "dn") != 0) {
691 msgel = PyObject_AsMessageElement(msg->elements, value, 0, key_str);
692 if (msgel == NULL) {
693 PyErr_SetString(PyExc_TypeError, "unable to import element");
694 talloc_free(mem_ctx);
695 return NULL;
697 memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
698 msg_pos++;
702 if (msg->dn == NULL) {
703 PyErr_SetString(PyExc_TypeError, "no dn set");
704 talloc_free(mem_ctx);
705 return NULL;
708 msg->num_elements = msg_pos;
709 } else {
710 msg = PyLdbMessage_AsMessage(py_msg);
713 ret = ldb_add(PyLdb_AsLdbContext(self), msg);
714 talloc_free(mem_ctx);
715 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
717 Py_RETURN_NONE;
720 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args)
722 PyObject *py_dn;
723 struct ldb_dn *dn;
724 int ret;
725 struct ldb_context *ldb;
726 if (!PyArg_ParseTuple(args, "O", &py_dn))
727 return NULL;
729 ldb = PyLdb_AsLdbContext(self);
731 if (!PyObject_AsDn(NULL, py_dn, ldb, &dn))
732 return NULL;
734 ret = ldb_delete(ldb, dn);
735 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
737 Py_RETURN_NONE;
740 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args)
742 PyObject *py_dn1, *py_dn2;
743 struct ldb_dn *dn1, *dn2;
744 int ret;
745 struct ldb_context *ldb;
746 TALLOC_CTX *mem_ctx;
747 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
748 return NULL;
750 mem_ctx = talloc_new(NULL);
751 if (mem_ctx == NULL) {
752 PyErr_NoMemory();
753 return NULL;
755 ldb = PyLdb_AsLdbContext(self);
756 if (!PyObject_AsDn(mem_ctx, py_dn1, ldb, &dn1)) {
757 talloc_free(mem_ctx);
758 return NULL;
761 if (!PyObject_AsDn(mem_ctx, py_dn2, ldb, &dn2)) {
762 talloc_free(mem_ctx);
763 return NULL;
766 ret = ldb_rename(ldb, dn1, dn2);
767 talloc_free(mem_ctx);
768 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
770 Py_RETURN_NONE;
773 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
775 char *name;
776 if (!PyArg_ParseTuple(args, "s", &name))
777 return NULL;
779 ldb_schema_attribute_remove(PyLdb_AsLdbContext(self), name);
781 Py_RETURN_NONE;
784 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
786 char *attribute, *syntax;
787 unsigned int flags;
788 int ret;
789 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
790 return NULL;
792 ret = ldb_schema_attribute_add(PyLdb_AsLdbContext(self), attribute, flags, syntax);
794 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
796 Py_RETURN_NONE;
799 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
801 if (ldif == NULL) {
802 Py_RETURN_NONE;
803 } else {
804 /* We don't want this attached to the 'ldb' any more */
805 return Py_BuildValue(discard_const_p(char, "(iO)"),
806 ldif->changetype,
807 PyLdbMessage_FromMessage(ldif->msg));
812 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
814 PyObject *list;
815 struct ldb_ldif *ldif;
816 const char *s;
818 TALLOC_CTX *mem_ctx;
820 if (!PyArg_ParseTuple(args, "s", &s))
821 return NULL;
823 mem_ctx = talloc_new(NULL);
824 if (!mem_ctx) {
825 Py_RETURN_NONE;
828 list = PyList_New(0);
829 while (s && *s != '\0') {
830 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
831 talloc_steal(mem_ctx, ldif);
832 if (ldif) {
833 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
834 } else {
835 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
836 talloc_free(mem_ctx);
837 return NULL;
840 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
841 return PyObject_GetIter(list);
844 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
846 const struct ldb_schema_attribute *a;
847 struct ldb_val old_val;
848 struct ldb_val new_val;
849 TALLOC_CTX *mem_ctx;
850 PyObject *ret;
851 char *element_name;
852 PyObject *val;
854 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
855 return NULL;
857 mem_ctx = talloc_new(NULL);
859 old_val.data = (uint8_t *)PyString_AsString(val);
860 old_val.length = PyString_Size(val);
862 a = ldb_schema_attribute_by_name(PyLdb_AsLdbContext(self), element_name);
864 if (a == NULL) {
865 Py_RETURN_NONE;
868 if (a->syntax->ldif_write_fn(PyLdb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
869 talloc_free(mem_ctx);
870 Py_RETURN_NONE;
873 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
875 talloc_free(mem_ctx);
877 return ret;
880 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
882 PyObject *py_base = Py_None;
883 enum ldb_scope scope = LDB_SCOPE_DEFAULT;
884 char *expr = NULL;
885 PyObject *py_attrs = Py_None;
886 PyObject *py_controls = Py_None;
887 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
888 int ret;
889 struct ldb_result *res;
890 struct ldb_request *req;
891 const char **attrs;
892 struct ldb_context *ldb_ctx;
893 struct ldb_control **parsed_controls;
894 struct ldb_dn *base;
895 PyObject *py_ret;
897 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
898 discard_const_p(char *, kwnames),
899 &py_base, &scope, &expr, &py_attrs, &py_controls))
900 return NULL;
902 ldb_ctx = PyLdb_AsLdbContext(self);
904 if (py_attrs == Py_None) {
905 attrs = NULL;
906 } else {
907 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
908 if (attrs == NULL)
909 return NULL;
912 if (py_base == Py_None) {
913 base = ldb_get_default_basedn(ldb_ctx);
914 } else {
915 if (!PyObject_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
916 talloc_free(attrs);
917 return NULL;
921 if (py_controls == Py_None) {
922 parsed_controls = NULL;
923 } else {
924 const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
925 parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
926 talloc_free(controls);
929 res = talloc_zero(ldb_ctx, struct ldb_result);
930 if (res == NULL) {
931 PyErr_NoMemory();
932 talloc_free(attrs);
933 return NULL;
936 ret = ldb_build_search_req(&req, ldb_ctx, ldb_ctx,
937 base,
938 scope,
939 expr,
940 attrs,
941 parsed_controls,
942 res,
943 ldb_search_default_callback,
944 NULL);
946 talloc_steal(req, attrs);
948 if (ret != LDB_SUCCESS) {
949 talloc_free(res);
950 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
951 return NULL;
954 ret = ldb_request(ldb_ctx, req);
956 if (ret == LDB_SUCCESS) {
957 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
960 talloc_free(req);
962 if (ret != LDB_SUCCESS) {
963 talloc_free(res);
964 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
965 return NULL;
968 py_ret = PyLdbResult_FromResult(res);
970 talloc_free(res);
972 return py_ret;
975 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
977 char *name;
978 void *data;
980 if (!PyArg_ParseTuple(args, "s", &name))
981 return NULL;
983 data = ldb_get_opaque(PyLdb_AsLdbContext(self), name);
985 if (data == NULL)
986 Py_RETURN_NONE;
988 /* FIXME: More interpretation */
990 return Py_True;
993 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
995 char *name;
996 PyObject *data;
998 if (!PyArg_ParseTuple(args, "sO", &name, &data))
999 return NULL;
1001 /* FIXME: More interpretation */
1003 ldb_set_opaque(PyLdb_AsLdbContext(self), name, data);
1005 Py_RETURN_NONE;
1008 static PyObject *py_ldb_modules(PyLdbObject *self)
1010 struct ldb_context *ldb = PyLdb_AsLdbContext(self);
1011 PyObject *ret = PyList_New(0);
1012 struct ldb_module *mod;
1014 for (mod = ldb->modules; mod; mod = mod->next) {
1015 PyList_Append(ret, PyLdbModule_FromModule(mod));
1018 return ret;
1021 static PyMethodDef py_ldb_methods[] = {
1022 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1023 "S.set_debug(callback) -> None\n"
1024 "Set callback for LDB debug messages.\n"
1025 "The callback should accept a debug level and debug text." },
1026 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1027 "S.set_create_perms(mode) -> None\n"
1028 "Set mode to use when creating new LDB files." },
1029 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1030 "S.set_modules_dir(path) -> None\n"
1031 "Set path LDB should search for modules" },
1032 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1033 "S.transaction_start() -> None\n"
1034 "Start a new transaction." },
1035 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1036 "S.transaction_commit() -> None\n"
1037 "commit a new transaction." },
1038 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1039 "S.transaction_cancel() -> None\n"
1040 "cancel a new transaction." },
1041 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1042 NULL },
1043 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1044 NULL },
1045 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1046 NULL },
1047 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1048 NULL },
1049 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1050 NULL },
1051 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1052 "S.connect(url, flags=0, options=None) -> None\n"
1053 "Connect to a LDB URL." },
1054 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS,
1055 "S.modify(message) -> None\n"
1056 "Modify an entry." },
1057 { "add", (PyCFunction)py_ldb_add, METH_VARARGS,
1058 "S.add(message) -> None\n"
1059 "Add an entry." },
1060 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS,
1061 "S.delete(dn) -> None\n"
1062 "Remove an entry." },
1063 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS,
1064 "S.rename(old_dn, new_dn) -> None\n"
1065 "Rename an entry." },
1066 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1067 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1068 "Search in a database.\n"
1069 "\n"
1070 ":param base: Optional base DN to search\n"
1071 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1072 ":param expression: Optional search expression\n"
1073 ":param attrs: Attributes to return (defaults to all)\n"
1074 ":param controls: Optional list of controls\n"
1075 ":return: Iterator over Message objects\n"
1077 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1078 NULL },
1079 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1080 NULL },
1081 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1082 NULL },
1083 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1084 "S.parse_ldif(ldif) -> iter(messages)\n"
1085 "Parse a string formatted using LDIF." },
1086 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1087 "S.get_opaque(name) -> value\n"
1088 "Get an opaque value set on this LDB connection. \n"
1089 ":note: The returned value may not be useful in Python."
1091 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1092 "S.set_opaque(name, value) -> None\n"
1093 "Set an opaque value on this LDB connection. \n"
1094 ":note: Passing incorrect values may cause crashes." },
1095 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1096 "S.modules() -> list\n"
1097 "Return the list of modules on this LDB connection " },
1098 { NULL },
1101 PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1103 PyLdbModuleObject *ret;
1105 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1106 if (ret == NULL) {
1107 PyErr_NoMemory();
1108 return NULL;
1110 ret->mem_ctx = talloc_new(NULL);
1111 ret->mod = talloc_reference(ret->mem_ctx, mod);
1112 return (PyObject *)ret;
1115 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1117 return PyLdbModule_FromModule(PyLdb_AsLdbContext(self)->modules);
1120 static PyGetSetDef py_ldb_getset[] = {
1121 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1122 { NULL }
1125 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1127 struct ldb_context *ldb_ctx = PyLdb_AsLdbContext(self);
1128 struct ldb_dn *dn;
1129 struct ldb_result *result;
1130 int ret;
1131 int count;
1133 if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn))
1134 return -1;
1136 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, NULL);
1137 if (ret != LDB_SUCCESS) {
1138 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1139 return -1;
1142 count = result->count;
1144 talloc_free(result);
1146 return count;
1149 static PySequenceMethods py_ldb_seq = {
1150 .sq_contains = (objobjproc)py_ldb_contains,
1153 PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1155 PyLdbObject *ret;
1157 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1158 if (ret == NULL) {
1159 PyErr_NoMemory();
1160 return NULL;
1162 ret->mem_ctx = talloc_new(NULL);
1163 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1164 return (PyObject *)ret;
1167 static void py_ldb_dealloc(PyLdbObject *self)
1169 talloc_free(self->mem_ctx);
1170 self->ob_type->tp_free(self);
1173 PyTypeObject PyLdb = {
1174 .tp_name = "Ldb",
1175 .tp_methods = py_ldb_methods,
1176 .tp_repr = (reprfunc)py_ldb_repr,
1177 .tp_new = py_ldb_new,
1178 .tp_init = (initproc)py_ldb_init,
1179 .tp_dealloc = (destructor)py_ldb_dealloc,
1180 .tp_getset = py_ldb_getset,
1181 .tp_getattro = PyObject_GenericGetAttr,
1182 .tp_basicsize = sizeof(PyLdbObject),
1183 .tp_doc = "Connection to a LDB database.",
1184 .tp_as_sequence = &py_ldb_seq,
1185 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1188 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1190 return PyString_FromFormat("<ldb module '%s'>", PyLdbModule_AsModule(self)->ops->name);
1193 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1195 return PyString_FromString(PyLdbModule_AsModule(self)->ops->name);
1198 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1200 PyLdbModule_AsModule(self)->ops->start_transaction(PyLdbModule_AsModule(self));
1201 Py_RETURN_NONE;
1204 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1206 PyLdbModule_AsModule(self)->ops->end_transaction(PyLdbModule_AsModule(self));
1207 Py_RETURN_NONE;
1210 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
1212 PyLdbModule_AsModule(self)->ops->del_transaction(PyLdbModule_AsModule(self));
1213 Py_RETURN_NONE;
1216 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
1218 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
1219 int ret, scope;
1220 struct ldb_request *req;
1221 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
1222 struct ldb_module *mod;
1223 const char * const*attrs;
1225 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
1226 discard_const_p(char *, kwnames),
1227 &py_base, &scope, &py_tree, &py_attrs))
1228 return NULL;
1230 mod = self->mod;
1232 if (py_attrs == Py_None) {
1233 attrs = NULL;
1234 } else {
1235 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
1236 if (attrs == NULL)
1237 return NULL;
1240 ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base),
1241 scope, NULL /* expr */, attrs,
1242 NULL /* controls */, NULL, NULL, NULL);
1244 talloc_steal(req, attrs);
1246 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1248 req->op.search.res = NULL;
1250 ret = mod->ops->search(mod, req);
1252 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1254 py_ret = PyLdbResult_FromResult(req->op.search.res);
1256 talloc_free(req);
1258 return py_ret;
1262 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
1264 struct ldb_request *req;
1265 PyObject *py_message;
1266 int ret;
1267 struct ldb_module *mod;
1269 if (!PyArg_ParseTuple(args, "O", &py_message))
1270 return NULL;
1272 req = talloc_zero(NULL, struct ldb_request);
1273 req->operation = LDB_ADD;
1274 req->op.add.message = PyLdbMessage_AsMessage(py_message);
1276 mod = PyLdbModule_AsModule(self);
1277 ret = mod->ops->add(mod, req);
1279 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1281 Py_RETURN_NONE;
1284 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
1286 int ret;
1287 struct ldb_request *req;
1288 PyObject *py_message;
1289 struct ldb_module *mod;
1291 if (!PyArg_ParseTuple(args, "O", &py_message))
1292 return NULL;
1294 req = talloc_zero(NULL, struct ldb_request);
1295 req->operation = LDB_MODIFY;
1296 req->op.mod.message = PyLdbMessage_AsMessage(py_message);
1298 mod = PyLdbModule_AsModule(self);
1299 ret = mod->ops->modify(mod, req);
1301 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1303 Py_RETURN_NONE;
1306 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
1308 int ret;
1309 struct ldb_request *req;
1310 PyObject *py_dn;
1312 if (!PyArg_ParseTuple(args, "O", &py_dn))
1313 return NULL;
1315 req = talloc_zero(NULL, struct ldb_request);
1316 req->operation = LDB_DELETE;
1317 req->op.del.dn = PyLdbDn_AsDn(py_dn);
1319 ret = PyLdbModule_AsModule(self)->ops->del(PyLdbModule_AsModule(self), req);
1321 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1323 Py_RETURN_NONE;
1326 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
1328 int ret;
1329 struct ldb_request *req;
1330 PyObject *py_dn1, *py_dn2;
1332 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
1333 return NULL;
1335 req = talloc_zero(NULL, struct ldb_request);
1337 req->operation = LDB_RENAME;
1338 req->op.rename.olddn = PyLdbDn_AsDn(py_dn1);
1339 req->op.rename.newdn = PyLdbDn_AsDn(py_dn2);
1341 ret = PyLdbModule_AsModule(self)->ops->rename(PyLdbModule_AsModule(self), req);
1343 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1345 Py_RETURN_NONE;
1348 static PyMethodDef py_ldb_module_methods[] = {
1349 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
1350 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
1351 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
1352 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
1353 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
1354 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
1355 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
1356 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
1357 { NULL },
1360 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
1362 talloc_free(self->mem_ctx);
1363 self->ob_type->tp_free(self);
1366 PyTypeObject PyLdbModule = {
1367 .tp_name = "LdbModule",
1368 .tp_methods = py_ldb_module_methods,
1369 .tp_repr = (reprfunc)py_ldb_module_repr,
1370 .tp_str = (reprfunc)py_ldb_module_str,
1371 .tp_basicsize = sizeof(PyLdbModuleObject),
1372 .tp_dealloc = (destructor)py_ldb_module_dealloc,
1373 .tp_flags = Py_TPFLAGS_DEFAULT,
1378 * Create a ldb_message_element from a Python object.
1380 * This will accept any sequence objects that contains strings, or
1381 * a string object.
1383 * A reference to set_obj will be borrowed.
1385 * @param mem_ctx Memory context
1386 * @param set_obj Python object to convert
1387 * @param flags ldb_message_element flags to set
1388 * @param attr_name Name of the attribute
1389 * @return New ldb_message_element, allocated as child of mem_ctx
1391 struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
1392 PyObject *set_obj, int flags,
1393 const char *attr_name)
1395 struct ldb_message_element *me;
1397 if (PyLdbMessageElement_Check(set_obj))
1398 return talloc_reference(mem_ctx,
1399 PyLdbMessageElement_AsMessageElement(set_obj));
1401 me = talloc(mem_ctx, struct ldb_message_element);
1403 me->name = talloc_strdup(me, attr_name);
1404 me->flags = flags;
1405 if (PyString_Check(set_obj)) {
1406 me->num_values = 1;
1407 me->values = talloc_array(me, struct ldb_val, me->num_values);
1408 me->values[0].length = PyString_Size(set_obj);
1409 me->values[0].data = talloc_memdup(me,
1410 (uint8_t *)PyString_AsString(set_obj), me->values[0].length);
1411 } else if (PySequence_Check(set_obj)) {
1412 int i;
1413 me->num_values = PySequence_Size(set_obj);
1414 me->values = talloc_array(me, struct ldb_val, me->num_values);
1415 for (i = 0; i < me->num_values; i++) {
1416 PyObject *obj = PySequence_GetItem(set_obj, i);
1418 me->values[i].length = PyString_Size(obj);
1419 me->values[i].data = talloc_memdup(me,
1420 (uint8_t *)PyString_AsString(obj), me->values[i].length);
1422 } else {
1423 talloc_free(me);
1424 me = NULL;
1427 return me;
1431 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
1432 struct ldb_message_element *me)
1434 int i;
1435 PyObject *result;
1437 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
1438 result = PyList_New(me->num_values);
1440 for (i = 0; i < me->num_values; i++) {
1441 PyList_SetItem(result, i,
1442 PyObject_FromLdbValue(ldb_ctx, me, &me->values[i]));
1445 return result;
1448 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
1450 int i;
1451 if (!PyArg_ParseTuple(args, "i", &i))
1452 return NULL;
1453 if (i < 0 || i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
1454 Py_RETURN_NONE;
1456 return PyObject_FromLdbValue(NULL, PyLdbMessageElement_AsMessageElement(self),
1457 &(PyLdbMessageElement_AsMessageElement(self)->values[i]));
1460 static PyMethodDef py_ldb_msg_element_methods[] = {
1461 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
1462 { NULL },
1465 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
1467 return PyLdbMessageElement_AsMessageElement(self)->num_values;
1470 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
1472 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1473 if (idx < 0 || idx >= el->num_values) {
1474 PyErr_SetString(PyExc_IndexError, "Out of range");
1475 return NULL;
1477 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
1480 static PySequenceMethods py_ldb_msg_element_seq = {
1481 .sq_length = (lenfunc)py_ldb_msg_element_len,
1482 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
1485 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
1487 return ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self),
1488 PyLdbMessageElement_AsMessageElement(other));
1491 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
1493 return PyObject_GetIter(ldb_msg_element_to_set(NULL, PyLdbMessageElement_AsMessageElement(self)));
1496 PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
1498 PyLdbMessageElementObject *ret;
1499 ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
1500 if (ret == NULL) {
1501 PyErr_NoMemory();
1502 return NULL;
1504 ret->mem_ctx = talloc_new(NULL);
1505 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
1506 PyErr_NoMemory();
1507 return NULL;
1509 ret->el = el;
1510 return (PyObject *)ret;
1513 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1515 PyObject *py_elements = NULL;
1516 struct ldb_message_element *el;
1517 int flags = 0;
1518 char *name = NULL;
1519 const char * const kwnames[] = { "elements", "flags", "name", NULL };
1520 PyLdbMessageElementObject *ret;
1521 TALLOC_CTX *mem_ctx;
1523 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Ois",
1524 discard_const_p(char *, kwnames),
1525 &py_elements, &flags, &name))
1526 return NULL;
1528 mem_ctx = talloc_new(NULL);
1529 if (mem_ctx == NULL) {
1530 PyErr_NoMemory();
1531 return NULL;
1534 el = talloc_zero(mem_ctx, struct ldb_message_element);
1536 if (py_elements != NULL) {
1537 int i;
1538 if (PyString_Check(py_elements)) {
1539 el->num_values = 1;
1540 el->values = talloc_array(el, struct ldb_val, 1);
1541 el->values[0].length = PyString_Size(py_elements);
1542 el->values[0].data = talloc_memdup(el,
1543 (uint8_t *)PyString_AsString(py_elements), el->values[0].length);
1544 } else if (PySequence_Check(py_elements)) {
1545 el->num_values = PySequence_Size(py_elements);
1546 el->values = talloc_array(el, struct ldb_val, el->num_values);
1547 for (i = 0; i < el->num_values; i++) {
1548 PyObject *item = PySequence_GetItem(py_elements, i);
1549 if (!PyString_Check(item)) {
1550 PyErr_Format(PyExc_TypeError,
1551 "Expected string as element %d in list",
1553 talloc_free(mem_ctx);
1554 return NULL;
1556 el->values[i].length = PyString_Size(item);
1557 el->values[i].data = talloc_memdup(el,
1558 (uint8_t *)PyString_AsString(item), el->values[i].length);
1560 } else {
1561 PyErr_SetString(PyExc_TypeError,
1562 "Expected string or list");
1563 talloc_free(mem_ctx);
1564 return NULL;
1568 el->flags = flags;
1569 el->name = talloc_strdup(el, name);
1571 ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
1572 if (ret == NULL) {
1573 PyErr_NoMemory();
1574 talloc_free(mem_ctx);
1575 return NULL;
1578 ret->mem_ctx = mem_ctx;
1579 ret->el = el;
1580 return (PyObject *)ret;
1583 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
1585 char *element_str = NULL;
1586 int i;
1587 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1588 PyObject *ret;
1590 for (i = 0; i < el->num_values; i++) {
1591 PyObject *o = py_ldb_msg_element_find(self, i);
1592 if (element_str == NULL)
1593 element_str = talloc_strdup(NULL, PyObject_REPR(o));
1594 else
1595 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
1598 ret = PyString_FromFormat("MessageElement([%s])", element_str);
1600 talloc_free(element_str);
1602 return ret;
1605 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
1607 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1609 if (el->num_values == 1)
1610 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
1611 else
1612 Py_RETURN_NONE;
1615 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
1617 talloc_free(self->mem_ctx);
1618 self->ob_type->tp_free(self);
1621 PyTypeObject PyLdbMessageElement = {
1622 .tp_name = "MessageElement",
1623 .tp_basicsize = sizeof(PyLdbMessageElementObject),
1624 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
1625 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
1626 .tp_str = (reprfunc)py_ldb_msg_element_str,
1627 .tp_methods = py_ldb_msg_element_methods,
1628 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
1629 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
1630 .tp_as_sequence = &py_ldb_msg_element_seq,
1631 .tp_new = py_ldb_msg_element_new,
1632 .tp_flags = Py_TPFLAGS_DEFAULT,
1635 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
1637 char *name;
1638 if (!PyArg_ParseTuple(args, "s", &name))
1639 return NULL;
1641 ldb_msg_remove_attr(self->msg, name);
1643 Py_RETURN_NONE;
1646 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
1648 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1649 int i, j = 0;
1650 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
1651 if (msg->dn != NULL) {
1652 PyList_SetItem(obj, j, PyString_FromString("dn"));
1653 j++;
1655 for (i = 0; i < msg->num_elements; i++) {
1656 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
1657 j++;
1659 return obj;
1662 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
1664 struct ldb_message_element *el;
1665 char *name = PyString_AsString(py_name);
1666 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1667 if (!strcmp(name, "dn"))
1668 return PyLdbDn_FromDn(msg->dn);
1669 el = ldb_msg_find_element(msg, name);
1670 if (el == NULL) {
1671 return NULL;
1673 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg);
1676 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
1678 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
1679 if (ret == NULL) {
1680 PyErr_SetString(PyExc_KeyError, "No such element");
1681 return NULL;
1683 return ret;
1686 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args)
1688 PyObject *name, *ret;
1689 if (!PyArg_ParseTuple(args, "O", &name))
1690 return NULL;
1692 ret = py_ldb_msg_getitem_helper(self, name);
1693 if (ret == NULL)
1694 Py_RETURN_NONE;
1695 return ret;
1698 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
1700 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1701 int i, j;
1702 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
1703 j = 0;
1704 if (msg->dn != NULL) {
1705 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn)));
1706 j++;
1708 for (i = 0; i < msg->num_elements; i++, j++) {
1709 PyList_SetItem(l, j, Py_BuildValue("(sO)", msg->elements[i].name, PyLdbMessageElement_FromMessageElement(&msg->elements[i], self->msg)));
1711 return l;
1714 static PyMethodDef py_ldb_msg_methods[] = {
1715 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, NULL },
1716 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, NULL },
1717 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL },
1718 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
1719 { NULL },
1722 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
1724 PyObject *list, *iter;
1726 list = py_ldb_msg_keys(self);
1727 iter = PyObject_GetIter(list);
1728 Py_DECREF(list);
1729 return iter;
1732 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
1734 char *attr_name;
1736 if (!PyString_Check(name)) {
1737 PyErr_SetNone(PyExc_TypeError);
1738 return -1;
1741 attr_name = PyString_AsString(name);
1742 if (value == NULL) {
1743 /* delitem */
1744 ldb_msg_remove_attr(self->msg, attr_name);
1745 } else {
1746 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
1747 value, 0, attr_name);
1748 if (el == NULL)
1749 return -1;
1750 ldb_msg_remove_attr(PyLdbMessage_AsMessage(self), attr_name);
1751 ldb_msg_add(PyLdbMessage_AsMessage(self), el, el->flags);
1753 return 0;
1756 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
1758 return PyLdbMessage_AsMessage(self)->num_elements;
1761 static PyMappingMethods py_ldb_msg_mapping = {
1762 .mp_length = (lenfunc)py_ldb_msg_length,
1763 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
1764 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
1767 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1769 const char * const kwnames[] = { "dn", NULL };
1770 struct ldb_message *ret;
1771 TALLOC_CTX *mem_ctx;
1772 PyObject *pydn = NULL;
1773 PyLdbMessageObject *py_ret;
1775 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
1776 discard_const_p(char *, kwnames),
1777 &pydn))
1778 return NULL;
1780 mem_ctx = talloc_new(NULL);
1781 if (mem_ctx == NULL) {
1782 PyErr_NoMemory();
1783 return NULL;
1786 ret = ldb_msg_new(mem_ctx);
1787 if (ret == NULL) {
1788 talloc_free(mem_ctx);
1789 PyErr_NoMemory();
1790 return NULL;
1793 if (pydn != NULL) {
1794 struct ldb_dn *dn;
1795 if (!PyObject_AsDn(NULL, pydn, NULL, &dn)) {
1796 talloc_free(mem_ctx);
1797 return NULL;
1799 ret->dn = talloc_reference(ret, dn);
1802 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
1803 if (py_ret == NULL) {
1804 PyErr_NoMemory();
1805 talloc_free(mem_ctx);
1806 return NULL;
1809 py_ret->mem_ctx = mem_ctx;
1810 py_ret->msg = ret;
1811 return (PyObject *)py_ret;
1814 PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
1816 PyLdbMessageObject *ret;
1818 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
1819 if (ret == NULL) {
1820 PyErr_NoMemory();
1821 return NULL;
1823 ret->mem_ctx = talloc_new(NULL);
1824 ret->msg = talloc_reference(ret->mem_ctx, msg);
1825 return (PyObject *)ret;
1828 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
1830 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1831 return PyLdbDn_FromDn(msg->dn);
1834 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
1836 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1837 if (!PyLdbDn_Check(value)) {
1838 PyErr_SetNone(PyExc_TypeError);
1839 return -1;
1842 msg->dn = talloc_reference(msg, PyLdbDn_AsDn(value));
1843 return 0;
1846 static PyGetSetDef py_ldb_msg_getset[] = {
1847 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
1848 { NULL }
1851 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
1853 PyObject *dict = PyDict_New(), *ret;
1854 if (PyDict_Update(dict, (PyObject *)self) != 0)
1855 return NULL;
1856 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
1857 Py_DECREF(dict);
1858 return ret;
1861 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
1863 talloc_free(self->mem_ctx);
1864 self->ob_type->tp_free(self);
1867 PyTypeObject PyLdbMessage = {
1868 .tp_name = "Message",
1869 .tp_methods = py_ldb_msg_methods,
1870 .tp_getset = py_ldb_msg_getset,
1871 .tp_as_mapping = &py_ldb_msg_mapping,
1872 .tp_basicsize = sizeof(PyLdbMessageObject),
1873 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
1874 .tp_new = py_ldb_msg_new,
1875 .tp_repr = (reprfunc)py_ldb_msg_repr,
1876 .tp_flags = Py_TPFLAGS_DEFAULT,
1877 .tp_iter = (getiterfunc)py_ldb_msg_iter,
1880 PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
1882 PyLdbTreeObject *ret;
1884 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
1885 if (ret == NULL) {
1886 PyErr_NoMemory();
1887 return NULL;
1890 ret->mem_ctx = talloc_new(NULL);
1891 ret->tree = talloc_reference(ret->mem_ctx, tree);
1892 return (PyObject *)ret;
1895 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
1897 talloc_free(self->mem_ctx);
1898 self->ob_type->tp_free(self);
1901 PyTypeObject PyLdbTree = {
1902 .tp_name = "Tree",
1903 .tp_basicsize = sizeof(PyLdbTreeObject),
1904 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
1905 .tp_flags = Py_TPFLAGS_DEFAULT,
1908 /* Ldb_module */
1909 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
1911 PyObject *py_ldb = (PyObject *)mod->private_data;
1912 PyObject *py_result, *py_base, *py_attrs, *py_tree;
1914 py_base = PyLdbDn_FromDn(req->op.search.base);
1916 if (py_base == NULL)
1917 return LDB_ERR_OPERATIONS_ERROR;
1919 py_tree = PyLdbTree_FromTree(req->op.search.tree);
1921 if (py_tree == NULL)
1922 return LDB_ERR_OPERATIONS_ERROR;
1924 if (req->op.search.attrs == NULL) {
1925 py_attrs = Py_None;
1926 } else {
1927 int i, len;
1928 for (len = 0; req->op.search.attrs[len]; len++);
1929 py_attrs = PyList_New(len);
1930 for (i = 0; i < len; i++)
1931 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
1934 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
1935 discard_const_p(char, "OiOO"),
1936 py_base, req->op.search.scope, py_tree, py_attrs);
1938 Py_DECREF(py_attrs);
1939 Py_DECREF(py_tree);
1940 Py_DECREF(py_base);
1942 if (py_result == NULL) {
1943 return LDB_ERR_PYTHON_EXCEPTION;
1946 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
1947 if (req->op.search.res == NULL) {
1948 return LDB_ERR_PYTHON_EXCEPTION;
1951 Py_DECREF(py_result);
1953 return LDB_SUCCESS;
1956 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
1958 PyObject *py_ldb = (PyObject *)mod->private_data;
1959 PyObject *py_result, *py_msg;
1961 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
1963 if (py_msg == NULL) {
1964 return LDB_ERR_OPERATIONS_ERROR;
1967 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
1968 discard_const_p(char, "O"),
1969 py_msg);
1971 Py_DECREF(py_msg);
1973 if (py_result == NULL) {
1974 return LDB_ERR_PYTHON_EXCEPTION;
1977 Py_DECREF(py_result);
1979 return LDB_SUCCESS;
1982 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
1984 PyObject *py_ldb = (PyObject *)mod->private_data;
1985 PyObject *py_result, *py_msg;
1987 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
1989 if (py_msg == NULL) {
1990 return LDB_ERR_OPERATIONS_ERROR;
1993 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
1994 discard_const_p(char, "O"),
1995 py_msg);
1997 Py_DECREF(py_msg);
1999 if (py_result == NULL) {
2000 return LDB_ERR_PYTHON_EXCEPTION;
2003 Py_DECREF(py_result);
2005 return LDB_SUCCESS;
2008 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
2010 PyObject *py_ldb = (PyObject *)mod->private_data;
2011 PyObject *py_result, *py_dn;
2013 py_dn = PyLdbDn_FromDn(req->op.del.dn);
2015 if (py_dn == NULL)
2016 return LDB_ERR_OPERATIONS_ERROR;
2018 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
2019 discard_const_p(char, "O"),
2020 py_dn);
2022 if (py_result == NULL) {
2023 return LDB_ERR_PYTHON_EXCEPTION;
2026 Py_DECREF(py_result);
2028 return LDB_SUCCESS;
2031 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
2033 PyObject *py_ldb = (PyObject *)mod->private_data;
2034 PyObject *py_result, *py_olddn, *py_newdn;
2036 py_olddn = PyLdbDn_FromDn(req->op.rename.olddn);
2038 if (py_olddn == NULL)
2039 return LDB_ERR_OPERATIONS_ERROR;
2041 py_newdn = PyLdbDn_FromDn(req->op.rename.newdn);
2043 if (py_newdn == NULL)
2044 return LDB_ERR_OPERATIONS_ERROR;
2046 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
2047 discard_const_p(char, "OO"),
2048 py_olddn, py_newdn);
2050 Py_DECREF(py_olddn);
2051 Py_DECREF(py_newdn);
2053 if (py_result == NULL) {
2054 return LDB_ERR_PYTHON_EXCEPTION;
2057 Py_DECREF(py_result);
2059 return LDB_SUCCESS;
2062 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
2064 PyObject *py_ldb = (PyObject *)mod->private_data;
2065 PyObject *py_result;
2067 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
2068 discard_const_p(char, ""));
2070 return LDB_ERR_OPERATIONS_ERROR;
2073 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
2075 PyObject *py_ldb = (PyObject *)mod->private_data;
2076 PyObject *py_result;
2078 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
2079 discard_const_p(char, ""));
2081 return LDB_ERR_OPERATIONS_ERROR;
2084 static int py_module_start_transaction(struct ldb_module *mod)
2086 PyObject *py_ldb = (PyObject *)mod->private_data;
2087 PyObject *py_result;
2089 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
2090 discard_const_p(char, ""));
2092 if (py_result == NULL) {
2093 return LDB_ERR_PYTHON_EXCEPTION;
2096 Py_DECREF(py_result);
2098 return LDB_SUCCESS;
2101 static int py_module_end_transaction(struct ldb_module *mod)
2103 PyObject *py_ldb = (PyObject *)mod->private_data;
2104 PyObject *py_result;
2106 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
2107 discard_const_p(char, ""));
2109 if (py_result == NULL) {
2110 return LDB_ERR_PYTHON_EXCEPTION;
2113 Py_DECREF(py_result);
2115 return LDB_SUCCESS;
2118 static int py_module_del_transaction(struct ldb_module *mod)
2120 PyObject *py_ldb = (PyObject *)mod->private_data;
2121 PyObject *py_result;
2123 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
2124 discard_const_p(char, ""));
2126 if (py_result == NULL) {
2127 return LDB_ERR_PYTHON_EXCEPTION;
2130 Py_DECREF(py_result);
2132 return LDB_SUCCESS;
2135 static int py_module_destructor(struct ldb_module *mod)
2137 Py_DECREF((PyObject *)mod->private_data);
2138 return 0;
2141 static int py_module_init(struct ldb_module *mod)
2143 PyObject *py_class = (PyObject *)mod->ops->private_data;
2144 PyObject *py_result, *py_next, *py_ldb;
2146 py_ldb = PyLdb_FromLdbContext(mod->ldb);
2148 if (py_ldb == NULL)
2149 return LDB_ERR_OPERATIONS_ERROR;
2151 py_next = PyLdbModule_FromModule(mod->next);
2153 if (py_next == NULL)
2154 return LDB_ERR_OPERATIONS_ERROR;
2156 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
2157 py_ldb, py_next);
2159 if (py_result == NULL) {
2160 return LDB_ERR_PYTHON_EXCEPTION;
2163 mod->private_data = py_result;
2165 talloc_set_destructor(mod, py_module_destructor);
2167 return ldb_next_init(mod);
2170 static PyObject *py_register_module(PyObject *module, PyObject *args)
2172 int ret;
2173 struct ldb_module_ops *ops;
2174 PyObject *input;
2176 if (!PyArg_ParseTuple(args, "O", &input))
2177 return NULL;
2179 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
2180 if (ops == NULL) {
2181 PyErr_NoMemory();
2182 return NULL;
2185 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
2187 Py_INCREF(input);
2188 ops->private_data = input;
2189 ops->init_context = py_module_init;
2190 ops->search = py_module_search;
2191 ops->add = py_module_add;
2192 ops->modify = py_module_modify;
2193 ops->del = py_module_del;
2194 ops->rename = py_module_rename;
2195 ops->request = py_module_request;
2196 ops->extended = py_module_extended;
2197 ops->start_transaction = py_module_start_transaction;
2198 ops->end_transaction = py_module_end_transaction;
2199 ops->del_transaction = py_module_del_transaction;
2201 ret = ldb_register_module(ops);
2203 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2205 Py_RETURN_NONE;
2208 static PyObject *py_timestring(PyObject *module, PyObject *args)
2210 time_t t;
2211 char *tresult;
2212 PyObject *ret;
2213 if (!PyArg_ParseTuple(args, "L", &t))
2214 return NULL;
2215 tresult = ldb_timestring(NULL, t);
2216 ret = PyString_FromString(tresult);
2217 talloc_free(tresult);
2218 return ret;
2221 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
2223 char *str;
2224 if (!PyArg_ParseTuple(args, "s", &str))
2225 return NULL;
2227 return PyInt_FromLong(ldb_string_to_time(str));
2230 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
2232 char *name;
2233 if (!PyArg_ParseTuple(args, "s", &name))
2234 return NULL;
2235 return PyBool_FromLong(ldb_valid_attr_name(name));
2238 static PyMethodDef py_ldb_global_methods[] = {
2239 { "register_module", py_register_module, METH_VARARGS,
2240 "S.register_module(module) -> None\n"
2241 "Register a LDB module."},
2242 { "timestring", py_timestring, METH_VARARGS,
2243 "S.timestring(int) -> string\n"
2244 "Generate a LDAP time string from a UNIX timestamp" },
2245 { "string_to_time", py_string_to_time, METH_VARARGS,
2246 "S.string_to_time(string) -> int\n"
2247 "Parse a LDAP time string into a UNIX timestamp." },
2248 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
2249 "S.valid_attr_name(name) -> bool\n"
2250 "Check whether the supplied name is a valid attribute name." },
2251 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
2252 NULL },
2253 { NULL }
2256 void initldb(void)
2258 PyObject *m;
2260 if (PyType_Ready(&PyLdbDn) < 0)
2261 return;
2263 if (PyType_Ready(&PyLdbMessage) < 0)
2264 return;
2266 if (PyType_Ready(&PyLdbMessageElement) < 0)
2267 return;
2269 if (PyType_Ready(&PyLdb) < 0)
2270 return;
2272 if (PyType_Ready(&PyLdbModule) < 0)
2273 return;
2275 if (PyType_Ready(&PyLdbTree) < 0)
2276 return;
2278 m = Py_InitModule3("ldb", py_ldb_global_methods,
2279 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
2280 if (m == NULL)
2281 return;
2283 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
2284 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
2285 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
2286 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
2288 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
2289 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
2290 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
2291 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
2293 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
2294 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
2295 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
2296 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
2297 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
2298 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
2299 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
2300 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
2301 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
2302 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
2303 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
2304 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
2305 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
2306 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
2307 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
2308 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
2309 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
2310 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
2311 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
2312 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
2313 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
2314 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
2315 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
2316 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
2317 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
2318 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
2319 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
2320 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
2321 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
2322 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
2323 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
2324 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
2325 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
2326 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
2327 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
2328 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
2329 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
2330 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
2331 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
2333 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
2334 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
2335 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
2336 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
2339 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
2341 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
2342 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
2344 Py_INCREF(&PyLdb);
2345 Py_INCREF(&PyLdbDn);
2346 Py_INCREF(&PyLdbModule);
2347 Py_INCREF(&PyLdbMessage);
2348 Py_INCREF(&PyLdbMessageElement);
2349 Py_INCREF(&PyLdbTree);
2351 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
2352 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
2353 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
2354 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
2355 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
2356 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);