provision/pyldb: Avoid linking in static python ldb module.
[Samba/fernandojvsilva.git] / source4 / lib / ldb / pyldb.c
bloba19768d41b6e56c897440ada037ba3edf32b6b44
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 <Python.h>
30 #include "replace.h"
31 #include "ldb_private.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 *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
66 static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx,
67 struct ldb_message_element *el,
68 struct ldb_val *val)
70 struct ldb_val new_val;
71 TALLOC_CTX *mem_ctx = talloc_new(NULL);
72 PyObject *ret;
74 new_val = *val;
76 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
78 talloc_free(mem_ctx);
80 return ret;
83 /**
84 * Obtain a ldb DN from a Python object.
86 * @param mem_ctx Memory context
87 * @param object Python object
88 * @param ldb_ctx LDB context
89 * @return Whether or not the conversion succeeded
91 bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object,
92 struct ldb_context *ldb_ctx, struct ldb_dn **dn)
94 struct ldb_dn *odn;
96 if (ldb_ctx != NULL && PyString_Check(object)) {
97 odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
98 *dn = odn;
99 return true;
102 if (PyLdbDn_Check(object)) {
103 *dn = PyLdbDn_AsDn(object);
104 return true;
107 PyErr_SetString(PyExc_TypeError, "Expected DN");
108 return false;
112 * Create a Python object from a ldb_result.
114 * @param result LDB result to convert
115 * @return Python object with converted result (a list object)
117 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
119 PyObject *ret;
120 int i;
121 if (result == NULL) {
122 Py_RETURN_NONE;
124 ret = PyList_New(result->count);
125 for (i = 0; i < result->count; i++) {
126 PyList_SetItem(ret, i, PyLdbMessage_FromMessage(result->msgs[i])
129 return ret;
133 * Create a LDB Result from a Python object.
134 * If conversion fails, NULL will be returned and a Python exception set.
136 * @param mem_ctx Memory context in which to allocate the LDB Result
137 * @param obj Python object to convert
138 * @return a ldb_result, or NULL if the conversion failed
140 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
141 PyObject *obj)
143 struct ldb_result *res;
144 int i;
146 if (obj == Py_None)
147 return NULL;
149 res = talloc_zero(mem_ctx, struct ldb_result);
150 res->count = PyList_Size(obj);
151 res->msgs = talloc_array(res, struct ldb_message *, res->count);
152 for (i = 0; i < res->count; i++) {
153 PyObject *item = PyList_GetItem(obj, i);
154 res->msgs[i] = PyLdbMessage_AsMessage(item);
156 return res;
159 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
161 return PyBool_FromLong(ldb_dn_validate(self->dn));
164 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
166 return PyBool_FromLong(ldb_dn_is_valid(self->dn));
169 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
171 return PyBool_FromLong(ldb_dn_is_special(self->dn));
174 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
176 return PyBool_FromLong(ldb_dn_is_null(self->dn));
179 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
181 return PyString_FromString(ldb_dn_get_casefold(self->dn));
184 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
186 return PyString_FromString(ldb_dn_get_linearized(self->dn));
189 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
191 return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
194 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
196 return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
199 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
201 return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
204 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
206 char *name;
208 if (!PyArg_ParseTuple(args, "s", &name))
209 return NULL;
211 return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
214 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
216 int ret;
217 ret = ldb_dn_compare(dn1->dn, dn2->dn);
218 if (ret < 0) ret = -1;
219 if (ret > 0) ret = 1;
220 return ret;
223 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
225 struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self);
226 struct ldb_dn *parent;
227 PyLdbDnObject *py_ret;
228 TALLOC_CTX *mem_ctx = talloc_new(NULL);
230 parent = ldb_dn_get_parent(mem_ctx, dn);
231 if (parent == NULL) {
232 talloc_free(mem_ctx);
233 Py_RETURN_NONE;
236 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
237 if (py_ret == NULL) {
238 PyErr_NoMemory();
239 talloc_free(mem_ctx);
240 return NULL;
242 py_ret->mem_ctx = mem_ctx;
243 py_ret->dn = parent;
244 return (PyObject *)py_ret;
247 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
249 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
251 PyObject *py_other;
252 struct ldb_dn *dn, *other;
253 if (!PyArg_ParseTuple(args, "O", &py_other))
254 return NULL;
256 dn = PyLdbDn_AsDn((PyObject *)self);
258 if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
259 return NULL;
261 return ldb_dn_add_child(dn, other)?Py_True:Py_False;
264 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
266 PyObject *py_other;
267 struct ldb_dn *other, *dn;
268 if (!PyArg_ParseTuple(args, "O", &py_other))
269 return NULL;
271 dn = PyLdbDn_AsDn((PyObject *)self);
273 if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
274 return NULL;
276 return ldb_dn_add_base(dn, other)?Py_True:Py_False;
279 static PyMethodDef py_ldb_dn_methods[] = {
280 { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS,
281 "S.validate() -> bool\n"
282 "Validate DN is correct." },
283 { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
284 "S.is_valid() -> bool\n" },
285 { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
286 "S.is_special() -> bool\n"
287 "Check whether this is a special LDB DN." },
288 { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
289 "Check whether this is a null DN." },
290 { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
291 NULL },
292 { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
293 NULL },
294 { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
295 "S.canonical_str() -> string\n"
296 "Canonical version of this DN (like a posix path)." },
297 { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
298 "S.canonical_ex_str() -> string\n"
299 "Canonical version of this DN (like a posix path, with terminating newline)." },
300 { "check_special", (PyCFunction)py_ldb_dn_is_special, METH_VARARGS,
301 NULL },
302 { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
303 "S.parent() -> dn\n"
304 "Get the parent for this DN." },
305 { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS,
306 "S.add_child(dn) -> None\n"
307 "Add a child DN to this DN." },
308 { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
309 "S.add_base(dn) -> None\n"
310 "Add a base DN to this DN." },
311 { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
312 NULL },
313 { NULL }
316 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
318 return ldb_dn_get_comp_num(PyLdbDn_AsDn((PyObject *)self));
321 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
323 struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self),
324 *other;
325 PyLdbDnObject *py_ret;
327 if (!PyObject_AsDn(NULL, py_other, NULL, &other))
328 return NULL;
330 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
331 if (py_ret == NULL) {
332 PyErr_NoMemory();
333 return NULL;
335 py_ret->mem_ctx = talloc_new(NULL);
336 py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
337 ldb_dn_add_child(py_ret->dn, other);
338 return (PyObject *)py_ret;
341 static PySequenceMethods py_ldb_dn_seq = {
342 .sq_length = (lenfunc)py_ldb_dn_len,
343 .sq_concat = (binaryfunc)py_ldb_dn_concat,
346 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
348 struct ldb_dn *ret;
349 char *str;
350 PyObject *py_ldb;
351 struct ldb_context *ldb_ctx;
352 TALLOC_CTX *mem_ctx;
353 PyLdbDnObject *py_ret;
354 const char * const kwnames[] = { "ldb", "dn", NULL };
356 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
357 discard_const_p(char *, kwnames),
358 &py_ldb, &str))
359 return NULL;
361 ldb_ctx = PyLdb_AsLdbContext(py_ldb);
363 mem_ctx = talloc_new(NULL);
364 if (mem_ctx == NULL) {
365 PyErr_NoMemory();
366 return NULL;
369 ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
371 if (ret == NULL || !ldb_dn_validate(ret)) {
372 talloc_free(mem_ctx);
373 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
374 return NULL;
377 py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
378 if (ret == NULL) {
379 talloc_free(mem_ctx);
380 PyErr_NoMemory();
381 return NULL;
383 py_ret->mem_ctx = mem_ctx;
384 py_ret->dn = ret;
385 return (PyObject *)py_ret;
388 PyObject *PyLdbDn_FromDn(struct ldb_dn *dn)
390 PyLdbDnObject *py_ret;
392 if (dn == NULL) {
393 Py_RETURN_NONE;
396 py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
397 if (py_ret == NULL) {
398 PyErr_NoMemory();
399 return NULL;
401 py_ret->mem_ctx = talloc_new(NULL);
402 py_ret->dn = talloc_reference(py_ret->mem_ctx, dn);
403 return (PyObject *)py_ret;
406 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
408 talloc_free(self->mem_ctx);
409 self->ob_type->tp_free(self);
412 PyTypeObject PyLdbDn = {
413 .tp_name = "Dn",
414 .tp_methods = py_ldb_dn_methods,
415 .tp_str = (reprfunc)py_ldb_dn_get_linearized,
416 .tp_repr = (reprfunc)py_ldb_dn_repr,
417 .tp_compare = (cmpfunc)py_ldb_dn_compare,
418 .tp_as_sequence = &py_ldb_dn_seq,
419 .tp_doc = "A LDB distinguished name.",
420 .tp_new = py_ldb_dn_new,
421 .tp_dealloc = (destructor)py_ldb_dn_dealloc,
422 .tp_basicsize = sizeof(PyLdbObject),
423 .tp_flags = Py_TPFLAGS_DEFAULT,
426 /* Debug */
427 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
428 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
430 PyObject *fn = (PyObject *)context;
431 PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
434 static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args)
436 PyObject *cb;
438 if (!PyArg_ParseTuple(args, "O", &cb))
439 return NULL;
441 Py_INCREF(cb);
442 /* FIXME: Where do we DECREF cb ? */
443 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), PyLdb_AsLdbContext(self));
445 Py_RETURN_NONE;
448 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
450 unsigned int perms;
451 if (!PyArg_ParseTuple(args, "I", &perms))
452 return NULL;
454 ldb_set_create_perms(PyLdb_AsLdbContext(self), perms);
456 Py_RETURN_NONE;
459 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
461 char *modules_dir;
462 if (!PyArg_ParseTuple(args, "s", &modules_dir))
463 return NULL;
465 ldb_set_modules_dir(PyLdb_AsLdbContext(self), modules_dir);
467 Py_RETURN_NONE;
470 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
472 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_start(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
473 Py_RETURN_NONE;
476 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
478 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
479 Py_RETURN_NONE;
482 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
484 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_prepare_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
485 Py_RETURN_NONE;
488 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
490 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_cancel(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
491 Py_RETURN_NONE;
494 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
496 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_setup_wellknown_attributes(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
497 Py_RETURN_NONE;
500 static PyObject *py_ldb_repr(PyLdbObject *self)
502 return PyString_FromFormat("<ldb connection>");
505 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
507 struct ldb_dn *dn = ldb_get_root_basedn(PyLdb_AsLdbContext(self));
508 if (dn == NULL)
509 Py_RETURN_NONE;
510 return PyLdbDn_FromDn(dn);
514 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
516 struct ldb_dn *dn = ldb_get_schema_basedn(PyLdb_AsLdbContext(self));
517 if (dn == NULL)
518 Py_RETURN_NONE;
519 return PyLdbDn_FromDn(dn);
522 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
524 struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self));
525 if (dn == NULL)
526 Py_RETURN_NONE;
527 return PyLdbDn_FromDn(dn);
530 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
532 struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self));
533 if (dn == NULL)
534 Py_RETURN_NONE;
535 return PyLdbDn_FromDn(dn);
538 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
539 const char *paramname)
541 const char **ret;
542 int i;
543 if (!PyList_Check(list)) {
544 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
545 return NULL;
547 ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
548 for (i = 0; i < PyList_Size(list); i++) {
549 PyObject *item = PyList_GetItem(list, i);
550 if (!PyString_Check(item)) {
551 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
552 return NULL;
554 ret[i] = talloc_strndup(ret, PyString_AsString(item),
555 PyString_Size(item));
557 ret[i] = NULL;
558 return ret;
561 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
563 const char * const kwnames[] = { "url", "flags", "options", NULL };
564 char *url = NULL;
565 PyObject *py_options = Py_None;
566 const char **options;
567 int flags = 0;
568 int ret;
569 struct ldb_context *ldb;
571 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO:Ldb.__init__",
572 discard_const_p(char *, kwnames),
573 &url, &flags, &py_options))
574 return -1;
576 ldb = PyLdb_AsLdbContext(self);
578 if (py_options == Py_None) {
579 options = NULL;
580 } else {
581 options = PyList_AsStringList(ldb, py_options, "options");
582 if (options == NULL)
583 return -1;
586 if (url != NULL) {
587 ret = ldb_connect(ldb, url, flags, options);
588 if (ret != LDB_SUCCESS) {
589 PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
590 return -1;
594 talloc_free(options);
595 return 0;
598 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
600 PyLdbObject *ret;
601 struct ldb_context *ldb;
602 ret = (PyLdbObject *)type->tp_alloc(type, 0);
603 if (ret == NULL) {
604 PyErr_NoMemory();
605 return NULL;
607 ret->mem_ctx = talloc_new(NULL);
608 ldb = ldb_init(ret->mem_ctx, NULL);
610 if (ldb == NULL) {
611 PyErr_NoMemory();
612 return NULL;
615 ret->ldb_ctx = ldb;
616 return (PyObject *)ret;
619 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
621 char *url;
622 int flags = 0;
623 PyObject *py_options = Py_None;
624 int ret;
625 const char **options;
626 const char * const kwnames[] = { "url", "flags", "options", NULL };
628 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO",
629 discard_const_p(char *, kwnames),
630 &url, &flags, &py_options))
631 return NULL;
633 if (py_options == Py_None) {
634 options = NULL;
635 } else {
636 options = PyList_AsStringList(NULL, py_options, "options");
637 if (options == NULL)
638 return NULL;
641 ret = ldb_connect(PyLdb_AsLdbContext(self), url, flags, options);
642 talloc_free(options);
644 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
646 Py_RETURN_NONE;
649 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args)
651 PyObject *py_msg;
652 PyObject *py_controls = Py_None;
653 struct ldb_context *ldb_ctx;
654 struct ldb_request *req;
655 struct ldb_control **parsed_controls;
656 struct ldb_message *msg;
657 int ret;
658 if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls))
659 return NULL;
661 ldb_ctx = PyLdb_AsLdbContext(self);
663 if (py_controls == Py_None) {
664 parsed_controls = NULL;
665 } else {
666 const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
667 parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
668 talloc_free(controls);
671 if (!PyLdbMessage_Check(py_msg)) {
672 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
673 return NULL;
675 msg = PyLdbMessage_AsMessage(py_msg);
677 ret = ldb_msg_sanity_check(ldb_ctx, msg);
678 if (ret != LDB_SUCCESS) {
679 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
680 return NULL;
683 ret = ldb_build_mod_req(&req, ldb_ctx, ldb_ctx,
684 msg,
685 parsed_controls,
686 NULL,
687 ldb_op_default_callback,
688 NULL);
690 if (ret != LDB_SUCCESS) {
691 PyErr_SetString(PyExc_TypeError, "failed to build request");
692 return NULL;
695 /* do request and autostart a transaction */
696 /* Then let's LDB handle the message error in case of pb as they are meaningful */
698 ret = ldb_transaction_start(ldb_ctx);
699 if (ret != LDB_SUCCESS) {
700 talloc_free(req);
701 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
704 ret = ldb_request(ldb_ctx, req);
705 if (ret == LDB_SUCCESS) {
706 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
709 if (ret == LDB_SUCCESS) {
710 ret = ldb_transaction_commit(ldb_ctx);
711 } else {
712 ldb_transaction_cancel(ldb_ctx);
713 if (ldb_ctx->err_string == NULL) {
714 /* no error string was setup by the backend */
715 ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
718 talloc_free(req);
719 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
721 Py_RETURN_NONE;
725 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
727 PyObject *py_msg;
728 int ret;
729 Py_ssize_t dict_pos, msg_pos;
730 struct ldb_message_element *msgel;
731 struct ldb_message *msg;
732 struct ldb_context *ldb_ctx;
733 struct ldb_request *req;
734 PyObject *key, *value;
735 PyObject *py_controls = Py_None;
736 TALLOC_CTX *mem_ctx;
737 struct ldb_control **parsed_controls;
739 if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls ))
740 return NULL;
741 ldb_ctx = PyLdb_AsLdbContext(self);
743 mem_ctx = talloc_new(NULL);
744 if (py_controls == Py_None) {
745 parsed_controls = NULL;
746 } else {
747 const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
748 parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
749 talloc_free(controls);
751 if (PyDict_Check(py_msg)) {
752 PyObject *dn_value = PyDict_GetItemString(py_msg, "dn");
753 msg = ldb_msg_new(mem_ctx);
754 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg));
755 msg_pos = dict_pos = 0;
756 if (dn_value) {
757 if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
758 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
759 talloc_free(mem_ctx);
760 return NULL;
762 if (msg->dn == NULL) {
763 PyErr_SetString(PyExc_TypeError, "dn set but not found");
764 talloc_free(mem_ctx);
765 return NULL;
769 while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
770 char *key_str = PyString_AsString(key);
771 if (strcmp(key_str, "dn") != 0) {
772 msgel = PyObject_AsMessageElement(msg->elements, value, 0, key_str);
773 if (msgel == NULL) {
774 PyErr_SetString(PyExc_TypeError, "unable to import element");
775 talloc_free(mem_ctx);
776 return NULL;
778 memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
779 msg_pos++;
783 if (msg->dn == NULL) {
784 PyErr_SetString(PyExc_TypeError, "no dn set");
785 talloc_free(mem_ctx);
786 return NULL;
789 msg->num_elements = msg_pos;
790 } else {
791 msg = PyLdbMessage_AsMessage(py_msg);
794 ret = ldb_msg_sanity_check(ldb_ctx, msg);
795 if (ret != LDB_SUCCESS) {
796 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
797 talloc_free(mem_ctx);
798 return NULL;
801 ret = ldb_build_add_req(&req, ldb_ctx, ldb_ctx,
802 msg,
803 parsed_controls,
804 NULL,
805 ldb_op_default_callback,
806 NULL);
808 if (ret != LDB_SUCCESS) {
809 PyErr_SetString(PyExc_TypeError, "failed to build request");
810 talloc_free(mem_ctx);
811 return NULL;
814 /* do request and autostart a transaction */
815 /* Then let's LDB handle the message error in case of pb as they are meaningful */
817 ret = ldb_transaction_start(ldb_ctx);
818 if (ret != LDB_SUCCESS) {
819 talloc_free(req);
820 talloc_free(mem_ctx);
821 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
824 ret = ldb_request(ldb_ctx, req);
825 if (ret == LDB_SUCCESS) {
826 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
829 if (ret == LDB_SUCCESS) {
830 ret = ldb_transaction_commit(ldb_ctx);
831 } else {
832 ldb_transaction_cancel(ldb_ctx);
833 if (ldb_ctx->err_string == NULL) {
834 /* no error string was setup by the backend */
835 ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
838 talloc_free(req);
839 talloc_free(mem_ctx);
840 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
842 Py_RETURN_NONE;
845 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args)
847 PyObject *py_dn;
848 struct ldb_dn *dn;
849 int ret;
850 struct ldb_context *ldb;
851 TALLOC_CTX *mem_ctx;
852 if (!PyArg_ParseTuple(args, "O", &py_dn))
853 return NULL;
855 mem_ctx = talloc_new(NULL);
856 if (mem_ctx == NULL) {
857 PyErr_NoMemory();
858 return NULL;
860 ldb = PyLdb_AsLdbContext(self);
861 if (!PyObject_AsDn(mem_ctx, py_dn, ldb, &dn)) {
862 talloc_free(mem_ctx);
863 return NULL;
866 ret = ldb_delete(ldb, dn);
867 talloc_free(mem_ctx);
868 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
870 Py_RETURN_NONE;
873 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args)
875 PyObject *py_dn1, *py_dn2;
876 struct ldb_dn *dn1, *dn2;
877 int ret;
878 struct ldb_context *ldb;
879 TALLOC_CTX *mem_ctx;
880 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
881 return NULL;
883 mem_ctx = talloc_new(NULL);
884 if (mem_ctx == NULL) {
885 PyErr_NoMemory();
886 return NULL;
888 ldb = PyLdb_AsLdbContext(self);
889 if (!PyObject_AsDn(mem_ctx, py_dn1, ldb, &dn1)) {
890 talloc_free(mem_ctx);
891 return NULL;
894 if (!PyObject_AsDn(mem_ctx, py_dn2, ldb, &dn2)) {
895 talloc_free(mem_ctx);
896 return NULL;
899 ret = ldb_rename(ldb, dn1, dn2);
900 talloc_free(mem_ctx);
901 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
903 Py_RETURN_NONE;
906 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
908 char *name;
909 if (!PyArg_ParseTuple(args, "s", &name))
910 return NULL;
912 ldb_schema_attribute_remove(PyLdb_AsLdbContext(self), name);
914 Py_RETURN_NONE;
917 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
919 char *attribute, *syntax;
920 unsigned int flags;
921 int ret;
922 if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
923 return NULL;
925 ret = ldb_schema_attribute_add(PyLdb_AsLdbContext(self), attribute, flags, syntax);
927 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
929 Py_RETURN_NONE;
932 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
934 if (ldif == NULL) {
935 Py_RETURN_NONE;
936 } else {
937 /* We don't want this attached to the 'ldb' any more */
938 return Py_BuildValue(discard_const_p(char, "(iO)"),
939 ldif->changetype,
940 PyLdbMessage_FromMessage(ldif->msg));
945 static PyObject *py_ldb_write_ldif(PyLdbMessageObject *self, PyObject *args)
947 int changetype;
948 PyObject *py_msg;
949 struct ldb_ldif ldif;
950 PyObject *ret;
951 char *string;
952 TALLOC_CTX *mem_ctx;
954 if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
955 return NULL;
957 if (!PyLdbMessage_Check(py_msg)) {
958 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
959 return NULL;
962 ldif.msg = PyLdbMessage_AsMessage(py_msg);
963 ldif.changetype = changetype;
965 mem_ctx = talloc_new(NULL);
967 string = ldb_ldif_write_string(PyLdb_AsLdbContext(self), mem_ctx, &ldif);
968 if (!string) {
969 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
970 return NULL;
973 ret = PyString_FromString(string);
975 talloc_free(mem_ctx);
977 return ret;
980 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
982 PyObject *list;
983 struct ldb_ldif *ldif;
984 const char *s;
986 TALLOC_CTX *mem_ctx;
988 if (!PyArg_ParseTuple(args, "s", &s))
989 return NULL;
991 mem_ctx = talloc_new(NULL);
992 if (!mem_ctx) {
993 Py_RETURN_NONE;
996 list = PyList_New(0);
997 while (s && *s != '\0') {
998 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
999 talloc_steal(mem_ctx, ldif);
1000 if (ldif) {
1001 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1002 } else {
1003 PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1004 talloc_free(mem_ctx);
1005 return NULL;
1008 talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1009 return PyObject_GetIter(list);
1012 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1014 PyObject *py_msg_old;
1015 PyObject *py_msg_new;
1016 struct ldb_message *diff;
1017 PyObject *py_ret;
1019 if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1020 return NULL;
1022 if (!PyLdbMessage_Check(py_msg_old)) {
1023 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1024 return NULL;
1027 if (!PyLdbMessage_Check(py_msg_new)) {
1028 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1029 return NULL;
1032 diff = ldb_msg_diff(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg_old), PyLdbMessage_AsMessage(py_msg_new));
1033 if (!diff) {
1034 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1035 return NULL;
1038 py_ret = PyLdbMessage_FromMessage(diff);
1040 return py_ret;
1043 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1045 const struct ldb_schema_attribute *a;
1046 struct ldb_val old_val;
1047 struct ldb_val new_val;
1048 TALLOC_CTX *mem_ctx;
1049 PyObject *ret;
1050 char *element_name;
1051 PyObject *val;
1053 if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1054 return NULL;
1056 mem_ctx = talloc_new(NULL);
1058 old_val.data = (uint8_t *)PyString_AsString(val);
1059 old_val.length = PyString_Size(val);
1061 a = ldb_schema_attribute_by_name(PyLdb_AsLdbContext(self), element_name);
1063 if (a == NULL) {
1064 Py_RETURN_NONE;
1067 if (a->syntax->ldif_write_fn(PyLdb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1068 talloc_free(mem_ctx);
1069 Py_RETURN_NONE;
1072 ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1074 talloc_free(mem_ctx);
1076 return ret;
1079 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1081 PyObject *py_base = Py_None;
1082 int scope = LDB_SCOPE_DEFAULT;
1083 char *expr = NULL;
1084 PyObject *py_attrs = Py_None;
1085 PyObject *py_controls = Py_None;
1086 const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1087 int ret;
1088 struct ldb_result *res;
1089 struct ldb_request *req;
1090 const char **attrs;
1091 struct ldb_context *ldb_ctx;
1092 struct ldb_control **parsed_controls;
1093 struct ldb_dn *base;
1094 PyObject *py_ret;
1096 /* type "int" rather than "enum" for "scope" is intentional */
1097 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1098 discard_const_p(char *, kwnames),
1099 &py_base, &scope, &expr, &py_attrs, &py_controls))
1100 return NULL;
1102 ldb_ctx = PyLdb_AsLdbContext(self);
1104 if (py_attrs == Py_None) {
1105 attrs = NULL;
1106 } else {
1107 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
1108 if (attrs == NULL)
1109 return NULL;
1112 if (py_base == Py_None) {
1113 base = ldb_get_default_basedn(ldb_ctx);
1114 } else {
1115 if (!PyObject_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1116 talloc_free(attrs);
1117 return NULL;
1121 if (py_controls == Py_None) {
1122 parsed_controls = NULL;
1123 } else {
1124 const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
1125 parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
1126 talloc_free(controls);
1129 res = talloc_zero(ldb_ctx, struct ldb_result);
1130 if (res == NULL) {
1131 PyErr_NoMemory();
1132 talloc_free(attrs);
1133 return NULL;
1136 ret = ldb_build_search_req(&req, ldb_ctx, ldb_ctx,
1137 base,
1138 scope,
1139 expr,
1140 attrs,
1141 parsed_controls,
1142 res,
1143 ldb_search_default_callback,
1144 NULL);
1146 talloc_steal(req, attrs);
1148 if (ret != LDB_SUCCESS) {
1149 talloc_free(res);
1150 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1151 return NULL;
1154 ret = ldb_request(ldb_ctx, req);
1156 if (ret == LDB_SUCCESS) {
1157 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1160 talloc_free(req);
1162 if (ret != LDB_SUCCESS) {
1163 talloc_free(res);
1164 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1165 return NULL;
1168 py_ret = PyLdbResult_FromResult(res);
1170 talloc_free(res);
1172 return py_ret;
1175 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1177 char *name;
1178 void *data;
1180 if (!PyArg_ParseTuple(args, "s", &name))
1181 return NULL;
1183 data = ldb_get_opaque(PyLdb_AsLdbContext(self), name);
1185 if (data == NULL)
1186 Py_RETURN_NONE;
1188 /* FIXME: More interpretation */
1190 return Py_True;
1193 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1195 char *name;
1196 PyObject *data;
1198 if (!PyArg_ParseTuple(args, "sO", &name, &data))
1199 return NULL;
1201 /* FIXME: More interpretation */
1203 ldb_set_opaque(PyLdb_AsLdbContext(self), name, data);
1205 Py_RETURN_NONE;
1208 static PyObject *py_ldb_modules(PyLdbObject *self)
1210 struct ldb_context *ldb = PyLdb_AsLdbContext(self);
1211 PyObject *ret = PyList_New(0);
1212 struct ldb_module *mod;
1214 for (mod = ldb->modules; mod; mod = mod->next) {
1215 PyList_Append(ret, PyLdbModule_FromModule(mod));
1218 return ret;
1221 static PyMethodDef py_ldb_methods[] = {
1222 { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS,
1223 "S.set_debug(callback) -> None\n"
1224 "Set callback for LDB debug messages.\n"
1225 "The callback should accept a debug level and debug text." },
1226 { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS,
1227 "S.set_create_perms(mode) -> None\n"
1228 "Set mode to use when creating new LDB files." },
1229 { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1230 "S.set_modules_dir(path) -> None\n"
1231 "Set path LDB should search for modules" },
1232 { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS,
1233 "S.transaction_start() -> None\n"
1234 "Start a new transaction." },
1235 { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1236 "S.transaction_prepare_commit() -> None\n"
1237 "prepare to commit a new transaction (2-stage commit)." },
1238 { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS,
1239 "S.transaction_commit() -> None\n"
1240 "commit a new transaction." },
1241 { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS,
1242 "S.transaction_cancel() -> None\n"
1243 "cancel a new transaction." },
1244 { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS,
1245 NULL },
1246 { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1247 NULL },
1248 { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1249 NULL },
1250 { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1251 NULL },
1252 { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1253 NULL },
1254 { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS,
1255 "S.connect(url, flags=0, options=None) -> None\n"
1256 "Connect to a LDB URL." },
1257 { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS,
1258 "S.modify(message) -> None\n"
1259 "Modify an entry." },
1260 { "add", (PyCFunction)py_ldb_add, METH_VARARGS,
1261 "S.add(message) -> None\n"
1262 "Add an entry." },
1263 { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS,
1264 "S.delete(dn) -> None\n"
1265 "Remove an entry." },
1266 { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS,
1267 "S.rename(old_dn, new_dn) -> None\n"
1268 "Rename an entry." },
1269 { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1270 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1271 "Search in a database.\n"
1272 "\n"
1273 ":param base: Optional base DN to search\n"
1274 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1275 ":param expression: Optional search expression\n"
1276 ":param attrs: Attributes to return (defaults to all)\n"
1277 ":param controls: Optional list of controls\n"
1278 ":return: Iterator over Message objects\n"
1280 { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1281 NULL },
1282 { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1283 NULL },
1284 { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1285 NULL },
1286 { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1287 "S.parse_ldif(ldif) -> iter(messages)\n"
1288 "Parse a string formatted using LDIF." },
1289 { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1290 "S.write_ldif(message, changetype) -> ldif\n"
1291 "Print the message as a string formatted using LDIF." },
1292 { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1293 "S.msg_diff(Message) -> Message\n"
1294 "Return an LDB Message of the difference between two Message objects." },
1295 { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1296 "S.get_opaque(name) -> value\n"
1297 "Get an opaque value set on this LDB connection. \n"
1298 ":note: The returned value may not be useful in Python."
1300 { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1301 "S.set_opaque(name, value) -> None\n"
1302 "Set an opaque value on this LDB connection. \n"
1303 ":note: Passing incorrect values may cause crashes." },
1304 { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1305 "S.modules() -> list\n"
1306 "Return the list of modules on this LDB connection " },
1307 { NULL },
1310 PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1312 PyLdbModuleObject *ret;
1314 ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1315 if (ret == NULL) {
1316 PyErr_NoMemory();
1317 return NULL;
1319 ret->mem_ctx = talloc_new(NULL);
1320 ret->mod = talloc_reference(ret->mem_ctx, mod);
1321 return (PyObject *)ret;
1324 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1326 return PyLdbModule_FromModule(PyLdb_AsLdbContext(self)->modules);
1329 static PyGetSetDef py_ldb_getset[] = {
1330 { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1331 { NULL }
1334 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1336 struct ldb_context *ldb_ctx = PyLdb_AsLdbContext(self);
1337 struct ldb_dn *dn;
1338 struct ldb_result *result;
1339 int ret;
1340 int count;
1342 if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn))
1343 return -1;
1345 ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, NULL);
1346 if (ret != LDB_SUCCESS) {
1347 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1348 return -1;
1351 count = result->count;
1353 talloc_free(result);
1355 return count;
1358 static PySequenceMethods py_ldb_seq = {
1359 .sq_contains = (objobjproc)py_ldb_contains,
1362 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1364 PyLdbObject *ret;
1366 ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1367 if (ret == NULL) {
1368 PyErr_NoMemory();
1369 return NULL;
1371 ret->mem_ctx = talloc_new(NULL);
1372 ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1373 return (PyObject *)ret;
1376 static void py_ldb_dealloc(PyLdbObject *self)
1378 talloc_free(self->mem_ctx);
1379 self->ob_type->tp_free(self);
1382 PyTypeObject PyLdb = {
1383 .tp_name = "Ldb",
1384 .tp_methods = py_ldb_methods,
1385 .tp_repr = (reprfunc)py_ldb_repr,
1386 .tp_new = py_ldb_new,
1387 .tp_init = (initproc)py_ldb_init,
1388 .tp_dealloc = (destructor)py_ldb_dealloc,
1389 .tp_getset = py_ldb_getset,
1390 .tp_getattro = PyObject_GenericGetAttr,
1391 .tp_basicsize = sizeof(PyLdbObject),
1392 .tp_doc = "Connection to a LDB database.",
1393 .tp_as_sequence = &py_ldb_seq,
1394 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1397 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1399 return PyString_FromFormat("<ldb module '%s'>", PyLdbModule_AsModule(self)->ops->name);
1402 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1404 return PyString_FromString(PyLdbModule_AsModule(self)->ops->name);
1407 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1409 PyLdbModule_AsModule(self)->ops->start_transaction(PyLdbModule_AsModule(self));
1410 Py_RETURN_NONE;
1413 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1415 PyLdbModule_AsModule(self)->ops->end_transaction(PyLdbModule_AsModule(self));
1416 Py_RETURN_NONE;
1419 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
1421 PyLdbModule_AsModule(self)->ops->del_transaction(PyLdbModule_AsModule(self));
1422 Py_RETURN_NONE;
1425 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
1427 PyObject *py_base, *py_tree, *py_attrs, *py_ret;
1428 int ret, scope;
1429 struct ldb_request *req;
1430 const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
1431 struct ldb_module *mod;
1432 const char * const*attrs;
1434 /* type "int" rather than "enum" for "scope" is intentional */
1435 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
1436 discard_const_p(char *, kwnames),
1437 &py_base, &scope, &py_tree, &py_attrs))
1438 return NULL;
1440 mod = self->mod;
1442 if (py_attrs == Py_None) {
1443 attrs = NULL;
1444 } else {
1445 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
1446 if (attrs == NULL)
1447 return NULL;
1450 ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base),
1451 scope, NULL /* expr */, attrs,
1452 NULL /* controls */, NULL, NULL, NULL);
1454 talloc_steal(req, attrs);
1456 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1458 req->op.search.res = NULL;
1460 ret = mod->ops->search(mod, req);
1462 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1464 py_ret = PyLdbResult_FromResult(req->op.search.res);
1466 talloc_free(req);
1468 return py_ret;
1472 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
1474 struct ldb_request *req;
1475 PyObject *py_message;
1476 int ret;
1477 struct ldb_module *mod;
1479 if (!PyArg_ParseTuple(args, "O", &py_message))
1480 return NULL;
1482 req = talloc_zero(NULL, struct ldb_request);
1483 req->operation = LDB_ADD;
1484 req->op.add.message = PyLdbMessage_AsMessage(py_message);
1486 mod = PyLdbModule_AsModule(self);
1487 ret = mod->ops->add(mod, req);
1489 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1491 Py_RETURN_NONE;
1494 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args)
1496 int ret;
1497 struct ldb_request *req;
1498 PyObject *py_message;
1499 struct ldb_module *mod;
1501 if (!PyArg_ParseTuple(args, "O", &py_message))
1502 return NULL;
1504 req = talloc_zero(NULL, struct ldb_request);
1505 req->operation = LDB_MODIFY;
1506 req->op.mod.message = PyLdbMessage_AsMessage(py_message);
1508 mod = PyLdbModule_AsModule(self);
1509 ret = mod->ops->modify(mod, req);
1511 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1513 Py_RETURN_NONE;
1516 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args)
1518 int ret;
1519 struct ldb_request *req;
1520 PyObject *py_dn;
1522 if (!PyArg_ParseTuple(args, "O", &py_dn))
1523 return NULL;
1525 req = talloc_zero(NULL, struct ldb_request);
1526 req->operation = LDB_DELETE;
1527 req->op.del.dn = PyLdbDn_AsDn(py_dn);
1529 ret = PyLdbModule_AsModule(self)->ops->del(PyLdbModule_AsModule(self), req);
1531 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1533 Py_RETURN_NONE;
1536 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
1538 int ret;
1539 struct ldb_request *req;
1540 PyObject *py_dn1, *py_dn2;
1542 if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
1543 return NULL;
1545 req = talloc_zero(NULL, struct ldb_request);
1547 req->operation = LDB_RENAME;
1548 req->op.rename.olddn = PyLdbDn_AsDn(py_dn1);
1549 req->op.rename.newdn = PyLdbDn_AsDn(py_dn2);
1551 ret = PyLdbModule_AsModule(self)->ops->rename(PyLdbModule_AsModule(self), req);
1553 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1555 Py_RETURN_NONE;
1558 static PyMethodDef py_ldb_module_methods[] = {
1559 { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
1560 { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
1561 { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
1562 { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
1563 { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
1564 { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
1565 { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
1566 { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
1567 { NULL },
1570 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
1572 talloc_free(self->mem_ctx);
1573 self->ob_type->tp_free(self);
1576 PyTypeObject PyLdbModule = {
1577 .tp_name = "LdbModule",
1578 .tp_methods = py_ldb_module_methods,
1579 .tp_repr = (reprfunc)py_ldb_module_repr,
1580 .tp_str = (reprfunc)py_ldb_module_str,
1581 .tp_basicsize = sizeof(PyLdbModuleObject),
1582 .tp_dealloc = (destructor)py_ldb_module_dealloc,
1583 .tp_flags = Py_TPFLAGS_DEFAULT,
1588 * Create a ldb_message_element from a Python object.
1590 * This will accept any sequence objects that contains strings, or
1591 * a string object.
1593 * A reference to set_obj will be borrowed.
1595 * @param mem_ctx Memory context
1596 * @param set_obj Python object to convert
1597 * @param flags ldb_message_element flags to set
1598 * @param attr_name Name of the attribute
1599 * @return New ldb_message_element, allocated as child of mem_ctx
1601 struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
1602 PyObject *set_obj, int flags,
1603 const char *attr_name)
1605 struct ldb_message_element *me;
1607 if (PyLdbMessageElement_Check(set_obj))
1608 return talloc_reference(mem_ctx,
1609 PyLdbMessageElement_AsMessageElement(set_obj));
1611 me = talloc(mem_ctx, struct ldb_message_element);
1613 me->name = talloc_strdup(me, attr_name);
1614 me->flags = flags;
1615 if (PyString_Check(set_obj)) {
1616 me->num_values = 1;
1617 me->values = talloc_array(me, struct ldb_val, me->num_values);
1618 me->values[0].length = PyString_Size(set_obj);
1619 me->values[0].data = talloc_memdup(me,
1620 (uint8_t *)PyString_AsString(set_obj), me->values[0].length);
1621 } else if (PySequence_Check(set_obj)) {
1622 int i;
1623 me->num_values = PySequence_Size(set_obj);
1624 me->values = talloc_array(me, struct ldb_val, me->num_values);
1625 for (i = 0; i < me->num_values; i++) {
1626 PyObject *obj = PySequence_GetItem(set_obj, i);
1628 me->values[i].length = PyString_Size(obj);
1629 me->values[i].data = talloc_memdup(me,
1630 (uint8_t *)PyString_AsString(obj), me->values[i].length);
1632 } else {
1633 talloc_free(me);
1634 me = NULL;
1637 return me;
1641 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
1642 struct ldb_message_element *me)
1644 int i;
1645 PyObject *result;
1647 /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
1648 result = PyList_New(me->num_values);
1650 for (i = 0; i < me->num_values; i++) {
1651 PyList_SetItem(result, i,
1652 PyObject_FromLdbValue(ldb_ctx, me, &me->values[i]));
1655 return result;
1658 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
1660 int i;
1661 if (!PyArg_ParseTuple(args, "i", &i))
1662 return NULL;
1663 if (i < 0 || i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
1664 Py_RETURN_NONE;
1666 return PyObject_FromLdbValue(NULL, PyLdbMessageElement_AsMessageElement(self),
1667 &(PyLdbMessageElement_AsMessageElement(self)->values[i]));
1670 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
1672 struct ldb_message_element *el;
1674 el = PyLdbMessageElement_AsMessageElement(self);
1675 return PyInt_FromLong(el->flags);
1678 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
1680 int flags;
1681 struct ldb_message_element *el;
1682 if (!PyArg_ParseTuple(args, "i", &flags))
1683 return NULL;
1685 el = PyLdbMessageElement_AsMessageElement(self);
1686 el->flags = flags;
1687 Py_RETURN_NONE;
1690 static PyMethodDef py_ldb_msg_element_methods[] = {
1691 { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
1692 { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
1693 { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
1694 { NULL },
1697 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
1699 return PyLdbMessageElement_AsMessageElement(self)->num_values;
1702 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
1704 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1705 if (idx < 0 || idx >= el->num_values) {
1706 PyErr_SetString(PyExc_IndexError, "Out of range");
1707 return NULL;
1709 return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
1712 static PySequenceMethods py_ldb_msg_element_seq = {
1713 .sq_length = (lenfunc)py_ldb_msg_element_len,
1714 .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
1717 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
1719 return ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self),
1720 PyLdbMessageElement_AsMessageElement(other));
1723 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
1725 return PyObject_GetIter(ldb_msg_element_to_set(NULL, PyLdbMessageElement_AsMessageElement(self)));
1728 PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
1730 PyLdbMessageElementObject *ret;
1731 ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
1732 if (ret == NULL) {
1733 PyErr_NoMemory();
1734 return NULL;
1736 ret->mem_ctx = talloc_new(NULL);
1737 if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
1738 PyErr_NoMemory();
1739 return NULL;
1741 ret->el = el;
1742 return (PyObject *)ret;
1745 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1747 PyObject *py_elements = NULL;
1748 struct ldb_message_element *el;
1749 int flags = 0;
1750 char *name = NULL;
1751 const char * const kwnames[] = { "elements", "flags", "name", NULL };
1752 PyLdbMessageElementObject *ret;
1753 TALLOC_CTX *mem_ctx;
1755 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Ois",
1756 discard_const_p(char *, kwnames),
1757 &py_elements, &flags, &name))
1758 return NULL;
1760 mem_ctx = talloc_new(NULL);
1761 if (mem_ctx == NULL) {
1762 PyErr_NoMemory();
1763 return NULL;
1766 el = talloc_zero(mem_ctx, struct ldb_message_element);
1768 if (py_elements != NULL) {
1769 int i;
1770 if (PyString_Check(py_elements)) {
1771 el->num_values = 1;
1772 el->values = talloc_array(el, struct ldb_val, 1);
1773 el->values[0].length = PyString_Size(py_elements);
1774 el->values[0].data = talloc_memdup(el,
1775 (uint8_t *)PyString_AsString(py_elements), el->values[0].length);
1776 } else if (PySequence_Check(py_elements)) {
1777 el->num_values = PySequence_Size(py_elements);
1778 el->values = talloc_array(el, struct ldb_val, el->num_values);
1779 for (i = 0; i < el->num_values; i++) {
1780 PyObject *item = PySequence_GetItem(py_elements, i);
1781 if (!PyString_Check(item)) {
1782 PyErr_Format(PyExc_TypeError,
1783 "Expected string as element %d in list",
1785 talloc_free(mem_ctx);
1786 return NULL;
1788 el->values[i].length = PyString_Size(item);
1789 el->values[i].data = talloc_memdup(el,
1790 (uint8_t *)PyString_AsString(item), el->values[i].length);
1792 } else {
1793 PyErr_SetString(PyExc_TypeError,
1794 "Expected string or list");
1795 talloc_free(mem_ctx);
1796 return NULL;
1800 el->flags = flags;
1801 el->name = talloc_strdup(el, name);
1803 ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
1804 if (ret == NULL) {
1805 PyErr_NoMemory();
1806 talloc_free(mem_ctx);
1807 return NULL;
1810 ret->mem_ctx = mem_ctx;
1811 ret->el = el;
1812 return (PyObject *)ret;
1815 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
1817 char *element_str = NULL;
1818 int i;
1819 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1820 PyObject *ret;
1822 for (i = 0; i < el->num_values; i++) {
1823 PyObject *o = py_ldb_msg_element_find(self, i);
1824 if (element_str == NULL)
1825 element_str = talloc_strdup(NULL, PyObject_REPR(o));
1826 else
1827 element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
1830 ret = PyString_FromFormat("MessageElement([%s])", element_str);
1832 talloc_free(element_str);
1834 return ret;
1837 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
1839 struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1841 if (el->num_values == 1)
1842 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
1843 else
1844 Py_RETURN_NONE;
1847 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
1849 talloc_free(self->mem_ctx);
1850 self->ob_type->tp_free(self);
1853 PyTypeObject PyLdbMessageElement = {
1854 .tp_name = "MessageElement",
1855 .tp_basicsize = sizeof(PyLdbMessageElementObject),
1856 .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
1857 .tp_repr = (reprfunc)py_ldb_msg_element_repr,
1858 .tp_str = (reprfunc)py_ldb_msg_element_str,
1859 .tp_methods = py_ldb_msg_element_methods,
1860 .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
1861 .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
1862 .tp_as_sequence = &py_ldb_msg_element_seq,
1863 .tp_new = py_ldb_msg_element_new,
1864 .tp_flags = Py_TPFLAGS_DEFAULT,
1867 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
1869 char *name;
1870 if (!PyArg_ParseTuple(args, "s", &name))
1871 return NULL;
1873 ldb_msg_remove_attr(self->msg, name);
1875 Py_RETURN_NONE;
1878 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
1880 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1881 int i, j = 0;
1882 PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
1883 if (msg->dn != NULL) {
1884 PyList_SetItem(obj, j, PyString_FromString("dn"));
1885 j++;
1887 for (i = 0; i < msg->num_elements; i++) {
1888 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
1889 j++;
1891 return obj;
1894 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
1896 struct ldb_message_element *el;
1897 char *name;
1898 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1899 if (!PyString_Check(py_name)) {
1900 PyErr_SetNone(PyExc_TypeError);
1901 return NULL;
1903 name = PyString_AsString(py_name);
1904 if (!strcmp(name, "dn"))
1905 return PyLdbDn_FromDn(msg->dn);
1906 el = ldb_msg_find_element(msg, name);
1907 if (el == NULL) {
1908 return NULL;
1910 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg);
1913 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
1915 PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
1916 if (ret == NULL) {
1917 PyErr_SetString(PyExc_KeyError, "No such element");
1918 return NULL;
1920 return ret;
1923 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args)
1925 PyObject *name, *ret;
1926 if (!PyArg_ParseTuple(args, "O", &name))
1927 return NULL;
1929 ret = py_ldb_msg_getitem_helper(self, name);
1930 if (ret == NULL) {
1931 if (PyErr_Occurred())
1932 return NULL;
1933 Py_RETURN_NONE;
1935 return ret;
1938 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
1940 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1941 int i, j;
1942 PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
1943 j = 0;
1944 if (msg->dn != NULL) {
1945 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn)));
1946 j++;
1948 for (i = 0; i < msg->num_elements; i++, j++) {
1949 PyList_SetItem(l, j, Py_BuildValue("(sO)", msg->elements[i].name, PyLdbMessageElement_FromMessageElement(&msg->elements[i], self->msg)));
1951 return l;
1954 static PyMethodDef py_ldb_msg_methods[] = {
1955 { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, NULL },
1956 { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, NULL },
1957 { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL },
1958 { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
1959 { NULL },
1962 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
1964 PyObject *list, *iter;
1966 list = py_ldb_msg_keys(self);
1967 iter = PyObject_GetIter(list);
1968 Py_DECREF(list);
1969 return iter;
1972 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
1974 char *attr_name;
1976 if (!PyString_Check(name)) {
1977 PyErr_SetNone(PyExc_TypeError);
1978 return -1;
1981 attr_name = PyString_AsString(name);
1982 if (value == NULL) {
1983 /* delitem */
1984 ldb_msg_remove_attr(self->msg, attr_name);
1985 } else {
1986 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
1987 value, 0, attr_name);
1988 if (el == NULL)
1989 return -1;
1990 ldb_msg_remove_attr(PyLdbMessage_AsMessage(self), attr_name);
1991 ldb_msg_add(PyLdbMessage_AsMessage(self), el, el->flags);
1993 return 0;
1996 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
1998 return PyLdbMessage_AsMessage(self)->num_elements;
2001 static PyMappingMethods py_ldb_msg_mapping = {
2002 .mp_length = (lenfunc)py_ldb_msg_length,
2003 .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2004 .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2007 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2009 const char * const kwnames[] = { "dn", NULL };
2010 struct ldb_message *ret;
2011 TALLOC_CTX *mem_ctx;
2012 PyObject *pydn = NULL;
2013 PyLdbMessageObject *py_ret;
2015 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2016 discard_const_p(char *, kwnames),
2017 &pydn))
2018 return NULL;
2020 mem_ctx = talloc_new(NULL);
2021 if (mem_ctx == NULL) {
2022 PyErr_NoMemory();
2023 return NULL;
2026 ret = ldb_msg_new(mem_ctx);
2027 if (ret == NULL) {
2028 talloc_free(mem_ctx);
2029 PyErr_NoMemory();
2030 return NULL;
2033 if (pydn != NULL) {
2034 struct ldb_dn *dn;
2035 if (!PyObject_AsDn(NULL, pydn, NULL, &dn)) {
2036 talloc_free(mem_ctx);
2037 return NULL;
2039 ret->dn = talloc_reference(ret, dn);
2042 py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2043 if (py_ret == NULL) {
2044 PyErr_NoMemory();
2045 talloc_free(mem_ctx);
2046 return NULL;
2049 py_ret->mem_ctx = mem_ctx;
2050 py_ret->msg = ret;
2051 return (PyObject *)py_ret;
2054 PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2056 PyLdbMessageObject *ret;
2058 ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2059 if (ret == NULL) {
2060 PyErr_NoMemory();
2061 return NULL;
2063 ret->mem_ctx = talloc_new(NULL);
2064 ret->msg = talloc_reference(ret->mem_ctx, msg);
2065 return (PyObject *)ret;
2068 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2070 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2071 return PyLdbDn_FromDn(msg->dn);
2074 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2076 struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2077 if (!PyLdbDn_Check(value)) {
2078 PyErr_SetNone(PyExc_TypeError);
2079 return -1;
2082 msg->dn = talloc_reference(msg, PyLdbDn_AsDn(value));
2083 return 0;
2086 static PyGetSetDef py_ldb_msg_getset[] = {
2087 { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2088 { NULL }
2091 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2093 PyObject *dict = PyDict_New(), *ret;
2094 if (PyDict_Update(dict, (PyObject *)self) != 0)
2095 return NULL;
2096 ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2097 Py_DECREF(dict);
2098 return ret;
2101 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2103 talloc_free(self->mem_ctx);
2104 self->ob_type->tp_free(self);
2107 PyTypeObject PyLdbMessage = {
2108 .tp_name = "Message",
2109 .tp_methods = py_ldb_msg_methods,
2110 .tp_getset = py_ldb_msg_getset,
2111 .tp_as_mapping = &py_ldb_msg_mapping,
2112 .tp_basicsize = sizeof(PyLdbMessageObject),
2113 .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2114 .tp_new = py_ldb_msg_new,
2115 .tp_repr = (reprfunc)py_ldb_msg_repr,
2116 .tp_flags = Py_TPFLAGS_DEFAULT,
2117 .tp_iter = (getiterfunc)py_ldb_msg_iter,
2120 PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2122 PyLdbTreeObject *ret;
2124 ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2125 if (ret == NULL) {
2126 PyErr_NoMemory();
2127 return NULL;
2130 ret->mem_ctx = talloc_new(NULL);
2131 ret->tree = talloc_reference(ret->mem_ctx, tree);
2132 return (PyObject *)ret;
2135 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2137 talloc_free(self->mem_ctx);
2138 self->ob_type->tp_free(self);
2141 PyTypeObject PyLdbTree = {
2142 .tp_name = "Tree",
2143 .tp_basicsize = sizeof(PyLdbTreeObject),
2144 .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2145 .tp_flags = Py_TPFLAGS_DEFAULT,
2148 /* Ldb_module */
2149 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2151 PyObject *py_ldb = (PyObject *)mod->private_data;
2152 PyObject *py_result, *py_base, *py_attrs, *py_tree;
2154 py_base = PyLdbDn_FromDn(req->op.search.base);
2156 if (py_base == NULL)
2157 return LDB_ERR_OPERATIONS_ERROR;
2159 py_tree = PyLdbTree_FromTree(req->op.search.tree);
2161 if (py_tree == NULL)
2162 return LDB_ERR_OPERATIONS_ERROR;
2164 if (req->op.search.attrs == NULL) {
2165 py_attrs = Py_None;
2166 } else {
2167 int i, len;
2168 for (len = 0; req->op.search.attrs[len]; len++);
2169 py_attrs = PyList_New(len);
2170 for (i = 0; i < len; i++)
2171 PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2174 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2175 discard_const_p(char, "OiOO"),
2176 py_base, req->op.search.scope, py_tree, py_attrs);
2178 Py_DECREF(py_attrs);
2179 Py_DECREF(py_tree);
2180 Py_DECREF(py_base);
2182 if (py_result == NULL) {
2183 return LDB_ERR_PYTHON_EXCEPTION;
2186 req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2187 if (req->op.search.res == NULL) {
2188 return LDB_ERR_PYTHON_EXCEPTION;
2191 Py_DECREF(py_result);
2193 return LDB_SUCCESS;
2196 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2198 PyObject *py_ldb = (PyObject *)mod->private_data;
2199 PyObject *py_result, *py_msg;
2201 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2203 if (py_msg == NULL) {
2204 return LDB_ERR_OPERATIONS_ERROR;
2207 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2208 discard_const_p(char, "O"),
2209 py_msg);
2211 Py_DECREF(py_msg);
2213 if (py_result == NULL) {
2214 return LDB_ERR_PYTHON_EXCEPTION;
2217 Py_DECREF(py_result);
2219 return LDB_SUCCESS;
2222 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
2224 PyObject *py_ldb = (PyObject *)mod->private_data;
2225 PyObject *py_result, *py_msg;
2227 py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
2229 if (py_msg == NULL) {
2230 return LDB_ERR_OPERATIONS_ERROR;
2233 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
2234 discard_const_p(char, "O"),
2235 py_msg);
2237 Py_DECREF(py_msg);
2239 if (py_result == NULL) {
2240 return LDB_ERR_PYTHON_EXCEPTION;
2243 Py_DECREF(py_result);
2245 return LDB_SUCCESS;
2248 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
2250 PyObject *py_ldb = (PyObject *)mod->private_data;
2251 PyObject *py_result, *py_dn;
2253 py_dn = PyLdbDn_FromDn(req->op.del.dn);
2255 if (py_dn == NULL)
2256 return LDB_ERR_OPERATIONS_ERROR;
2258 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
2259 discard_const_p(char, "O"),
2260 py_dn);
2262 if (py_result == NULL) {
2263 return LDB_ERR_PYTHON_EXCEPTION;
2266 Py_DECREF(py_result);
2268 return LDB_SUCCESS;
2271 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
2273 PyObject *py_ldb = (PyObject *)mod->private_data;
2274 PyObject *py_result, *py_olddn, *py_newdn;
2276 py_olddn = PyLdbDn_FromDn(req->op.rename.olddn);
2278 if (py_olddn == NULL)
2279 return LDB_ERR_OPERATIONS_ERROR;
2281 py_newdn = PyLdbDn_FromDn(req->op.rename.newdn);
2283 if (py_newdn == NULL)
2284 return LDB_ERR_OPERATIONS_ERROR;
2286 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
2287 discard_const_p(char, "OO"),
2288 py_olddn, py_newdn);
2290 Py_DECREF(py_olddn);
2291 Py_DECREF(py_newdn);
2293 if (py_result == NULL) {
2294 return LDB_ERR_PYTHON_EXCEPTION;
2297 Py_DECREF(py_result);
2299 return LDB_SUCCESS;
2302 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
2304 PyObject *py_ldb = (PyObject *)mod->private_data;
2305 PyObject *py_result;
2307 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
2308 discard_const_p(char, ""));
2310 return LDB_ERR_OPERATIONS_ERROR;
2313 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
2315 PyObject *py_ldb = (PyObject *)mod->private_data;
2316 PyObject *py_result;
2318 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
2319 discard_const_p(char, ""));
2321 return LDB_ERR_OPERATIONS_ERROR;
2324 static int py_module_start_transaction(struct ldb_module *mod)
2326 PyObject *py_ldb = (PyObject *)mod->private_data;
2327 PyObject *py_result;
2329 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
2330 discard_const_p(char, ""));
2332 if (py_result == NULL) {
2333 return LDB_ERR_PYTHON_EXCEPTION;
2336 Py_DECREF(py_result);
2338 return LDB_SUCCESS;
2341 static int py_module_end_transaction(struct ldb_module *mod)
2343 PyObject *py_ldb = (PyObject *)mod->private_data;
2344 PyObject *py_result;
2346 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
2347 discard_const_p(char, ""));
2349 if (py_result == NULL) {
2350 return LDB_ERR_PYTHON_EXCEPTION;
2353 Py_DECREF(py_result);
2355 return LDB_SUCCESS;
2358 static int py_module_del_transaction(struct ldb_module *mod)
2360 PyObject *py_ldb = (PyObject *)mod->private_data;
2361 PyObject *py_result;
2363 py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
2364 discard_const_p(char, ""));
2366 if (py_result == NULL) {
2367 return LDB_ERR_PYTHON_EXCEPTION;
2370 Py_DECREF(py_result);
2372 return LDB_SUCCESS;
2375 static int py_module_destructor(struct ldb_module *mod)
2377 Py_DECREF((PyObject *)mod->private_data);
2378 return 0;
2381 static int py_module_init(struct ldb_module *mod)
2383 PyObject *py_class = (PyObject *)mod->ops->private_data;
2384 PyObject *py_result, *py_next, *py_ldb;
2386 py_ldb = PyLdb_FromLdbContext(mod->ldb);
2388 if (py_ldb == NULL)
2389 return LDB_ERR_OPERATIONS_ERROR;
2391 py_next = PyLdbModule_FromModule(mod->next);
2393 if (py_next == NULL)
2394 return LDB_ERR_OPERATIONS_ERROR;
2396 py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
2397 py_ldb, py_next);
2399 if (py_result == NULL) {
2400 return LDB_ERR_PYTHON_EXCEPTION;
2403 mod->private_data = py_result;
2405 talloc_set_destructor(mod, py_module_destructor);
2407 return ldb_next_init(mod);
2410 static PyObject *py_register_module(PyObject *module, PyObject *args)
2412 int ret;
2413 struct ldb_module_ops *ops;
2414 PyObject *input;
2416 if (!PyArg_ParseTuple(args, "O", &input))
2417 return NULL;
2419 ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
2420 if (ops == NULL) {
2421 PyErr_NoMemory();
2422 return NULL;
2425 ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
2427 Py_INCREF(input);
2428 ops->private_data = input;
2429 ops->init_context = py_module_init;
2430 ops->search = py_module_search;
2431 ops->add = py_module_add;
2432 ops->modify = py_module_modify;
2433 ops->del = py_module_del;
2434 ops->rename = py_module_rename;
2435 ops->request = py_module_request;
2436 ops->extended = py_module_extended;
2437 ops->start_transaction = py_module_start_transaction;
2438 ops->end_transaction = py_module_end_transaction;
2439 ops->del_transaction = py_module_del_transaction;
2441 ret = ldb_register_module(ops);
2443 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2445 Py_RETURN_NONE;
2448 static PyObject *py_timestring(PyObject *module, PyObject *args)
2450 time_t t;
2451 unsigned long val;
2452 char *tresult;
2453 PyObject *ret;
2454 if (!PyArg_ParseTuple(args, "l", &val))
2455 return NULL;
2456 t = (time_t)val;
2457 tresult = ldb_timestring(NULL, t);
2458 ret = PyString_FromString(tresult);
2459 talloc_free(tresult);
2460 return ret;
2463 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
2465 char *str;
2466 if (!PyArg_ParseTuple(args, "s", &str))
2467 return NULL;
2469 return PyInt_FromLong(ldb_string_to_time(str));
2472 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
2474 char *name;
2475 if (!PyArg_ParseTuple(args, "s", &name))
2476 return NULL;
2477 return PyBool_FromLong(ldb_valid_attr_name(name));
2480 static PyMethodDef py_ldb_global_methods[] = {
2481 { "register_module", py_register_module, METH_VARARGS,
2482 "S.register_module(module) -> None\n"
2483 "Register a LDB module."},
2484 { "timestring", py_timestring, METH_VARARGS,
2485 "S.timestring(int) -> string\n"
2486 "Generate a LDAP time string from a UNIX timestamp" },
2487 { "string_to_time", py_string_to_time, METH_VARARGS,
2488 "S.string_to_time(string) -> int\n"
2489 "Parse a LDAP time string into a UNIX timestamp." },
2490 { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
2491 "S.valid_attr_name(name) -> bool\n"
2492 "Check whether the supplied name is a valid attribute name." },
2493 { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
2494 NULL },
2495 { NULL }
2498 void initldb(void)
2500 PyObject *m;
2502 if (PyType_Ready(&PyLdbDn) < 0)
2503 return;
2505 if (PyType_Ready(&PyLdbMessage) < 0)
2506 return;
2508 if (PyType_Ready(&PyLdbMessageElement) < 0)
2509 return;
2511 if (PyType_Ready(&PyLdb) < 0)
2512 return;
2514 if (PyType_Ready(&PyLdbModule) < 0)
2515 return;
2517 if (PyType_Ready(&PyLdbTree) < 0)
2518 return;
2520 m = Py_InitModule3("ldb", py_ldb_global_methods,
2521 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
2522 if (m == NULL)
2523 return;
2525 PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
2526 PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
2527 PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
2528 PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
2530 PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
2531 PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
2532 PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
2533 PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
2535 PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
2536 PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
2537 PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
2539 PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
2540 PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
2541 PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
2542 PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
2543 PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
2544 PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
2545 PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
2546 PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
2547 PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
2548 PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
2549 PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
2550 PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
2551 PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
2552 PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
2553 PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
2554 PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
2555 PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
2556 PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
2557 PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
2558 PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
2559 PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
2560 PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
2561 PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
2562 PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
2563 PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
2564 PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
2565 PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
2566 PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
2567 PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
2568 PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
2569 PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
2570 PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
2571 PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
2572 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
2573 PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
2574 PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
2575 PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
2576 PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
2577 PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
2579 PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
2580 PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
2581 PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
2582 PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
2585 PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
2587 PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
2588 PyModule_AddObject(m, "LdbError", PyExc_LdbError);
2590 Py_INCREF(&PyLdb);
2591 Py_INCREF(&PyLdbDn);
2592 Py_INCREF(&PyLdbModule);
2593 Py_INCREF(&PyLdbMessage);
2594 Py_INCREF(&PyLdbMessageElement);
2595 Py_INCREF(&PyLdbTree);
2597 PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
2598 PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
2599 PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
2600 PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
2601 PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
2602 PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);