c2d75b43d3e289731e7f5be5662891f667987c6a
[ira/wip.git] / source4 / lib / ldb / pyldb.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Python interface to ldb.
5
6    Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7    Copyright (C) 2006 Simo Sorce <idra@samba.org>
8    Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9    Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10
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
14
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.
19
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.
24
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/>.
27 */
28
29 #include <Python.h>
30 #include <pytalloc.h>
31 #include "ldb_private.h"
32 #include "pyldb.h"
33
34 void initldb(void);
35 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
36 static PyObject *PyExc_LdbError;
37
38 staticforward PyTypeObject PyLdbMessage;
39 staticforward PyTypeObject PyLdbModule;
40 staticforward PyTypeObject PyLdbDn;
41 staticforward PyTypeObject PyLdb;
42 staticforward PyTypeObject PyLdbMessageElement;
43 staticforward PyTypeObject PyLdbTree;
44 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
45 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
46 static struct ldb_message_element *PyObject_AsMessageElement(
47                                                       TALLOC_CTX *mem_ctx,
48                                                       PyObject *set_obj,
49                                                       int flags,
50                                                       const char *attr_name);
51
52 /* There's no Py_ssize_t in 2.4, apparently */
53 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
54 typedef int Py_ssize_t;
55 typedef inquiry lenfunc;
56 typedef intargfunc ssizeargfunc;
57 #endif
58
59 #ifndef Py_RETURN_NONE
60 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
61 #endif
62
63 #define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
64
65 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
66 {
67         if (ret == LDB_ERR_PYTHON_EXCEPTION)
68                 return; /* Python exception should already be set, just keep that */
69
70         PyErr_SetObject(error, 
71                         Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
72                                       ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
73 }
74
75 static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx, 
76                                        struct ldb_message_element *el,
77                                        struct ldb_val *val)
78 {
79         struct ldb_val new_val;
80         TALLOC_CTX *mem_ctx = talloc_new(NULL);
81         PyObject *ret;
82
83         new_val = *val;
84
85         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
86
87         talloc_free(mem_ctx);
88
89         return ret;
90 }
91
92 /**
93  * Create a Python object from a ldb_result.
94  *
95  * @param result LDB result to convert
96  * @return Python object with converted result (a list object)
97  */
98 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
99 {
100         PyObject *ret;
101         Py_ssize_t i;
102         if (result == NULL) {
103                 Py_RETURN_NONE;
104         } 
105         ret = PyList_New(result->count);
106         for (i = 0; i < result->count; i++) {
107                 PyList_SetItem(ret, i, PyLdbMessage_FromMessage(result->msgs[i]));
108         }
109         return ret;
110 }
111
112 /**
113  * Create a LDB Result from a Python object. 
114  * If conversion fails, NULL will be returned and a Python exception set.
115  *
116  * @param mem_ctx Memory context in which to allocate the LDB Result
117  * @param obj Python object to convert
118  * @return a ldb_result, or NULL if the conversion failed
119  */
120 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, 
121                                                PyObject *obj)
122 {
123         struct ldb_result *res;
124         Py_ssize_t i;
125
126         if (obj == Py_None)
127                 return NULL;
128
129         res = talloc_zero(mem_ctx, struct ldb_result);
130         res->count = PyList_Size(obj);
131         res->msgs = talloc_array(res, struct ldb_message *, res->count);
132         for (i = 0; i < res->count; i++) {
133                 PyObject *item = PyList_GetItem(obj, i);
134                 res->msgs[i] = PyLdbMessage_AsMessage(item);
135         }
136         return res;
137 }
138
139 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
140 {
141         return PyBool_FromLong(ldb_dn_validate(self->dn));
142 }
143
144 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
145 {
146         return PyBool_FromLong(ldb_dn_is_valid(self->dn));
147 }
148
149 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
150 {
151         return PyBool_FromLong(ldb_dn_is_special(self->dn));
152 }
153
154 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
155 {
156         return PyBool_FromLong(ldb_dn_is_null(self->dn));
157 }
158  
159 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
160 {
161         return PyString_FromString(ldb_dn_get_casefold(self->dn));
162 }
163
164 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
165 {
166         return PyString_FromString(ldb_dn_get_linearized(self->dn));
167 }
168
169 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
170 {
171         return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
172 }
173
174 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
175 {
176         return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
177 }
178
179 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
180 {
181         return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
182 }
183
184 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
185 {
186         char *name;
187
188         if (!PyArg_ParseTuple(args, "s", &name))
189                 return NULL;
190
191         return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
192 }
193
194 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
195 {
196         int ret;
197         ret = ldb_dn_compare(dn1->dn, dn2->dn);
198         if (ret < 0) ret = -1;
199         if (ret > 0) ret = 1;
200         return ret;
201 }
202
203 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
204 {
205         struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self);
206         struct ldb_dn *parent;
207         PyLdbDnObject *py_ret;
208         TALLOC_CTX *mem_ctx = talloc_new(NULL);
209
210         parent = ldb_dn_get_parent(mem_ctx, dn);
211         if (parent == NULL) {
212                 talloc_free(mem_ctx);
213                 Py_RETURN_NONE;
214         }
215
216         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
217         if (py_ret == NULL) {
218                 PyErr_NoMemory();
219                 talloc_free(mem_ctx);
220                 return NULL;
221         }
222         py_ret->mem_ctx = mem_ctx;
223         py_ret->dn = parent;
224         return (PyObject *)py_ret;
225 }
226
227 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
228
229 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
230 {
231         PyObject *py_other;
232         struct ldb_dn *dn, *other;
233         if (!PyArg_ParseTuple(args, "O", &py_other))
234                 return NULL;
235
236         dn = PyLdbDn_AsDn((PyObject *)self);
237
238         if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
239                 return NULL;
240
241         return ldb_dn_add_child(dn, other)?Py_True:Py_False;
242 }
243
244 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
245 {
246         PyObject *py_other;
247         struct ldb_dn *other, *dn;
248         if (!PyArg_ParseTuple(args, "O", &py_other))
249                 return NULL;
250
251         dn = PyLdbDn_AsDn((PyObject *)self);
252
253         if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
254                 return NULL;
255
256         return ldb_dn_add_base(dn, other)?Py_True:Py_False;
257 }
258
259 static PyMethodDef py_ldb_dn_methods[] = {
260         { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, 
261                 "S.validate() -> bool\n"
262                 "Validate DN is correct." },
263         { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
264                 "S.is_valid() -> bool\n" },
265         { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
266                 "S.is_special() -> bool\n"
267                 "Check whether this is a special LDB DN." },
268         { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
269                 "Check whether this is a null DN." },
270         { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
271                 NULL },
272         { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
273                 NULL },
274         { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
275                 "S.canonical_str() -> string\n"
276                 "Canonical version of this DN (like a posix path)." },
277         { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
278                 "S.canonical_ex_str() -> string\n"
279                 "Canonical version of this DN (like a posix path, with terminating newline)." },
280         { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
281                 "S.parent() -> dn\n"
282                 "Get the parent for this DN." },
283         { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS, 
284                 "S.add_child(dn) -> None\n"
285                 "Add a child DN to this DN." },
286         { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
287                 "S.add_base(dn) -> None\n"
288                 "Add a base DN to this DN." },
289         { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
290                 "S.check_special(name) -> bool\n\n"
291                 "Check if name is a special DN name"},
292         { NULL }
293 };
294
295 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
296 {
297         return ldb_dn_get_comp_num(PyLdbDn_AsDn((PyObject *)self));
298 }
299
300 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
301 {
302         struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self), 
303                                   *other;
304         PyLdbDnObject *py_ret;
305         
306         if (!PyObject_AsDn(NULL, py_other, NULL, &other))
307                 return NULL;
308
309         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
310         if (py_ret == NULL) {
311                 PyErr_NoMemory();
312                 return NULL;
313         }
314         py_ret->mem_ctx = talloc_new(NULL);
315         py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
316         ldb_dn_add_child(py_ret->dn, other);
317         return (PyObject *)py_ret;
318 }
319
320 static PySequenceMethods py_ldb_dn_seq = {
321         .sq_length = (lenfunc)py_ldb_dn_len,
322         .sq_concat = (binaryfunc)py_ldb_dn_concat,
323 };
324
325 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
326 {
327         struct ldb_dn *ret;
328         char *str;
329         PyObject *py_ldb;
330         struct ldb_context *ldb_ctx;
331         TALLOC_CTX *mem_ctx;
332         PyLdbDnObject *py_ret;
333         const char * const kwnames[] = { "ldb", "dn", NULL };
334
335         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
336                                          discard_const_p(char *, kwnames),
337                                          &py_ldb, &str))
338                 return NULL;
339
340         ldb_ctx = PyLdb_AsLdbContext(py_ldb);
341
342         mem_ctx = talloc_new(NULL);
343         if (mem_ctx == NULL) {
344                 PyErr_NoMemory();
345                 return NULL;
346         }
347
348         ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
349
350         if (ret == NULL || !ldb_dn_validate(ret)) {
351                 talloc_free(mem_ctx);
352                 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
353                 return NULL;
354         }
355
356         py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
357         if (ret == NULL) {
358                 talloc_free(mem_ctx);
359                 PyErr_NoMemory();
360                 return NULL;
361         }
362         py_ret->mem_ctx = mem_ctx;
363         py_ret->dn = ret;
364         return (PyObject *)py_ret;
365 }
366
367 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
368 {
369         talloc_free(self->mem_ctx);
370         PyObject_Del(self);
371 }
372
373 static PyTypeObject PyLdbDn = {
374         .tp_name = "ldb.Dn",
375         .tp_methods = py_ldb_dn_methods,
376         .tp_str = (reprfunc)py_ldb_dn_get_linearized,
377         .tp_repr = (reprfunc)py_ldb_dn_repr,
378         .tp_compare = (cmpfunc)py_ldb_dn_compare,
379         .tp_as_sequence = &py_ldb_dn_seq,
380         .tp_doc = "A LDB distinguished name.",
381         .tp_new = py_ldb_dn_new,
382         .tp_dealloc = (destructor)py_ldb_dn_dealloc,
383         .tp_basicsize = sizeof(PyLdbObject),
384         .tp_flags = Py_TPFLAGS_DEFAULT,
385 };
386
387 /* Debug */
388 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
389 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
390 {
391         PyObject *fn = (PyObject *)context;
392         PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
393 }
394
395 static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args)
396 {
397         PyObject *cb;
398
399         if (!PyArg_ParseTuple(args, "O", &cb))
400                 return NULL;
401
402         Py_INCREF(cb);
403         /* FIXME: Where do we DECREF cb ? */
404         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), PyLdb_AsLdbContext(self));
405
406         Py_RETURN_NONE;
407 }
408
409 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
410 {
411         unsigned int perms;
412         if (!PyArg_ParseTuple(args, "I", &perms))
413                 return NULL;
414
415         ldb_set_create_perms(PyLdb_AsLdbContext(self), perms);
416
417         Py_RETURN_NONE;
418 }
419
420 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
421 {
422         char *modules_dir;
423         if (!PyArg_ParseTuple(args, "s", &modules_dir))
424                 return NULL;
425
426         ldb_set_modules_dir(PyLdb_AsLdbContext(self), modules_dir);
427
428         Py_RETURN_NONE;
429 }
430
431 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
432 {
433         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_start(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
434         Py_RETURN_NONE;
435 }
436
437 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
438 {
439         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
440         Py_RETURN_NONE;
441 }
442
443 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
444 {
445         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_prepare_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
446         Py_RETURN_NONE;
447 }
448
449 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
450 {
451         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_transaction_cancel(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
452         Py_RETURN_NONE;
453 }
454
455 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
456 {
457         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_setup_wellknown_attributes(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
458         Py_RETURN_NONE;
459 }
460
461 static PyObject *py_ldb_repr(PyLdbObject *self)
462 {
463         return PyString_FromFormat("<ldb connection>");
464 }
465
466 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
467 {
468         struct ldb_dn *dn = ldb_get_root_basedn(PyLdb_AsLdbContext(self));
469         if (dn == NULL)
470                 Py_RETURN_NONE;
471         return PyLdbDn_FromDn(dn);
472 }
473
474
475 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
476 {
477         struct ldb_dn *dn = ldb_get_schema_basedn(PyLdb_AsLdbContext(self));
478         if (dn == NULL)
479                 Py_RETURN_NONE;
480         return PyLdbDn_FromDn(dn);
481 }
482
483 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
484 {
485         struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self));
486         if (dn == NULL)
487                 Py_RETURN_NONE;
488         return PyLdbDn_FromDn(dn);
489 }
490
491 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
492 {
493         struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self));
494         if (dn == NULL)
495                 Py_RETURN_NONE;
496         return PyLdbDn_FromDn(dn);
497 }
498
499 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, 
500                                         const char *paramname)
501 {
502         const char **ret;
503         Py_ssize_t i;
504         if (!PyList_Check(list)) {
505                 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
506                 return NULL;
507         }
508         ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
509         if (ret == NULL) {
510                 PyErr_NoMemory();
511                 return NULL;
512         }
513
514         for (i = 0; i < PyList_Size(list); i++) {
515                 PyObject *item = PyList_GetItem(list, i);
516                 if (!PyString_Check(item)) {
517                         PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
518                         return NULL;
519                 }
520                 ret[i] = talloc_strndup(ret, PyString_AsString(item),
521                                         PyString_Size(item));
522         }
523         ret[i] = NULL;
524         return ret;
525 }
526
527 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
528 {
529         const char * const kwnames[] = { "url", "flags", "options", NULL };
530         char *url = NULL;
531         PyObject *py_options = Py_None;
532         const char **options;
533         int flags = 0;
534         int ret;
535         struct ldb_context *ldb;
536
537         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO:Ldb.__init__",
538                                          discard_const_p(char *, kwnames),
539                                          &url, &flags, &py_options))
540                 return -1;
541
542         ldb = PyLdb_AsLdbContext(self);
543
544         if (py_options == Py_None) {
545                 options = NULL;
546         } else {
547                 options = PyList_AsStringList(ldb, py_options, "options");
548                 if (options == NULL)
549                         return -1;
550         }
551
552         if (url != NULL) {
553                 ret = ldb_connect(ldb, url, flags, options);
554                 if (ret != LDB_SUCCESS) {
555                         PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
556                         return -1;
557                 }
558         }
559
560         talloc_free(options);
561         return 0;
562 }
563
564 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
565 {
566         PyLdbObject *ret;
567         struct ldb_context *ldb;
568         ret = (PyLdbObject *)type->tp_alloc(type, 0);
569         if (ret == NULL) {
570                 PyErr_NoMemory();
571                 return NULL;
572         }
573         ret->mem_ctx = talloc_new(NULL);
574         ldb = ldb_init(ret->mem_ctx, NULL);
575
576         if (ldb == NULL) {
577                 PyErr_NoMemory();
578                 return NULL;
579         }
580
581         ret->ldb_ctx = ldb;
582         return (PyObject *)ret;
583 }
584
585 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
586 {
587         char *url;
588         int flags = 0;
589         PyObject *py_options = Py_None;
590         int ret;
591         const char **options;
592         const char * const kwnames[] = { "url", "flags", "options", NULL };
593
594         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO",
595                                          discard_const_p(char *, kwnames),
596                                          &url, &flags, &py_options))
597                 return NULL;
598
599         if (py_options == Py_None) {
600                 options = NULL;
601         } else {
602                 options = PyList_AsStringList(NULL, py_options, "options");
603                 if (options == NULL)
604                         return NULL;
605         }
606
607         ret = ldb_connect(PyLdb_AsLdbContext(self), url, flags, options);
608         talloc_free(options);
609
610         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
611
612         Py_RETURN_NONE;
613 }
614
615 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args)
616 {
617         PyObject *py_msg;
618         PyObject *py_controls = Py_None;
619         struct ldb_context *ldb_ctx;
620         struct ldb_request *req;
621         struct ldb_control **parsed_controls;
622         struct ldb_message *msg;
623         int ret;
624         TALLOC_CTX *mem_ctx;
625
626         if (!PyArg_ParseTuple(args, "O|O", &py_msg, &py_controls))
627                 return NULL;
628
629         mem_ctx = talloc_new(NULL);
630         if (mem_ctx == NULL) {
631                 PyErr_NoMemory();
632                 return NULL;
633         }
634         ldb_ctx = PyLdb_AsLdbContext(self);
635
636         if (py_controls == Py_None) {
637                 parsed_controls = NULL;
638         } else {
639                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
640                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
641                 talloc_free(controls);
642         }
643
644         if (!PyLdbMessage_Check(py_msg)) {
645                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
646                 talloc_free(mem_ctx);
647                 return NULL;
648         }
649         msg = PyLdbMessage_AsMessage(py_msg);
650
651         ret = ldb_msg_sanity_check(ldb_ctx, msg);
652         if (ret != LDB_SUCCESS) {
653                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
654                 talloc_free(mem_ctx);
655                 return NULL;
656         }
657
658         ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
659                                 NULL, ldb_op_default_callback, NULL);
660         if (ret != LDB_SUCCESS) {
661                 PyErr_SetString(PyExc_TypeError, "failed to build request");
662                 talloc_free(mem_ctx);
663                 return NULL;
664         }
665
666         /* do request and autostart a transaction */
667         /* Then let's LDB handle the message error in case of pb as they are meaningful */
668
669         ret = ldb_transaction_start(ldb_ctx);
670         if (ret != LDB_SUCCESS) {
671                 talloc_free(mem_ctx);
672                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
673         }
674
675         ret = ldb_request(ldb_ctx, req);
676         if (ret == LDB_SUCCESS) {
677                         ret = ldb_wait(req->handle, LDB_WAIT_ALL);
678         }
679
680         if (ret == LDB_SUCCESS) {
681                 ret = ldb_transaction_commit(ldb_ctx);
682         } else {
683                 ldb_transaction_cancel(ldb_ctx);
684                 if (ldb_ctx->err_string == NULL) {
685                         /* no error string was setup by the backend */
686                         ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
687                 }
688         }
689
690         talloc_free(mem_ctx);
691         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
692
693         Py_RETURN_NONE;
694 }
695
696
697 /**
698  * Obtain a ldb message from a Python Dictionary object.
699  *
700  * @param mem_ctx Memory context
701  * @param py_obj Python Dictionary object
702  * @param ldb_ctx LDB context
703  * @param mod_flags Flags to be set on every message element
704  * @return ldb_message on success or NULL on failure
705  */
706 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
707                                             PyObject *py_obj,
708                                             struct ldb_context *ldb_ctx,
709                                             unsigned int mod_flags)
710 {
711         struct ldb_message *msg;
712         unsigned int msg_pos = 0;
713         Py_ssize_t dict_pos = 0;
714         PyObject *key, *value;
715         struct ldb_message_element *msg_el;
716         PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
717
718         msg = ldb_msg_new(mem_ctx);
719         msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
720
721         if (dn_value) {
722                 if (!PyObject_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
723                         PyErr_SetString(PyExc_TypeError, "unable to import dn object");
724                         return NULL;
725                 }
726                 if (msg->dn == NULL) {
727                         PyErr_SetString(PyExc_TypeError, "dn set but not found");
728                         return NULL;
729                 }
730         } else {
731                 PyErr_SetString(PyExc_TypeError, "no dn set");
732                 return NULL;
733         }
734
735         while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
736                 char *key_str = PyString_AsString(key);
737                 if (strcmp(key_str, "dn") != 0) {
738                         msg_el = PyObject_AsMessageElement(msg->elements, value,
739                                                            mod_flags, key_str);
740                         if (msg_el == NULL) {
741                                 PyErr_SetString(PyExc_TypeError, "unable to import element");
742                                 return NULL;
743                         }
744                         memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
745                         msg_pos++;
746                 }
747         }
748
749         msg->num_elements = msg_pos;
750
751         return msg;
752 }
753
754 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
755 {
756         PyObject *py_obj;
757         int ret;
758         struct ldb_context *ldb_ctx;
759         struct ldb_request *req;
760         struct ldb_message *msg = NULL;
761         PyObject *py_controls = Py_None;
762         TALLOC_CTX *mem_ctx;
763         struct ldb_control **parsed_controls;
764
765         if (!PyArg_ParseTuple(args, "O|O", &py_obj, &py_controls ))
766                 return NULL;
767
768         mem_ctx = talloc_new(NULL);
769         if (mem_ctx == NULL) {
770                 PyErr_NoMemory();
771                 return NULL;
772         }
773         ldb_ctx = PyLdb_AsLdbContext(self);
774
775         if (py_controls == Py_None) {
776                 parsed_controls = NULL;
777         } else {
778                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
779                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
780                 talloc_free(controls);
781         }
782
783         if (PyLdbMessage_Check(py_obj)) {
784                 msg = PyLdbMessage_AsMessage(py_obj);
785         } else if (PyDict_Check(py_obj)) {
786                 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
787         } else {
788                 PyErr_SetString(PyExc_TypeError,
789                                 "Dictionary or LdbMessage object expected!");
790         }
791
792         if (!msg) {
793                 /* we should have a PyErr already set */
794                 talloc_free(mem_ctx);
795                 return NULL;
796         }
797
798         ret = ldb_msg_sanity_check(ldb_ctx, msg);
799         if (ret != LDB_SUCCESS) {
800                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
801                 talloc_free(mem_ctx);
802                 return NULL;
803         }
804
805         ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
806                                 NULL, ldb_op_default_callback, NULL);
807         if (ret != LDB_SUCCESS) {
808                 PyErr_SetString(PyExc_TypeError, "failed to build request");
809                 talloc_free(mem_ctx);
810                 return NULL;
811         }
812
813         /* do request and autostart a transaction */
814         /* Then let's LDB handle the message error in case of pb as they are meaningful */
815
816         ret = ldb_transaction_start(ldb_ctx);
817         if (ret != LDB_SUCCESS) {
818                 talloc_free(mem_ctx);
819                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
820         }
821
822         ret = ldb_request(ldb_ctx, req);
823         if (ret == LDB_SUCCESS) {
824                         ret = ldb_wait(req->handle, LDB_WAIT_ALL);
825         } 
826
827         if (ret == LDB_SUCCESS) {
828                         ret = ldb_transaction_commit(ldb_ctx);
829         } else {
830                 ldb_transaction_cancel(ldb_ctx);
831                 if (ldb_ctx->err_string == NULL) {
832                         /* no error string was setup by the backend */
833                         ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
834                 }
835         }
836
837         talloc_free(mem_ctx);
838         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
839
840         Py_RETURN_NONE;
841 }
842
843 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args)
844 {
845         PyObject *py_dn;
846         struct ldb_dn *dn;
847         int ret;
848         struct ldb_context *ldb_ctx;
849         struct ldb_request *req;
850         PyObject *py_controls = Py_None;
851         TALLOC_CTX *mem_ctx;
852         struct ldb_control **parsed_controls;
853
854         if (!PyArg_ParseTuple(args, "O|O", &py_dn, &py_controls))
855                 return NULL;
856
857         mem_ctx = talloc_new(NULL);
858         if (mem_ctx == NULL) {
859                 PyErr_NoMemory();
860                 return NULL;
861         }
862         ldb_ctx = PyLdb_AsLdbContext(self);
863
864         if (py_controls == Py_None) {
865                 parsed_controls = NULL;
866         } else {
867                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
868                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
869                 talloc_free(controls);
870         }
871
872         if (!PyObject_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
873                 talloc_free(mem_ctx);
874                 return NULL;
875         }
876
877         ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
878                                 NULL, ldb_op_default_callback, NULL);
879         if (ret != LDB_SUCCESS) {
880                 PyErr_SetString(PyExc_TypeError, "failed to build request");
881                 talloc_free(mem_ctx);
882                 return NULL;
883         }
884
885         /* do request and autostart a transaction */
886         /* Then let's LDB handle the message error in case of pb as they are meaningful */
887
888         ret = ldb_transaction_start(ldb_ctx);
889         if (ret != LDB_SUCCESS) {
890                 talloc_free(mem_ctx);
891                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
892         }
893
894         ret = ldb_request(ldb_ctx, req);
895         if (ret == LDB_SUCCESS) {
896                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
897         }
898
899         if (ret == LDB_SUCCESS) {
900                 ret = ldb_transaction_commit(ldb_ctx);
901         } else {
902                 ldb_transaction_cancel(ldb_ctx);
903                 if (ldb_ctx->err_string == NULL) {
904                         /* no error string was setup by the backend */
905                         ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
906                 }
907         }
908
909         talloc_free(mem_ctx);
910         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
911
912         Py_RETURN_NONE;
913 }
914
915 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args)
916 {
917         PyObject *py_dn1, *py_dn2;
918         struct ldb_dn *dn1, *dn2;
919         int ret;
920         struct ldb_context *ldb;
921         TALLOC_CTX *mem_ctx;
922         PyObject *py_controls = Py_None;
923         struct ldb_control **parsed_controls;
924         struct ldb_context *ldb_ctx;
925         struct ldb_request *req;
926
927         ldb_ctx = PyLdb_AsLdbContext(self);
928
929         if (!PyArg_ParseTuple(args, "OO|O", &py_dn1, &py_dn2, &py_controls))
930                 return NULL;
931
932
933         mem_ctx = talloc_new(NULL);
934         if (mem_ctx == NULL) {
935                 PyErr_NoMemory();
936                 return NULL;
937         }
938         ldb = PyLdb_AsLdbContext(self);
939
940         if (py_controls == Py_None) {
941                 parsed_controls = NULL;
942         } else {
943                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
944                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
945                 talloc_free(controls);
946         }
947
948
949         if (!PyObject_AsDn(mem_ctx, py_dn1, ldb, &dn1)) {
950                 talloc_free(mem_ctx);
951                 return NULL;
952         }
953
954         if (!PyObject_AsDn(mem_ctx, py_dn2, ldb, &dn2)) {
955                 talloc_free(mem_ctx);
956                 return NULL;
957         }
958
959         ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
960                                 NULL, ldb_op_default_callback, NULL);
961         if (ret != LDB_SUCCESS) {
962                 PyErr_SetString(PyExc_TypeError, "failed to build request");
963                 talloc_free(mem_ctx);
964                 return NULL;
965         }
966
967         /* do request and autostart a transaction */
968         /* Then let's LDB handle the message error in case of pb as they are meaningful */
969
970         ret = ldb_transaction_start(ldb_ctx);
971         if (ret != LDB_SUCCESS) {
972                 talloc_free(mem_ctx);
973                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
974         }
975
976         ret = ldb_request(ldb_ctx, req);
977         if (ret == LDB_SUCCESS) {
978                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
979         }
980
981         if (ret == LDB_SUCCESS) {
982                 ret = ldb_transaction_commit(ldb_ctx);
983         } else {
984                 ldb_transaction_cancel(ldb_ctx);
985                 if (ldb_ctx->err_string == NULL) {
986                         /* no error string was setup by the backend */
987                         ldb_asprintf_errstring(ldb_ctx, "%s (%d)", ldb_strerror(ret), ret);
988                 }
989         }
990
991         talloc_free(mem_ctx);
992         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
993
994         Py_RETURN_NONE;
995 }
996
997 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
998 {
999         char *name;
1000         if (!PyArg_ParseTuple(args, "s", &name))
1001                 return NULL;
1002
1003         ldb_schema_attribute_remove(PyLdb_AsLdbContext(self), name);
1004
1005         Py_RETURN_NONE;
1006 }
1007
1008 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1009 {
1010         char *attribute, *syntax;
1011         unsigned int flags;
1012         int ret;
1013         if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1014                 return NULL;
1015
1016         ret = ldb_schema_attribute_add(PyLdb_AsLdbContext(self), attribute, flags, syntax);
1017
1018         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, PyLdb_AsLdbContext(self));
1019
1020         Py_RETURN_NONE;
1021 }
1022
1023 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1024 {
1025         if (ldif == NULL) {
1026                 Py_RETURN_NONE;
1027         } else {
1028         /* We don't want this attached to the 'ldb' any more */
1029                 return Py_BuildValue(discard_const_p(char, "(iO)"),
1030                                      ldif->changetype,
1031                                      PyLdbMessage_FromMessage(ldif->msg));
1032         }
1033 }
1034
1035
1036 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1037 {
1038         int changetype;
1039         PyObject *py_msg;
1040         struct ldb_ldif ldif;
1041         PyObject *ret;
1042         char *string;
1043         TALLOC_CTX *mem_ctx;
1044
1045         if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1046                 return NULL;
1047
1048         if (!PyLdbMessage_Check(py_msg)) {
1049                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1050                 return NULL;
1051         }
1052
1053         ldif.msg = PyLdbMessage_AsMessage(py_msg);
1054         ldif.changetype = changetype;
1055
1056         mem_ctx = talloc_new(NULL);
1057
1058         string = ldb_ldif_write_string(PyLdb_AsLdbContext(self), mem_ctx, &ldif);
1059         if (!string) {
1060                 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1061                 return NULL;
1062         }
1063
1064         ret = PyString_FromString(string);
1065
1066         talloc_free(mem_ctx);
1067
1068         return ret;
1069 }
1070
1071 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1072 {
1073         PyObject *list;
1074         struct ldb_ldif *ldif;
1075         const char *s;
1076
1077         TALLOC_CTX *mem_ctx;
1078
1079         if (!PyArg_ParseTuple(args, "s", &s))
1080                 return NULL;
1081
1082         mem_ctx = talloc_new(NULL);
1083         if (!mem_ctx) {
1084                 Py_RETURN_NONE;
1085         }
1086
1087         list = PyList_New(0);
1088         while (s && *s != '\0') {
1089                 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1090                 talloc_steal(mem_ctx, ldif);
1091                 if (ldif) {
1092                         PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1093                 } else {
1094                         PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1095                         talloc_free(mem_ctx);
1096                         return NULL;
1097                 }
1098         }
1099         talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1100         return PyObject_GetIter(list);
1101 }
1102
1103 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1104 {
1105         int ldb_ret;
1106         PyObject *py_msg_old;
1107         PyObject *py_msg_new;
1108         struct ldb_message *diff;
1109         struct ldb_context *ldb;
1110         PyObject *py_ret;
1111
1112         if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1113                 return NULL;
1114
1115         if (!PyLdbMessage_Check(py_msg_old)) {
1116                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1117                 return NULL;
1118         }
1119
1120         if (!PyLdbMessage_Check(py_msg_new)) {
1121                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1122                 return NULL;
1123         }
1124
1125         ldb = PyLdb_AsLdbContext(self);
1126         ldb_ret = ldb_msg_difference(ldb, ldb,
1127                                      PyLdbMessage_AsMessage(py_msg_old),
1128                                      PyLdbMessage_AsMessage(py_msg_new),
1129                                      &diff);
1130         if (ldb_ret != LDB_SUCCESS) {
1131                 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1132                 return NULL;
1133         }
1134
1135         py_ret = PyLdbMessage_FromMessage(diff);
1136
1137         talloc_unlink(ldb, diff);
1138
1139         return py_ret;
1140 }
1141
1142 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1143 {
1144         const struct ldb_schema_attribute *a;
1145         struct ldb_val old_val;
1146         struct ldb_val new_val;
1147         TALLOC_CTX *mem_ctx;
1148         PyObject *ret;
1149         char *element_name;
1150         PyObject *val;
1151
1152         if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1153                 return NULL;
1154
1155         mem_ctx = talloc_new(NULL);
1156
1157         old_val.data = (uint8_t *)PyString_AsString(val);
1158         old_val.length = PyString_Size(val);
1159
1160         a = ldb_schema_attribute_by_name(PyLdb_AsLdbContext(self), element_name);
1161
1162         if (a == NULL) {
1163                 Py_RETURN_NONE;
1164         }
1165
1166         if (a->syntax->ldif_write_fn(PyLdb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1167                 talloc_free(mem_ctx);
1168                 Py_RETURN_NONE;
1169         }
1170
1171         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1172
1173         talloc_free(mem_ctx);
1174
1175         return ret;
1176 }
1177
1178 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1179 {
1180         PyObject *py_base = Py_None;
1181         int scope = LDB_SCOPE_DEFAULT;
1182         char *expr = NULL;
1183         PyObject *py_attrs = Py_None;
1184         PyObject *py_controls = Py_None;
1185         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1186         int ret;
1187         struct ldb_result *res;
1188         struct ldb_request *req;
1189         const char **attrs;
1190         struct ldb_context *ldb_ctx;
1191         struct ldb_control **parsed_controls;
1192         struct ldb_dn *base;
1193         PyObject *py_ret;
1194         TALLOC_CTX *mem_ctx;
1195
1196         /* type "int" rather than "enum" for "scope" is intentional */
1197         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1198                                          discard_const_p(char *, kwnames),
1199                                          &py_base, &scope, &expr, &py_attrs, &py_controls))
1200                 return NULL;
1201
1202
1203         mem_ctx = talloc_new(NULL);
1204         if (mem_ctx == NULL) {
1205                 PyErr_NoMemory();
1206                 return NULL;
1207         }
1208         ldb_ctx = PyLdb_AsLdbContext(self);
1209
1210         if (py_attrs == Py_None) {
1211                 attrs = NULL;
1212         } else {
1213                 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1214                 if (attrs == NULL) {
1215                         talloc_free(mem_ctx);
1216                         return NULL;
1217                 }
1218         }
1219
1220         if (py_base == Py_None) {
1221                 base = ldb_get_default_basedn(ldb_ctx);
1222         } else {
1223                 if (!PyObject_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1224                         talloc_free(attrs);
1225                         return NULL;
1226                 }
1227         }
1228
1229         if (py_controls == Py_None) {
1230                 parsed_controls = NULL;
1231         } else {
1232                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1233                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1234                 talloc_free(controls);
1235         }
1236
1237         res = talloc_zero(mem_ctx, struct ldb_result);
1238         if (res == NULL) {
1239                 PyErr_NoMemory();
1240                 talloc_free(mem_ctx);
1241                 return NULL;
1242         }
1243
1244         ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1245                                    base,
1246                                    scope,
1247                                    expr,
1248                                    attrs,
1249                                    parsed_controls,
1250                                    res,
1251                                    ldb_search_default_callback,
1252                                    NULL);
1253
1254         if (ret != LDB_SUCCESS) {
1255                 talloc_free(mem_ctx);
1256                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1257                 return NULL;
1258         }
1259
1260         talloc_steal(req, attrs);
1261
1262         ret = ldb_request(ldb_ctx, req);
1263
1264         if (ret == LDB_SUCCESS) {
1265                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1266         }
1267
1268         if (ret != LDB_SUCCESS) {
1269                 talloc_free(mem_ctx);
1270                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1271                 return NULL;
1272         }
1273
1274         py_ret = PyLdbResult_FromResult(res);
1275
1276         talloc_free(mem_ctx);
1277
1278         return py_ret;
1279 }
1280
1281 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1282 {
1283         char *name;
1284         void *data;
1285
1286         if (!PyArg_ParseTuple(args, "s", &name))
1287                 return NULL;
1288
1289         data = ldb_get_opaque(PyLdb_AsLdbContext(self), name);
1290
1291         if (data == NULL)
1292                 Py_RETURN_NONE;
1293
1294         /* FIXME: More interpretation */
1295
1296         return Py_True;
1297 }
1298
1299 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1300 {
1301         char *name;
1302         PyObject *data;
1303
1304         if (!PyArg_ParseTuple(args, "sO", &name, &data))
1305                 return NULL;
1306
1307         /* FIXME: More interpretation */
1308
1309         ldb_set_opaque(PyLdb_AsLdbContext(self), name, data);
1310
1311         Py_RETURN_NONE;
1312 }
1313
1314 static PyObject *py_ldb_modules(PyLdbObject *self)
1315 {
1316         struct ldb_context *ldb = PyLdb_AsLdbContext(self);
1317         PyObject *ret = PyList_New(0);
1318         struct ldb_module *mod;
1319
1320         for (mod = ldb->modules; mod; mod = mod->next) {
1321                 PyList_Append(ret, PyLdbModule_FromModule(mod));
1322         }
1323
1324         return ret;
1325 }
1326
1327 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1328 {
1329         struct ldb_context *ldb = PyLdb_AsLdbContext(self);
1330         int type, ret;
1331         uint64_t value;
1332
1333         if (!PyArg_ParseTuple(args, "i", &type))
1334                 return NULL;
1335
1336         /* FIXME: More interpretation */
1337
1338         ret = ldb_sequence_number(ldb, type, &value);
1339
1340         if (ret != LDB_SUCCESS) {
1341                 PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1342                 return NULL;
1343         }
1344         return PyLong_FromLongLong(value);
1345 }
1346 static PyMethodDef py_ldb_methods[] = {
1347         { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, 
1348                 "S.set_debug(callback) -> None\n"
1349                 "Set callback for LDB debug messages.\n"
1350                 "The callback should accept a debug level and debug text." },
1351         { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, 
1352                 "S.set_create_perms(mode) -> None\n"
1353                 "Set mode to use when creating new LDB files." },
1354         { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1355                 "S.set_modules_dir(path) -> None\n"
1356                 "Set path LDB should search for modules" },
1357         { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, 
1358                 "S.transaction_start() -> None\n"
1359                 "Start a new transaction." },
1360         { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1361                 "S.transaction_prepare_commit() -> None\n"
1362                 "prepare to commit a new transaction (2-stage commit)." },
1363         { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, 
1364                 "S.transaction_commit() -> None\n"
1365                 "commit a new transaction." },
1366         { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, 
1367                 "S.transaction_cancel() -> None\n"
1368                 "cancel a new transaction." },
1369         { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, 
1370                 NULL },
1371         { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1372                 NULL },
1373         { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1374                 NULL },
1375         { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1376                 NULL },
1377         { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1378                 NULL },
1379         { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, 
1380                 "S.connect(url, flags=0, options=None) -> None\n"
1381                 "Connect to a LDB URL." },
1382         { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS, 
1383                 "S.modify(message) -> None\n"
1384                 "Modify an entry." },
1385         { "add", (PyCFunction)py_ldb_add, METH_VARARGS, 
1386                 "S.add(message) -> None\n"
1387                 "Add an entry." },
1388         { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS,
1389                 "S.delete(dn) -> None\n"
1390                 "Remove an entry." },
1391         { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS,
1392                 "S.rename(old_dn, new_dn) -> None\n"
1393                 "Rename an entry." },
1394         { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1395                 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1396                 "Search in a database.\n"
1397                 "\n"
1398                 ":param base: Optional base DN to search\n"
1399                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1400                 ":param expression: Optional search expression\n"
1401                 ":param attrs: Attributes to return (defaults to all)\n"
1402                 ":param controls: Optional list of controls\n"
1403                 ":return: Iterator over Message objects\n"
1404         },
1405         { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1406                 NULL },
1407         { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1408                 NULL },
1409         { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1410                 NULL },
1411         { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1412                 "S.parse_ldif(ldif) -> iter(messages)\n"
1413                 "Parse a string formatted using LDIF." },
1414         { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1415                 "S.write_ldif(message, changetype) -> ldif\n"
1416                 "Print the message as a string formatted using LDIF." },
1417         { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1418                 "S.msg_diff(Message) -> Message\n"
1419                 "Return an LDB Message of the difference between two Message objects." },
1420         { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1421                 "S.get_opaque(name) -> value\n"
1422                 "Get an opaque value set on this LDB connection. \n"
1423                 ":note: The returned value may not be useful in Python."
1424         },
1425         { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1426                 "S.set_opaque(name, value) -> None\n"
1427                 "Set an opaque value on this LDB connection. \n"
1428                 ":note: Passing incorrect values may cause crashes." },
1429         { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1430                 "S.modules() -> list\n"
1431                 "Return the list of modules on this LDB connection " },
1432         { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1433                 "S.sequence_number(type) -> value\n"
1434                 "Return the value of the sequence according to the requested type" },
1435         { NULL },
1436 };
1437
1438 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1439 {
1440         PyLdbModuleObject *ret;
1441
1442         ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1443         if (ret == NULL) {
1444                 PyErr_NoMemory();
1445                 return NULL;
1446         }
1447         ret->mem_ctx = talloc_new(NULL);
1448         ret->mod = talloc_reference(ret->mem_ctx, mod);
1449         return (PyObject *)ret;
1450 }
1451
1452 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1453 {
1454         return PyLdbModule_FromModule(PyLdb_AsLdbContext(self)->modules);
1455 }
1456
1457 static PyGetSetDef py_ldb_getset[] = {
1458         { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1459         { NULL }
1460 };
1461
1462 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1463 {
1464         struct ldb_context *ldb_ctx = PyLdb_AsLdbContext(self);
1465         struct ldb_dn *dn;
1466         struct ldb_result *result;
1467         unsigned int count;
1468         int ret;
1469
1470         if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1471                 return -1;
1472         }
1473
1474         ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1475                          NULL);
1476         if (ret != LDB_SUCCESS) {
1477                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1478                 return -1;
1479         }
1480
1481         count = result->count;
1482
1483         talloc_free(result);
1484
1485         if (count > 1) {
1486                 PyErr_Format(PyExc_RuntimeError,
1487                              "Searching for [%s] dn gave %u results!",
1488                              ldb_dn_get_linearized(dn),
1489                              count);
1490                 return -1;
1491         }
1492
1493         return count;
1494 }
1495
1496 static PySequenceMethods py_ldb_seq = {
1497         .sq_contains = (objobjproc)py_ldb_contains,
1498 };
1499
1500 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1501 {
1502         PyLdbObject *ret;
1503
1504         ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1505         if (ret == NULL) {
1506                 PyErr_NoMemory();
1507                 return NULL;
1508         }
1509         ret->mem_ctx = talloc_new(NULL);
1510         ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1511         return (PyObject *)ret;
1512 }
1513
1514 static void py_ldb_dealloc(PyLdbObject *self)
1515 {
1516         talloc_free(self->mem_ctx);
1517         self->ob_type->tp_free(self);
1518 }
1519
1520 static PyTypeObject PyLdb = {
1521         .tp_name = "ldb.Ldb",
1522         .tp_methods = py_ldb_methods,
1523         .tp_repr = (reprfunc)py_ldb_repr,
1524         .tp_new = py_ldb_new,
1525         .tp_init = (initproc)py_ldb_init,
1526         .tp_dealloc = (destructor)py_ldb_dealloc,
1527         .tp_getset = py_ldb_getset,
1528         .tp_getattro = PyObject_GenericGetAttr,
1529         .tp_basicsize = sizeof(PyLdbObject),
1530         .tp_doc = "Connection to a LDB database.",
1531         .tp_as_sequence = &py_ldb_seq,
1532         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1533 };
1534
1535 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1536 {
1537         return PyString_FromFormat("<ldb module '%s'>", PyLdbModule_AsModule(self)->ops->name);
1538 }
1539
1540 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1541 {
1542         return PyString_FromString(PyLdbModule_AsModule(self)->ops->name);
1543 }
1544
1545 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1546 {
1547         PyLdbModule_AsModule(self)->ops->start_transaction(PyLdbModule_AsModule(self));
1548         Py_RETURN_NONE;
1549 }
1550
1551 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1552 {
1553         PyLdbModule_AsModule(self)->ops->end_transaction(PyLdbModule_AsModule(self));
1554         Py_RETURN_NONE;
1555 }
1556
1557 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
1558 {
1559         PyLdbModule_AsModule(self)->ops->del_transaction(PyLdbModule_AsModule(self));
1560         Py_RETURN_NONE;
1561 }
1562
1563 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
1564 {
1565         PyObject *py_base, *py_tree, *py_attrs, *py_ret;
1566         int ret, scope;
1567         struct ldb_request *req;
1568         const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
1569         struct ldb_module *mod;
1570         const char * const*attrs;
1571
1572         /* type "int" rather than "enum" for "scope" is intentional */
1573         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
1574                                          discard_const_p(char *, kwnames),
1575                                          &py_base, &scope, &py_tree, &py_attrs))
1576                 return NULL;
1577
1578         mod = self->mod;
1579
1580         if (py_attrs == Py_None) {
1581                 attrs = NULL;
1582         } else {
1583                 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
1584                 if (attrs == NULL)
1585                         return NULL;
1586         }
1587
1588         ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base), 
1589                              scope, NULL /* expr */, attrs,
1590                              NULL /* controls */, NULL, NULL, NULL);
1591
1592         talloc_steal(req, attrs);
1593
1594         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1595
1596         req->op.search.res = NULL;
1597
1598         ret = mod->ops->search(mod, req);
1599
1600         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1601
1602         py_ret = PyLdbResult_FromResult(req->op.search.res);
1603
1604         talloc_free(req);
1605
1606         return py_ret;  
1607 }
1608
1609
1610 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
1611 {
1612         struct ldb_request *req;
1613         PyObject *py_message;
1614         int ret;
1615         struct ldb_module *mod;
1616
1617         if (!PyArg_ParseTuple(args, "O", &py_message))
1618                 return NULL;
1619
1620         req = talloc_zero(NULL, struct ldb_request);
1621         req->operation = LDB_ADD;
1622         req->op.add.message = PyLdbMessage_AsMessage(py_message);
1623
1624         mod = PyLdbModule_AsModule(self);
1625         ret = mod->ops->add(mod, req);
1626
1627         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1628
1629         Py_RETURN_NONE;
1630 }
1631
1632 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) 
1633 {
1634         int ret;
1635         struct ldb_request *req;
1636         PyObject *py_message;
1637         struct ldb_module *mod;
1638
1639         if (!PyArg_ParseTuple(args, "O", &py_message))
1640                 return NULL;
1641
1642         req = talloc_zero(NULL, struct ldb_request);
1643         req->operation = LDB_MODIFY;
1644         req->op.mod.message = PyLdbMessage_AsMessage(py_message);
1645
1646         mod = PyLdbModule_AsModule(self);
1647         ret = mod->ops->modify(mod, req);
1648
1649         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
1650
1651         Py_RETURN_NONE;
1652 }
1653
1654 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) 
1655 {
1656         int ret;
1657         struct ldb_request *req;
1658         PyObject *py_dn;
1659
1660         if (!PyArg_ParseTuple(args, "O", &py_dn))
1661                 return NULL;
1662
1663         req = talloc_zero(NULL, struct ldb_request);
1664         req->operation = LDB_DELETE;
1665         req->op.del.dn = PyLdbDn_AsDn(py_dn);
1666
1667         ret = PyLdbModule_AsModule(self)->ops->del(PyLdbModule_AsModule(self), req);
1668
1669         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1670
1671         Py_RETURN_NONE;
1672 }
1673
1674 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
1675 {
1676         int ret;
1677         struct ldb_request *req;
1678         PyObject *py_dn1, *py_dn2;
1679
1680         if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
1681                 return NULL;
1682
1683         req = talloc_zero(NULL, struct ldb_request);
1684
1685         req->operation = LDB_RENAME;
1686         req->op.rename.olddn = PyLdbDn_AsDn(py_dn1);
1687         req->op.rename.newdn = PyLdbDn_AsDn(py_dn2);
1688
1689         ret = PyLdbModule_AsModule(self)->ops->rename(PyLdbModule_AsModule(self), req);
1690
1691         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
1692
1693         Py_RETURN_NONE;
1694 }
1695
1696 static PyMethodDef py_ldb_module_methods[] = {
1697         { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
1698         { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
1699         { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
1700         { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
1701         { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
1702         { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
1703         { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
1704         { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
1705         { NULL },
1706 };
1707
1708 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
1709 {
1710         talloc_free(self->mem_ctx);
1711         PyObject_Del(self);
1712 }
1713
1714 static PyTypeObject PyLdbModule = {
1715         .tp_name = "ldb.LdbModule",
1716         .tp_methods = py_ldb_module_methods,
1717         .tp_repr = (reprfunc)py_ldb_module_repr,
1718         .tp_str = (reprfunc)py_ldb_module_str,
1719         .tp_basicsize = sizeof(PyLdbModuleObject),
1720         .tp_dealloc = (destructor)py_ldb_module_dealloc,
1721         .tp_flags = Py_TPFLAGS_DEFAULT,
1722 };
1723
1724
1725 /**
1726  * Create a ldb_message_element from a Python object.
1727  *
1728  * This will accept any sequence objects that contains strings, or 
1729  * a string object.
1730  *
1731  * A reference to set_obj will be borrowed. 
1732  *
1733  * @param mem_ctx Memory context
1734  * @param set_obj Python object to convert
1735  * @param flags ldb_message_element flags to set
1736  * @param attr_name Name of the attribute
1737  * @return New ldb_message_element, allocated as child of mem_ctx
1738  */
1739 static struct ldb_message_element *PyObject_AsMessageElement(
1740                                                       TALLOC_CTX *mem_ctx,
1741                                                       PyObject *set_obj,
1742                                                       int flags,
1743                                                       const char *attr_name)
1744 {
1745         struct ldb_message_element *me;
1746
1747         if (PyLdbMessageElement_Check(set_obj)) {
1748                 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
1749                 /* We have to talloc_reference() the memory context, not the pointer
1750                  * which may not actually be it's own context */
1751                 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
1752                         return PyLdbMessageElement_AsMessageElement(set_obj);
1753                 }
1754                 return NULL;
1755         }
1756
1757         me = talloc(mem_ctx, struct ldb_message_element);
1758         if (me == NULL) {
1759                 PyErr_NoMemory();
1760                 return NULL;
1761         }
1762
1763         me->name = talloc_strdup(me, attr_name);
1764         me->flags = flags;
1765         if (PyString_Check(set_obj)) {
1766                 me->num_values = 1;
1767                 me->values = talloc_array(me, struct ldb_val, me->num_values);
1768                 me->values[0].length = PyString_Size(set_obj);
1769                 me->values[0].data = talloc_memdup(me, 
1770                         (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
1771         } else if (PySequence_Check(set_obj)) {
1772                 Py_ssize_t i;
1773                 me->num_values = PySequence_Size(set_obj);
1774                 me->values = talloc_array(me, struct ldb_val, me->num_values);
1775                 for (i = 0; i < me->num_values; i++) {
1776                         PyObject *obj = PySequence_GetItem(set_obj, i);
1777                         if (!PyString_Check(obj)) {
1778                                 PyErr_Format(PyExc_TypeError,
1779                                              "Expected string as element %zd in list", i);
1780                                 talloc_free(me);
1781                                 return NULL;
1782                         }
1783
1784                         me->values[i].length = PyString_Size(obj);
1785                         me->values[i].data = talloc_memdup(me, 
1786                                 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
1787                 }
1788         } else {
1789                 talloc_free(me);
1790                 me = NULL;
1791         }
1792
1793         return me;
1794 }
1795
1796
1797 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
1798                                         struct ldb_message_element *me)
1799 {
1800         Py_ssize_t i;
1801         PyObject *result;
1802
1803         /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
1804         result = PyList_New(me->num_values);
1805
1806         for (i = 0; i < me->num_values; i++) {
1807                 PyList_SetItem(result, i,
1808                         PyObject_FromLdbValue(ldb_ctx, me, &me->values[i]));
1809         }
1810
1811         return result;
1812 }
1813
1814 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
1815 {
1816         unsigned int i;
1817         if (!PyArg_ParseTuple(args, "I", &i))
1818                 return NULL;
1819         if (i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
1820                 Py_RETURN_NONE;
1821
1822         return PyObject_FromLdbValue(NULL, PyLdbMessageElement_AsMessageElement(self), 
1823                                                                  &(PyLdbMessageElement_AsMessageElement(self)->values[i]));
1824 }
1825
1826 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
1827 {
1828         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1829         return PyInt_FromLong(el->flags);
1830 }
1831
1832 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
1833 {
1834         int flags;
1835         struct ldb_message_element *el;
1836         if (!PyArg_ParseTuple(args, "i", &flags))
1837                 return NULL;
1838
1839         el = PyLdbMessageElement_AsMessageElement(self);
1840         el->flags = flags;
1841         Py_RETURN_NONE;
1842 }
1843
1844 static PyMethodDef py_ldb_msg_element_methods[] = {
1845         { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
1846         { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
1847         { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
1848         { NULL },
1849 };
1850
1851 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
1852 {
1853         return PyLdbMessageElement_AsMessageElement(self)->num_values;
1854 }
1855
1856 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
1857 {
1858         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1859         if (idx < 0 || idx >= el->num_values) {
1860                 PyErr_SetString(PyExc_IndexError, "Out of range");
1861                 return NULL;
1862         }
1863         return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
1864 }
1865
1866 static PySequenceMethods py_ldb_msg_element_seq = {
1867         .sq_length = (lenfunc)py_ldb_msg_element_len,
1868         .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
1869 };
1870
1871 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
1872 {
1873         int ret = ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self),
1874                                                                           PyLdbMessageElement_AsMessageElement(other));
1875         return SIGN(ret);
1876 }
1877
1878 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
1879 {
1880         return PyObject_GetIter(ldb_msg_element_to_set(NULL, PyLdbMessageElement_AsMessageElement(self)));
1881 }
1882
1883 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
1884 {
1885         PyLdbMessageElementObject *ret;
1886         ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
1887         if (ret == NULL) {
1888                 PyErr_NoMemory();
1889                 return NULL;
1890         }
1891         ret->mem_ctx = talloc_new(NULL);
1892         if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
1893                 PyErr_NoMemory();
1894                 return NULL;
1895         }
1896         ret->el = el;
1897         return (PyObject *)ret;
1898 }
1899
1900 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1901 {
1902         PyObject *py_elements = NULL;
1903         struct ldb_message_element *el;
1904         int flags = 0;
1905         char *name = NULL;
1906         const char * const kwnames[] = { "elements", "flags", "name", NULL };
1907         PyLdbMessageElementObject *ret;
1908         TALLOC_CTX *mem_ctx;
1909
1910         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Ois",
1911                                          discard_const_p(char *, kwnames),
1912                                          &py_elements, &flags, &name))
1913                 return NULL;
1914
1915         mem_ctx = talloc_new(NULL);
1916         if (mem_ctx == NULL) {
1917                 PyErr_NoMemory();
1918                 return NULL;
1919         }
1920
1921         el = talloc_zero(mem_ctx, struct ldb_message_element);
1922         if (el == NULL) {
1923                 PyErr_NoMemory();
1924                 talloc_free(mem_ctx);
1925                 return NULL;
1926         }
1927
1928         if (py_elements != NULL) {
1929                 Py_ssize_t i;
1930                 if (PyString_Check(py_elements)) {
1931                         el->num_values = 1;
1932                         el->values = talloc_array(el, struct ldb_val, 1);
1933                         if (el->values == NULL) {
1934                                 talloc_free(mem_ctx);
1935                                 PyErr_NoMemory();
1936                                 return NULL;
1937                         }
1938                         el->values[0].length = PyString_Size(py_elements);
1939                         el->values[0].data = talloc_memdup(el->values, 
1940                                 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
1941                 } else if (PySequence_Check(py_elements)) {
1942                         el->num_values = PySequence_Size(py_elements);
1943                         el->values = talloc_array(el, struct ldb_val, el->num_values);
1944                         if (el->values == NULL) {
1945                                 talloc_free(mem_ctx);
1946                                 PyErr_NoMemory();
1947                                 return NULL;
1948                         }
1949                         for (i = 0; i < el->num_values; i++) {
1950                                 PyObject *item = PySequence_GetItem(py_elements, i);
1951                                 if (item == NULL) {
1952                                         talloc_free(mem_ctx);
1953                                         return NULL;
1954                                 }
1955                                 if (!PyString_Check(item)) {
1956                                         PyErr_Format(PyExc_TypeError, 
1957                                                      "Expected string as element %zd in list", i);
1958                                         talloc_free(mem_ctx);
1959                                         return NULL;
1960                                 }
1961                                 el->values[i].length = PyString_Size(item);
1962                                 el->values[i].data = talloc_memdup(el,
1963                                         (uint8_t *)PyString_AsString(item), el->values[i].length+1);
1964                         }
1965                 } else {
1966                         PyErr_SetString(PyExc_TypeError, 
1967                                         "Expected string or list");
1968                         talloc_free(mem_ctx);
1969                         return NULL;
1970                 }
1971         }
1972
1973         el->flags = flags;
1974         el->name = talloc_strdup(el, name);
1975
1976         ret = PyObject_New(PyLdbMessageElementObject, type);
1977         if (ret == NULL) {
1978                 talloc_free(mem_ctx);
1979                 return NULL;
1980         }
1981
1982         ret->mem_ctx = mem_ctx;
1983         ret->el = el;
1984         return (PyObject *)ret;
1985 }
1986
1987 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
1988 {
1989         char *element_str = NULL;
1990         Py_ssize_t i;
1991         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1992         PyObject *ret;
1993
1994         for (i = 0; i < el->num_values; i++) {
1995                 PyObject *o = py_ldb_msg_element_find(self, i);
1996                 if (element_str == NULL)
1997                         element_str = talloc_strdup(NULL, PyObject_REPR(o));
1998                 else
1999                         element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2000         }
2001
2002         if (element_str != NULL) {
2003                 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2004                 talloc_free(element_str);
2005         } else {
2006                 ret = PyString_FromString("MessageElement([])");
2007         }
2008
2009         return ret;
2010 }
2011
2012 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2013 {
2014         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
2015
2016         if (el->num_values == 1)
2017                 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2018         else
2019                 Py_RETURN_NONE;
2020 }
2021
2022 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2023 {
2024         talloc_free(self->mem_ctx);
2025         PyObject_Del(self);
2026 }
2027
2028 static PyTypeObject PyLdbMessageElement = {
2029         .tp_name = "ldb.MessageElement",
2030         .tp_basicsize = sizeof(PyLdbMessageElementObject),
2031         .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2032         .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2033         .tp_str = (reprfunc)py_ldb_msg_element_str,
2034         .tp_methods = py_ldb_msg_element_methods,
2035         .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2036         .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2037         .tp_as_sequence = &py_ldb_msg_element_seq,
2038         .tp_new = py_ldb_msg_element_new,
2039         .tp_flags = Py_TPFLAGS_DEFAULT,
2040 };
2041
2042
2043 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2044 {
2045         PyObject *py_ldb;
2046         PyObject *py_dict;
2047         PyObject *py_ret;
2048         struct ldb_message *msg;
2049         struct ldb_context *ldb_ctx;
2050         unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2051
2052         if (!PyArg_ParseTuple(args, "O!O!|I",
2053                               &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2054                               &mod_flags)) {
2055                 return NULL;
2056         }
2057
2058         /* mask only flags we are going to use */
2059         mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2060         if (!mod_flags) {
2061                 PyErr_SetString(PyExc_ValueError,
2062                                 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2063                                 " expected as mod_flag value");
2064                 return NULL;
2065         }
2066
2067         ldb_ctx = PyLdb_AsLdbContext(py_ldb);
2068
2069         msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2070         if (!msg) {
2071                 return NULL;
2072         }
2073
2074         py_ret = PyLdbMessage_FromMessage(msg);
2075
2076         talloc_unlink(ldb_ctx, msg);
2077
2078         return py_ret;
2079 }
2080
2081 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2082 {
2083         char *name;
2084         if (!PyArg_ParseTuple(args, "s", &name))
2085                 return NULL;
2086
2087         ldb_msg_remove_attr(self->msg, name);
2088
2089         Py_RETURN_NONE;
2090 }
2091
2092 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2093 {
2094         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2095         Py_ssize_t i, j = 0;
2096         PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2097         if (msg->dn != NULL) {
2098                 PyList_SetItem(obj, j, PyString_FromString("dn"));
2099                 j++;
2100         }
2101         for (i = 0; i < msg->num_elements; i++) {
2102                 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2103                 j++;
2104         }
2105         return obj;
2106 }
2107
2108 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2109 {
2110         struct ldb_message_element *el;
2111         char *name;
2112         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2113         if (!PyString_Check(py_name)) {
2114                 PyErr_SetNone(PyExc_TypeError);
2115                 return NULL;
2116         }
2117         name = PyString_AsString(py_name);
2118         if (!strcmp(name, "dn"))
2119                 return PyLdbDn_FromDn(msg->dn);
2120         el = ldb_msg_find_element(msg, name);
2121         if (el == NULL) {
2122                 return NULL;
2123         }
2124         return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2125 }
2126
2127 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2128 {
2129         PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2130         if (ret == NULL) {
2131                 PyErr_SetString(PyExc_KeyError, "No such element");
2132                 return NULL;
2133         }
2134         return ret;
2135 }
2136
2137 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args)
2138 {
2139         PyObject *name, *ret;
2140         if (!PyArg_ParseTuple(args, "O", &name))
2141                 return NULL;
2142
2143         ret = py_ldb_msg_getitem_helper(self, name);
2144         if (ret == NULL) {
2145                 if (PyErr_Occurred())
2146                         return NULL;
2147                 Py_RETURN_NONE;
2148         }
2149         return ret;
2150 }
2151
2152 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2153 {
2154         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2155         Py_ssize_t i, j = 0;
2156         PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2157         if (msg->dn != NULL) {
2158                 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn)));
2159                 j++;
2160         }
2161         for (i = 0; i < msg->num_elements; i++, j++) {
2162                 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2163                 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2164                 PyList_SetItem(l, j, value);
2165         }
2166         return l;
2167 }
2168
2169 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2170 {
2171         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2172         Py_ssize_t i = 0;
2173         PyObject *l = PyList_New(msg->num_elements);
2174         for (i = 0; i < msg->num_elements; i++) {
2175                 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2176         }
2177         return l;
2178 }
2179
2180 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2181 {
2182         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2183         PyLdbMessageElementObject *py_element;
2184         int ret;
2185         struct ldb_message_element *el;
2186
2187         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2188                 return NULL;
2189
2190         el = talloc_reference(msg, py_element->el);
2191         if (el == NULL) {
2192                 PyErr_NoMemory();
2193                 return NULL;
2194         }
2195
2196         ret = ldb_msg_add(msg, el, el->flags);
2197         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2198
2199         Py_RETURN_NONE;
2200 }
2201
2202 static PyMethodDef py_ldb_msg_methods[] = {
2203         { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2204                 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2205                 "Class method to create ldb.Message object from Dictionary.\n"
2206                 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2207         { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, 
2208                 "S.keys() -> list\n\n"
2209                 "Return sequence of all attribute names." },
2210         { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, 
2211                 "S.remove(name)\n\n"
2212                 "Remove all entries for attributes with the specified name."},
2213         { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL },
2214         { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2215         { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2216         { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2217                 "S.append(element)\n\n"
2218                 "Add an element to this message." },
2219         { NULL },
2220 };
2221
2222 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2223 {
2224         PyObject *list, *iter;
2225
2226         list = py_ldb_msg_keys(self);
2227         iter = PyObject_GetIter(list);
2228         Py_DECREF(list);
2229         return iter;
2230 }
2231
2232 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2233 {
2234         char *attr_name;
2235
2236         if (!PyString_Check(name)) {
2237                 PyErr_SetNone(PyExc_TypeError);
2238                 return -1;
2239         }
2240
2241         attr_name = PyString_AsString(name);
2242         if (value == NULL) {
2243                 /* delitem */
2244                 ldb_msg_remove_attr(self->msg, attr_name);
2245         } else {
2246                 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2247                                                                            value, 0, attr_name);
2248                 if (el == NULL)
2249                         return -1;
2250                 ldb_msg_remove_attr(PyLdbMessage_AsMessage(self), attr_name);
2251                 ldb_msg_add(PyLdbMessage_AsMessage(self), el, el->flags);
2252         }
2253         return 0;
2254 }
2255
2256 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2257 {
2258         return PyLdbMessage_AsMessage(self)->num_elements;
2259 }
2260
2261 static PyMappingMethods py_ldb_msg_mapping = {
2262         .mp_length = (lenfunc)py_ldb_msg_length,
2263         .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2264         .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2265 };
2266
2267 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2268 {
2269         const char * const kwnames[] = { "dn", NULL };
2270         struct ldb_message *ret;
2271         TALLOC_CTX *mem_ctx;
2272         PyObject *pydn = NULL;
2273         PyLdbMessageObject *py_ret;
2274
2275         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2276                                          discard_const_p(char *, kwnames),
2277                                          &pydn))
2278                 return NULL;
2279
2280         mem_ctx = talloc_new(NULL);
2281         if (mem_ctx == NULL) {
2282                 PyErr_NoMemory();
2283                 return NULL;
2284         }
2285
2286         ret = ldb_msg_new(mem_ctx);
2287         if (ret == NULL) {
2288                 talloc_free(mem_ctx);
2289                 PyErr_NoMemory();
2290                 return NULL;
2291         }
2292
2293         if (pydn != NULL) {
2294                 struct ldb_dn *dn;
2295                 if (!PyObject_AsDn(NULL, pydn, NULL, &dn)) {
2296                         talloc_free(mem_ctx);
2297                         return NULL;
2298                 }
2299                 ret->dn = talloc_reference(ret, dn);
2300         }
2301
2302         py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2303         if (py_ret == NULL) {
2304                 PyErr_NoMemory();
2305                 talloc_free(mem_ctx);
2306                 return NULL;
2307         }
2308
2309         py_ret->mem_ctx = mem_ctx;
2310         py_ret->msg = ret;
2311         return (PyObject *)py_ret;
2312 }
2313
2314 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2315 {
2316         PyLdbMessageObject *ret;
2317
2318         ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2319         if (ret == NULL) {
2320                 PyErr_NoMemory();
2321                 return NULL;
2322         }
2323         ret->mem_ctx = talloc_new(NULL);
2324         ret->msg = talloc_reference(ret->mem_ctx, msg);
2325         return (PyObject *)ret;
2326 }
2327
2328 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2329 {
2330         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2331         return PyLdbDn_FromDn(msg->dn);
2332 }
2333
2334 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2335 {
2336         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
2337         if (!PyLdbDn_Check(value)) {
2338                 PyErr_SetNone(PyExc_TypeError);
2339                 return -1;
2340         }
2341
2342         msg->dn = talloc_reference(msg, PyLdbDn_AsDn(value));
2343         return 0;
2344 }
2345
2346 static PyGetSetDef py_ldb_msg_getset[] = {
2347         { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2348         { NULL }
2349 };
2350
2351 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2352 {
2353         PyObject *dict = PyDict_New(), *ret;
2354         if (PyDict_Update(dict, (PyObject *)self) != 0)
2355                 return NULL;
2356         ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2357         Py_DECREF(dict);
2358         return ret;
2359 }
2360
2361 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2362 {
2363         talloc_free(self->mem_ctx);
2364         PyObject_Del(self);
2365 }
2366
2367 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2368                               PyLdbMessageObject *py_msg2)
2369 {
2370         struct ldb_message *msg1 = PyLdbMessage_AsMessage(py_msg1),
2371                            *msg2 = PyLdbMessage_AsMessage(py_msg2);
2372         unsigned int i;
2373         int ret;
2374
2375         if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2376                 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2377                 if (ret != 0) {
2378                         return SIGN(ret);
2379                 }
2380         }
2381
2382         ret = msg1->num_elements - msg2->num_elements;
2383         if (ret != 0) {
2384                 return SIGN(ret);
2385         }
2386
2387         for (i = 0; i < msg1->num_elements; i++) {
2388                 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2389                                                    &msg2->elements[i]);
2390                 if (ret != 0) {
2391                         return SIGN(ret);
2392                 }
2393
2394                 ret = ldb_msg_element_compare(&msg1->elements[i],
2395                                               &msg2->elements[i]);
2396                 if (ret != 0) {
2397                         return SIGN(ret);
2398                 }
2399         }
2400
2401         return 0;
2402 }
2403
2404 static PyTypeObject PyLdbMessage = {
2405         .tp_name = "ldb.Message",
2406         .tp_methods = py_ldb_msg_methods,
2407         .tp_getset = py_ldb_msg_getset,
2408         .tp_as_mapping = &py_ldb_msg_mapping,
2409         .tp_basicsize = sizeof(PyLdbMessageObject),
2410         .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2411         .tp_new = py_ldb_msg_new,
2412         .tp_repr = (reprfunc)py_ldb_msg_repr,
2413         .tp_flags = Py_TPFLAGS_DEFAULT,
2414         .tp_iter = (getiterfunc)py_ldb_msg_iter,
2415         .tp_compare = (cmpfunc)py_ldb_msg_compare,
2416 };
2417
2418 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2419 {
2420         PyLdbTreeObject *ret;
2421
2422         ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2423         if (ret == NULL) {
2424                 PyErr_NoMemory();
2425                 return NULL;
2426         }
2427
2428         ret->mem_ctx = talloc_new(NULL);
2429         ret->tree = talloc_reference(ret->mem_ctx, tree);
2430         return (PyObject *)ret;
2431 }
2432
2433 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2434 {
2435         talloc_free(self->mem_ctx);
2436         PyObject_Del(self);
2437 }
2438
2439 static PyTypeObject PyLdbTree = {
2440         .tp_name = "ldb.Tree",
2441         .tp_basicsize = sizeof(PyLdbTreeObject),
2442         .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2443         .tp_flags = Py_TPFLAGS_DEFAULT,
2444 };
2445
2446 /* Ldb_module */
2447 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2448 {
2449         PyObject *py_ldb = (PyObject *)mod->private_data;
2450         PyObject *py_result, *py_base, *py_attrs, *py_tree;
2451
2452         py_base = PyLdbDn_FromDn(req->op.search.base);
2453
2454         if (py_base == NULL)
2455                 return LDB_ERR_OPERATIONS_ERROR;
2456
2457         py_tree = PyLdbTree_FromTree(req->op.search.tree);
2458
2459         if (py_tree == NULL)
2460                 return LDB_ERR_OPERATIONS_ERROR;
2461
2462         if (req->op.search.attrs == NULL) {
2463                 py_attrs = Py_None;
2464         } else {
2465                 int i, len;
2466                 for (len = 0; req->op.search.attrs[len]; len++);
2467                 py_attrs = PyList_New(len);
2468                 for (i = 0; i < len; i++)
2469                         PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2470         }
2471
2472         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2473                                         discard_const_p(char, "OiOO"),
2474                                         py_base, req->op.search.scope, py_tree, py_attrs);
2475
2476         Py_DECREF(py_attrs);
2477         Py_DECREF(py_tree);
2478         Py_DECREF(py_base);
2479
2480         if (py_result == NULL) {
2481                 return LDB_ERR_PYTHON_EXCEPTION;
2482         }
2483
2484         req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2485         if (req->op.search.res == NULL) {
2486                 return LDB_ERR_PYTHON_EXCEPTION;
2487         }
2488
2489         Py_DECREF(py_result);
2490
2491         return LDB_SUCCESS;
2492 }
2493
2494 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2495 {
2496         PyObject *py_ldb = (PyObject *)mod->private_data;
2497         PyObject *py_result, *py_msg;
2498
2499         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2500
2501         if (py_msg == NULL) {
2502                 return LDB_ERR_OPERATIONS_ERROR;
2503         }
2504
2505         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2506                                         discard_const_p(char, "O"),
2507                                         py_msg);
2508
2509         Py_DECREF(py_msg);
2510
2511         if (py_result == NULL) {
2512                 return LDB_ERR_PYTHON_EXCEPTION;
2513         }
2514
2515         Py_DECREF(py_result);
2516
2517         return LDB_SUCCESS;
2518 }
2519
2520 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
2521 {
2522         PyObject *py_ldb = (PyObject *)mod->private_data;
2523         PyObject *py_result, *py_msg;
2524
2525         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
2526
2527         if (py_msg == NULL) {
2528                 return LDB_ERR_OPERATIONS_ERROR;
2529         }
2530
2531         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
2532                                         discard_const_p(char, "O"),
2533                                         py_msg);
2534
2535         Py_DECREF(py_msg);
2536
2537         if (py_result == NULL) {
2538                 return LDB_ERR_PYTHON_EXCEPTION;
2539         }
2540
2541         Py_DECREF(py_result);
2542
2543         return LDB_SUCCESS;
2544 }
2545
2546 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
2547 {
2548         PyObject *py_ldb = (PyObject *)mod->private_data;
2549         PyObject *py_result, *py_dn;
2550
2551         py_dn = PyLdbDn_FromDn(req->op.del.dn);
2552
2553         if (py_dn == NULL)
2554                 return LDB_ERR_OPERATIONS_ERROR;
2555
2556         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
2557                                         discard_const_p(char, "O"),
2558                                         py_dn);
2559
2560         if (py_result == NULL) {
2561                 return LDB_ERR_PYTHON_EXCEPTION;
2562         }
2563
2564         Py_DECREF(py_result);
2565
2566         return LDB_SUCCESS;
2567 }
2568
2569 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
2570 {
2571         PyObject *py_ldb = (PyObject *)mod->private_data;
2572         PyObject *py_result, *py_olddn, *py_newdn;
2573
2574         py_olddn = PyLdbDn_FromDn(req->op.rename.olddn);
2575
2576         if (py_olddn == NULL)
2577                 return LDB_ERR_OPERATIONS_ERROR;
2578
2579         py_newdn = PyLdbDn_FromDn(req->op.rename.newdn);
2580
2581         if (py_newdn == NULL)
2582                 return LDB_ERR_OPERATIONS_ERROR;
2583
2584         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
2585                                         discard_const_p(char, "OO"),
2586                                         py_olddn, py_newdn);
2587
2588         Py_DECREF(py_olddn);
2589         Py_DECREF(py_newdn);
2590
2591         if (py_result == NULL) {
2592                 return LDB_ERR_PYTHON_EXCEPTION;
2593         }
2594
2595         Py_DECREF(py_result);
2596
2597         return LDB_SUCCESS;
2598 }
2599
2600 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
2601 {
2602         PyObject *py_ldb = (PyObject *)mod->private_data;
2603         PyObject *py_result;
2604
2605         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
2606                                         discard_const_p(char, ""));
2607
2608         return LDB_ERR_OPERATIONS_ERROR;
2609 }
2610
2611 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
2612 {
2613         PyObject *py_ldb = (PyObject *)mod->private_data;
2614         PyObject *py_result;
2615
2616         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
2617                                         discard_const_p(char, ""));
2618
2619         return LDB_ERR_OPERATIONS_ERROR;
2620 }
2621
2622 static int py_module_start_transaction(struct ldb_module *mod)
2623 {
2624         PyObject *py_ldb = (PyObject *)mod->private_data;
2625         PyObject *py_result;
2626
2627         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
2628                                         discard_const_p(char, ""));
2629
2630         if (py_result == NULL) {
2631                 return LDB_ERR_PYTHON_EXCEPTION;
2632         }
2633
2634         Py_DECREF(py_result);
2635
2636         return LDB_SUCCESS;
2637 }
2638
2639 static int py_module_end_transaction(struct ldb_module *mod)
2640 {
2641         PyObject *py_ldb = (PyObject *)mod->private_data;
2642         PyObject *py_result;
2643
2644         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
2645                                         discard_const_p(char, ""));
2646
2647         if (py_result == NULL) {
2648                 return LDB_ERR_PYTHON_EXCEPTION;
2649         }
2650
2651         Py_DECREF(py_result);
2652
2653         return LDB_SUCCESS;
2654 }
2655
2656 static int py_module_del_transaction(struct ldb_module *mod)
2657 {
2658         PyObject *py_ldb = (PyObject *)mod->private_data;
2659         PyObject *py_result;
2660
2661         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
2662                                         discard_const_p(char, ""));
2663
2664         if (py_result == NULL) {
2665                 return LDB_ERR_PYTHON_EXCEPTION;
2666         }
2667
2668         Py_DECREF(py_result);
2669
2670         return LDB_SUCCESS;
2671 }
2672
2673 static int py_module_destructor(struct ldb_module *mod)
2674 {
2675         Py_DECREF((PyObject *)mod->private_data);
2676         return 0;
2677 }
2678
2679 static int py_module_init(struct ldb_module *mod)
2680 {
2681         PyObject *py_class = (PyObject *)mod->ops->private_data;
2682         PyObject *py_result, *py_next, *py_ldb;
2683
2684         py_ldb = PyLdb_FromLdbContext(mod->ldb);
2685
2686         if (py_ldb == NULL)
2687                 return LDB_ERR_OPERATIONS_ERROR;
2688
2689         py_next = PyLdbModule_FromModule(mod->next);
2690
2691         if (py_next == NULL)
2692                 return LDB_ERR_OPERATIONS_ERROR;
2693
2694         py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
2695                                           py_ldb, py_next);
2696
2697         if (py_result == NULL) {
2698                 return LDB_ERR_PYTHON_EXCEPTION;
2699         }
2700
2701         mod->private_data = py_result;
2702
2703         talloc_set_destructor(mod, py_module_destructor);
2704
2705         return ldb_next_init(mod);
2706 }
2707
2708 static PyObject *py_register_module(PyObject *module, PyObject *args)
2709 {
2710         int ret;
2711         struct ldb_module_ops *ops;
2712         PyObject *input;
2713
2714         if (!PyArg_ParseTuple(args, "O", &input))
2715                 return NULL;
2716
2717         ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
2718         if (ops == NULL) {
2719                 PyErr_NoMemory();
2720                 return NULL;
2721         }
2722
2723         ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
2724
2725         Py_INCREF(input);
2726         ops->private_data = input;
2727         ops->init_context = py_module_init;
2728         ops->search = py_module_search;
2729         ops->add = py_module_add;
2730         ops->modify = py_module_modify;
2731         ops->del = py_module_del;
2732         ops->rename = py_module_rename;
2733         ops->request = py_module_request;
2734         ops->extended = py_module_extended;
2735         ops->start_transaction = py_module_start_transaction;
2736         ops->end_transaction = py_module_end_transaction;
2737         ops->del_transaction = py_module_del_transaction;
2738
2739         ret = ldb_register_module(ops);
2740
2741         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2742
2743         Py_RETURN_NONE;
2744 }
2745
2746 static PyObject *py_timestring(PyObject *module, PyObject *args)
2747 {
2748         /* most times "time_t" is a signed integer type with 32 or 64 bit:
2749          * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
2750         long int t_val;
2751         char *tresult;
2752         PyObject *ret;
2753         if (!PyArg_ParseTuple(args, "l", &t_val))
2754                 return NULL;
2755         tresult = ldb_timestring(NULL, (time_t) t_val);
2756         ret = PyString_FromString(tresult);
2757         talloc_free(tresult);
2758         return ret;
2759 }
2760
2761 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
2762 {
2763         char *str;
2764         if (!PyArg_ParseTuple(args, "s", &str))
2765                 return NULL;
2766
2767         return PyInt_FromLong(ldb_string_to_time(str));
2768 }
2769
2770 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
2771 {
2772         char *name;
2773         if (!PyArg_ParseTuple(args, "s", &name))
2774                 return NULL;
2775         return PyBool_FromLong(ldb_valid_attr_name(name));
2776 }
2777
2778 static PyMethodDef py_ldb_global_methods[] = {
2779         { "register_module", py_register_module, METH_VARARGS, 
2780                 "S.register_module(module) -> None\n"
2781                 "Register a LDB module."},
2782         { "timestring", py_timestring, METH_VARARGS, 
2783                 "S.timestring(int) -> string\n"
2784                 "Generate a LDAP time string from a UNIX timestamp" },
2785         { "string_to_time", py_string_to_time, METH_VARARGS,
2786                 "S.string_to_time(string) -> int\n"
2787                 "Parse a LDAP time string into a UNIX timestamp." },
2788         { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
2789                 "S.valid_attr_name(name) -> bool\n"
2790                 "Check whether the supplied name is a valid attribute name." },
2791         { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
2792                 NULL },
2793         { NULL }
2794 };
2795
2796 void initldb(void)
2797 {
2798         PyObject *m;
2799
2800         if (PyType_Ready(&PyLdbDn) < 0)
2801                 return;
2802
2803         if (PyType_Ready(&PyLdbMessage) < 0)
2804                 return;
2805
2806         if (PyType_Ready(&PyLdbMessageElement) < 0)
2807                 return;
2808
2809         if (PyType_Ready(&PyLdb) < 0)
2810                 return;
2811
2812         if (PyType_Ready(&PyLdbModule) < 0)
2813                 return;
2814
2815         if (PyType_Ready(&PyLdbTree) < 0)
2816                 return;
2817
2818         m = Py_InitModule3("ldb", py_ldb_global_methods, 
2819                 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
2820         if (m == NULL)
2821                 return;
2822
2823         PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
2824         PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
2825         PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
2826         PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
2827         PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
2828         PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
2829         PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
2830
2831         PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
2832         PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
2833         PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
2834         PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
2835
2836         PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
2837         PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
2838         PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
2839
2840         PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
2841         PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
2842         PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
2843         PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
2844         PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
2845         PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
2846         PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
2847         PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
2848         PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
2849         PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
2850         PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
2851         PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
2852         PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
2853         PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
2854         PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
2855         PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
2856         PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
2857         PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
2858         PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
2859         PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
2860         PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
2861         PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
2862         PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
2863         PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
2864         PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
2865         PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
2866         PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
2867         PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
2868         PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
2869         PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
2870         PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
2871         PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
2872         PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
2873         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
2874         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
2875         PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
2876         PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
2877         PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
2878         PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
2879
2880         PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
2881         PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
2882         PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
2883         PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
2884
2885         PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
2886
2887         PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
2888         PyModule_AddObject(m, "LdbError", PyExc_LdbError);
2889
2890         Py_INCREF(&PyLdb);
2891         Py_INCREF(&PyLdbDn);
2892         Py_INCREF(&PyLdbModule);
2893         Py_INCREF(&PyLdbMessage);
2894         Py_INCREF(&PyLdbMessageElement);
2895         Py_INCREF(&PyLdbTree);
2896
2897         PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
2898         PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
2899         PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
2900         PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
2901         PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
2902         PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
2903
2904         PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
2905 }