pyldb: Properly preallocate result control list
[gd/samba-autobuild/.git] / 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    Copyright (C) 2009-2011 Andrew Tridgell
11    Copyright (C) 2009-2011 Andrew Bartlett
12
13     ** NOTE! The following LGPL license applies to the ldb
14     ** library. This does NOT imply that all of Samba is released
15     ** under the LGPL
16
17    This library is free software; you can redistribute it and/or
18    modify it under the terms of the GNU Lesser General Public
19    License as published by the Free Software Foundation; either
20    version 3 of the License, or (at your option) any later version.
21
22    This library is distributed in the hope that it will be useful,
23    but WITHOUT ANY WARRANTY; without even the implied warranty of
24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25    Lesser General Public License for more details.
26
27    You should have received a copy of the GNU Lesser General Public
28    License along with this library; if not, see <http://www.gnu.org/licenses/>.
29 */
30
31 #include <Python.h>
32 #include "ldb_private.h"
33 #include "pyldb.h"
34
35 void initldb(void);
36 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
37 static PyObject *PyExc_LdbError;
38
39 static PyTypeObject PyLdbControl;
40 static PyTypeObject PyLdbResult;
41 static PyTypeObject PyLdbMessage;
42 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
43 static PyTypeObject PyLdbModule;
44 static PyTypeObject PyLdbDn;
45 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
46 static PyTypeObject PyLdb;
47 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
48 static PyTypeObject PyLdbMessageElement;
49 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
50
51 staticforward PyTypeObject PyLdbTree;
52 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
53 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
54 static struct ldb_message_element *PyObject_AsMessageElement(
55                                                       TALLOC_CTX *mem_ctx,
56                                                       PyObject *set_obj,
57                                                       unsigned int flags,
58                                                       const char *attr_name);
59
60 /* There's no Py_ssize_t in 2.4, apparently */
61 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
62 typedef int Py_ssize_t;
63 typedef inquiry lenfunc;
64 typedef intargfunc ssizeargfunc;
65 #endif
66
67 #define SIGN(a) (((a) == 0)?0:((a) < 0?-1:1))
68
69
70
71 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
72 {
73         if (self->data != NULL) {
74                 char* control = ldb_control_to_string(self->mem_ctx, self->data);
75                 if (control == NULL) {
76                         PyErr_NoMemory();
77                         return NULL;
78                 }
79                 return PyString_FromString(control);
80         } else {
81                 return PyString_FromFormat("ldb control");
82         }
83 }
84
85 static void py_ldb_control_dealloc(PyLdbControlObject *self)
86 {
87         if (self->mem_ctx != NULL) {
88                 talloc_free(self->mem_ctx);
89         }
90         self->data = NULL;
91         Py_TYPE(self)->tp_free(self);
92 }
93
94 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
95 {
96         return PyString_FromString(self->data->oid);
97 }
98
99 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
100 {
101         return PyBool_FromLong(self->data->critical);
102 }
103
104 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
105 {
106         if (PyObject_IsTrue(value)) {
107                 self->data->critical = true;
108         } else {
109                 self->data->critical = false;
110         }
111         return 0;
112 }
113
114 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
115 {
116         char *data = NULL;
117         const char * const kwnames[] = { "ldb", "data", NULL };
118         struct ldb_control *parsed_controls;
119         PyLdbControlObject *ret;
120         PyObject *py_ldb;
121         TALLOC_CTX *mem_ctx;
122         struct ldb_context *ldb_ctx;
123
124         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
125                                          discard_const_p(char *, kwnames),
126                                          &py_ldb, &data))
127                 return NULL;
128
129         mem_ctx = talloc_new(NULL);
130         if (mem_ctx == NULL) {
131                 PyErr_NoMemory();
132                 return NULL;
133         }
134
135         ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
136         parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
137
138         if (!parsed_controls) {
139                 talloc_free(mem_ctx);
140                 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
141                 return NULL;
142         }
143
144         ret = PyObject_New(PyLdbControlObject, type);
145         if (ret == NULL) {
146                 PyErr_NoMemory();
147                 talloc_free(mem_ctx);
148                 return NULL;
149         }
150
151         ret->mem_ctx = mem_ctx;
152
153         ret->data = talloc_move(mem_ctx, &parsed_controls);
154         if (ret->data == NULL) {
155                 Py_DECREF(ret);
156                 PyErr_NoMemory();
157                 talloc_free(mem_ctx);
158                 return NULL;
159         }
160
161         return (PyObject *)ret;
162 }
163
164 static PyGetSetDef py_ldb_control_getset[] = {
165         { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
166         { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
167         { NULL }
168 };
169
170 static PyTypeObject PyLdbControl = {
171         .tp_name = "ldb.control",
172         .tp_dealloc = (destructor)py_ldb_control_dealloc,
173         .tp_getattro = PyObject_GenericGetAttr,
174         .tp_basicsize = sizeof(PyLdbControlObject),
175         .tp_getset = py_ldb_control_getset,
176         .tp_doc = "LDB control.",
177         .tp_str = (reprfunc)py_ldb_control_str,
178         .tp_new = py_ldb_control_new,
179         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
180 };
181
182 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
183 {
184         if (ret == LDB_ERR_PYTHON_EXCEPTION)
185                 return; /* Python exception should already be set, just keep that */
186
187         PyErr_SetObject(error, 
188                         Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
189                                       ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
190 }
191
192 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
193 {
194         return PyString_FromStringAndSize((const char *)val->data, val->length);
195 }
196
197 /**
198  * Create a Python object from a ldb_result.
199  *
200  * @param result LDB result to convert
201  * @return Python object with converted result (a list object)
202  */
203 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
204 {
205         TALLOC_CTX *ctl_ctx = talloc_new(NULL);
206         PyLdbControlObject *ctrl;
207         if (ctl_ctx == NULL) {
208                 PyErr_NoMemory();
209                 return NULL;
210         }
211
212         ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
213         if (ctrl == NULL) {
214                 talloc_free(ctl_ctx);
215                 PyErr_NoMemory();
216                 return NULL;
217         }
218         ctrl->mem_ctx = ctl_ctx;
219         ctrl->data = talloc_steal(ctrl->mem_ctx, control);
220         if (ctrl->data == NULL) {
221                 Py_DECREF(ctrl);
222                 PyErr_NoMemory();
223                 return NULL;
224         }
225         return (PyObject*) ctrl;
226 }
227
228 /**
229  * Create a Python object from a ldb_result.
230  *
231  * @param result LDB result to convert
232  * @return Python object with converted result (a list object)
233  */
234 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
235 {
236         PyLdbResultObject *ret;
237         PyObject *list, *controls, *referals;
238         Py_ssize_t i;
239
240         if (result == NULL) {
241                 Py_RETURN_NONE;
242         }
243
244         ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
245         if (ret == NULL) {
246                 PyErr_NoMemory();
247                 return NULL;
248         }
249
250         list = PyList_New(result->count);
251         if (list == NULL) {
252                 PyErr_NoMemory();
253                 Py_DECREF(ret);
254                 return NULL;
255         }
256
257         for (i = 0; i < result->count; i++) {
258                 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
259         }
260
261         ret->mem_ctx = talloc_new(NULL);
262         if (ret->mem_ctx == NULL) {
263                 Py_DECREF(list);
264                 Py_DECREF(ret);
265                 PyErr_NoMemory();
266                 return NULL;
267         }
268
269         ret->msgs = list;
270
271         if (result->controls) {
272                 i = 0;
273                 while (result->controls[i]) {
274                         i++;
275                 }
276                 controls = PyList_New(i);
277                 if (controls == NULL) {
278                         Py_DECREF(ret);
279                         PyErr_NoMemory();
280                         return NULL;
281                 }
282                 for (i=0; result->controls[i]; i++) {
283                         PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
284                         if (ctrl == NULL) {
285                                 Py_DECREF(ret);
286                                 Py_DECREF(controls);
287                                 PyErr_NoMemory();
288                                 return NULL;
289                         }
290                         PyList_SetItem(controls, i, ctrl);
291                 }
292         } else {
293                 /*
294                  * No controls so we keep an empty list
295                  */
296                 controls = PyList_New(0);
297                 if (controls == NULL) {
298                         Py_DECREF(ret);
299                         PyErr_NoMemory();
300                         return NULL;
301                 }
302         }
303
304         ret->controls = controls;
305
306         i = 0;
307
308         while (result->refs && result->refs[i]) {
309                 i++;
310         }
311
312         referals = PyList_New(i);
313         if (referals == NULL) {
314                 Py_DECREF(ret);
315                 PyErr_NoMemory();
316                 return NULL;
317         }
318
319         for (i = 0;result->refs && result->refs[i]; i++) {
320                 PyList_SetItem(referals, i, PyString_FromString(result->refs[i]));
321         }
322         ret->referals = referals;
323         return (PyObject *)ret;
324 }
325
326 /**
327  * Create a LDB Result from a Python object.
328  * If conversion fails, NULL will be returned and a Python exception set.
329  *
330  * Note: the result object only includes the messages at the moment; extended
331  * result, controls and referrals are ignored.
332  *
333  * @param mem_ctx Memory context in which to allocate the LDB Result
334  * @param obj Python object to convert
335  * @return a ldb_result, or NULL if the conversion failed
336  */
337 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, 
338                                                PyObject *obj)
339 {
340         struct ldb_result *res;
341         Py_ssize_t i;
342
343         if (obj == Py_None)
344                 return NULL;
345
346         res = talloc_zero(mem_ctx, struct ldb_result);
347         res->count = PyList_Size(obj);
348         res->msgs = talloc_array(res, struct ldb_message *, res->count);
349         for (i = 0; i < res->count; i++) {
350                 PyObject *item = PyList_GetItem(obj, i);
351                 res->msgs[i] = pyldb_Message_AsMessage(item);
352         }
353         return res;
354 }
355
356 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
357 {
358         return PyBool_FromLong(ldb_dn_validate(self->dn));
359 }
360
361 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
362 {
363         return PyBool_FromLong(ldb_dn_is_valid(self->dn));
364 }
365
366 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
367 {
368         return PyBool_FromLong(ldb_dn_is_special(self->dn));
369 }
370
371 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
372 {
373         return PyBool_FromLong(ldb_dn_is_null(self->dn));
374 }
375  
376 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
377 {
378         return PyString_FromString(ldb_dn_get_casefold(self->dn));
379 }
380
381 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
382 {
383         return PyString_FromString(ldb_dn_get_linearized(self->dn));
384 }
385
386 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
387 {
388         return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
389 }
390
391 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
392 {
393         return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
394 }
395
396 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
397 {
398         const char * const kwnames[] = { "mode", NULL };
399         int mode = 1;
400         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
401                                          discard_const_p(char *, kwnames),
402                                          &mode))
403                 return NULL;
404         return PyString_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
405 }
406
407 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
408 {
409         char *name;
410         const struct ldb_val *val;
411
412         if (!PyArg_ParseTuple(args, "s", &name))
413                 return NULL;
414         val = ldb_dn_get_extended_component(self->dn, name);
415         if (val == NULL) {
416                 Py_RETURN_NONE;
417         }
418
419         return PyString_FromStringAndSize((const char *)val->data, val->length);
420 }
421
422 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
423 {
424         char *name;
425         PyObject *value;
426         int err;
427
428         if (!PyArg_ParseTuple(args, "sO", &name, &value))
429                 return NULL;
430
431         if (value == Py_None) {
432                 err = ldb_dn_set_extended_component(self->dn, name, NULL);
433         } else {
434                 struct ldb_val val;
435                 if (!PyString_Check(value)) {
436                         PyErr_SetString(PyExc_TypeError, "Expected a string argument");
437                         return NULL;
438                 }
439                 val.data = (uint8_t *)PyString_AsString(value);
440                 val.length = PyString_Size(value);
441                 err = ldb_dn_set_extended_component(self->dn, name, &val);
442         }
443
444         if (err != LDB_SUCCESS) {
445                 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
446                 return NULL;
447         }
448
449         Py_RETURN_NONE;
450 }
451
452 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
453 {
454         return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
455 }
456
457 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
458 {
459         char *name;
460
461         if (!PyArg_ParseTuple(args, "s", &name))
462                 return NULL;
463
464         return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
465 }
466
467 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
468 {
469         int ret;
470         ret = ldb_dn_compare(dn1->dn, dn2->dn);
471         if (ret < 0) ret = -1;
472         if (ret > 0) ret = 1;
473         return ret;
474 }
475
476 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
477 {
478         struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
479         struct ldb_dn *parent;
480         PyLdbDnObject *py_ret;
481         TALLOC_CTX *mem_ctx = talloc_new(NULL);
482
483         parent = ldb_dn_get_parent(mem_ctx, dn);
484         if (parent == NULL) {
485                 talloc_free(mem_ctx);
486                 Py_RETURN_NONE;
487         }
488
489         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
490         if (py_ret == NULL) {
491                 PyErr_NoMemory();
492                 talloc_free(mem_ctx);
493                 return NULL;
494         }
495         py_ret->mem_ctx = mem_ctx;
496         py_ret->dn = parent;
497         return (PyObject *)py_ret;
498 }
499
500 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
501
502 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
503 {
504         PyObject *py_other;
505         struct ldb_dn *dn, *other;
506         if (!PyArg_ParseTuple(args, "O", &py_other))
507                 return NULL;
508
509         dn = pyldb_Dn_AsDn((PyObject *)self);
510
511         if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
512                 return NULL;
513
514         return PyBool_FromLong(ldb_dn_add_child(dn, other));
515 }
516
517 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
518 {
519         PyObject *py_other;
520         struct ldb_dn *other, *dn;
521         if (!PyArg_ParseTuple(args, "O", &py_other))
522                 return NULL;
523
524         dn = pyldb_Dn_AsDn((PyObject *)self);
525
526         if (!pyldb_Object_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
527                 return NULL;
528
529         return PyBool_FromLong(ldb_dn_add_base(dn, other));
530 }
531
532 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
533 {
534         struct ldb_dn *dn;
535         int i;
536         if (!PyArg_ParseTuple(args, "i", &i))
537                 return NULL;
538
539         dn = pyldb_Dn_AsDn((PyObject *)self);
540
541         return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
542 }
543
544 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
545 {
546         PyObject *py_base;
547         struct ldb_dn *dn, *base;
548         if (!PyArg_ParseTuple(args, "O", &py_base))
549                 return NULL;
550
551         dn = pyldb_Dn_AsDn((PyObject *)self);
552
553         if (!pyldb_Object_AsDn(NULL, py_base, dn_ldb_ctx(dn), &base))
554                 return NULL;
555
556         return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
557 }
558
559 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
560 {
561         struct ldb_dn *dn;
562         const char *name;
563         unsigned int num = 0;
564
565         if (!PyArg_ParseTuple(args, "I", &num))
566                 return NULL;
567
568         dn = pyldb_Dn_AsDn((PyObject *)self);
569
570         name = ldb_dn_get_component_name(dn, num);
571         if (name == NULL) {
572                 Py_RETURN_NONE;
573         }
574
575         return PyString_FromString(name);
576 }
577
578 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
579 {
580         struct ldb_dn *dn;
581         const struct ldb_val *val;
582         unsigned int num = 0;
583
584         if (!PyArg_ParseTuple(args, "I", &num))
585                 return NULL;
586
587         dn = pyldb_Dn_AsDn((PyObject *)self);
588
589         val = ldb_dn_get_component_val(dn, num);
590         if (val == NULL) {
591                 Py_RETURN_NONE;
592         }
593
594         return PyObject_FromLdbValue(val);
595 }
596
597 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
598 {
599         unsigned int num = 0;
600         char *name = NULL;
601         PyObject *value = Py_None;
602         struct ldb_val val = { NULL, };
603         int err;
604
605         if (!PyArg_ParseTuple(args, "IsO", &num, &name, &value))
606                 return NULL;
607
608         if (value != Py_None) {
609                 if (!PyString_Check(value)) {
610                         PyErr_SetString(PyExc_TypeError, "Expected a string argument");
611                         return NULL;
612                 }
613                 val.data = (uint8_t *)PyString_AsString(value);
614                 val.length = PyString_Size(value);
615         }
616
617         err = ldb_dn_set_component(self->dn, num, name, val);
618         if (err != LDB_SUCCESS) {
619                 PyErr_SetString(PyExc_TypeError, "Failed to set component");
620                 return NULL;
621         }
622
623         Py_RETURN_NONE;
624 }
625
626 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
627 {
628         struct ldb_dn *dn;
629         const char *name;
630
631         dn = pyldb_Dn_AsDn((PyObject *)self);
632
633         name = ldb_dn_get_rdn_name(dn);
634         if (name == NULL) {
635                 Py_RETURN_NONE;
636         }
637
638         return PyString_FromString(name);
639 }
640
641 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
642 {
643         struct ldb_dn *dn;
644         const struct ldb_val *val;
645
646         dn = pyldb_Dn_AsDn((PyObject *)self);
647
648         val = ldb_dn_get_rdn_val(dn);
649         if (val == NULL) {
650                 Py_RETURN_NONE;
651         }
652
653         return PyObject_FromLdbValue(val);
654 }
655
656 static PyMethodDef py_ldb_dn_methods[] = {
657         { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, 
658                 "S.validate() -> bool\n"
659                 "Validate DN is correct." },
660         { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
661                 "S.is_valid() -> bool\n" },
662         { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
663                 "S.is_special() -> bool\n"
664                 "Check whether this is a special LDB DN." },
665         { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
666                 "Check whether this is a null DN." },
667         { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
668                 NULL },
669         { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
670                 NULL },
671         { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
672                 "S.canonical_str() -> string\n"
673                 "Canonical version of this DN (like a posix path)." },
674         { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
675                 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
676         { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
677                 "S.canonical_ex_str() -> string\n"
678                 "Canonical version of this DN (like a posix path, with terminating newline)." },
679         { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
680                 "S.extended_str(mode=1) -> string\n"
681                 "Extended version of this DN" },
682         { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
683                 "S.parent() -> dn\n"
684                 "Get the parent for this DN." },
685         { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS, 
686                 "S.add_child(dn) -> None\n"
687                 "Add a child DN to this DN." },
688         { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
689                 "S.add_base(dn) -> None\n"
690                 "Add a base DN to this DN." },
691         { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
692                 "S.remove_base_components(int) -> bool\n"
693                 "Remove a number of DN components from the base of this DN." },
694         { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
695                 "S.check_special(name) -> bool\n\n"
696                 "Check if name is a special DN name"},
697         { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
698                 "S.get_extended_component(name) -> string\n\n"
699                 "returns a DN extended component as a binary string"},
700         { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
701                 "S.set_extended_component(name, value) -> None\n\n"
702                 "set a DN extended component as a binary string"},
703         { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
704                 "S.get_component_name(num) -> string\n"
705                 "get the attribute name of the specified component" },
706         { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
707                 "S.get_component_value(num) -> string\n"
708                 "get the attribute value of the specified component as a binary string" },
709         { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
710                 "S.get_component_value(num, name, value) -> None\n"
711                 "set the attribute name and value of the specified component" },
712         { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
713                 "S.get_rdn_name() -> string\n"
714                 "get the RDN attribute name" },
715         { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
716                 "S.get_rdn_value() -> string\n"
717                 "get the RDN attribute value as a binary string" },
718         { NULL }
719 };
720
721 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
722 {
723         return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
724 }
725
726 /*
727   copy a DN as a python object
728  */
729 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
730 {
731         PyLdbDnObject *py_ret;
732
733         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
734         if (py_ret == NULL) {
735                 PyErr_NoMemory();
736                 return NULL;
737         }
738         py_ret->mem_ctx = talloc_new(NULL);
739         py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
740         return (PyObject *)py_ret;
741 }
742
743 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
744 {
745         struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self), 
746                                   *other;
747         PyLdbDnObject *py_ret;
748
749         if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
750                 return NULL;
751
752         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
753         if (py_ret == NULL) {
754                 PyErr_NoMemory();
755                 return NULL;
756         }
757         py_ret->mem_ctx = talloc_new(NULL);
758         py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
759         ldb_dn_add_base(py_ret->dn, other);
760         return (PyObject *)py_ret;
761 }
762
763 static PySequenceMethods py_ldb_dn_seq = {
764         .sq_length = (lenfunc)py_ldb_dn_len,
765         .sq_concat = (binaryfunc)py_ldb_dn_concat,
766 };
767
768 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
769 {
770         struct ldb_dn *ret;
771         char *str;
772         PyObject *py_ldb;
773         struct ldb_context *ldb_ctx;
774         TALLOC_CTX *mem_ctx;
775         PyLdbDnObject *py_ret;
776         const char * const kwnames[] = { "ldb", "dn", NULL };
777
778         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
779                                          discard_const_p(char *, kwnames),
780                                          &py_ldb, &str))
781                 return NULL;
782
783         if (!PyLdb_Check(py_ldb)) {
784                 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
785                 return NULL;
786         }
787
788         ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
789
790         mem_ctx = talloc_new(NULL);
791         if (mem_ctx == NULL) {
792                 PyErr_NoMemory();
793                 return NULL;
794         }
795
796         ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
797         if (!ldb_dn_validate(ret)) {
798                 talloc_free(mem_ctx);
799                 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
800                 return NULL;
801         }
802
803         py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
804         if (ret == NULL) {
805                 talloc_free(mem_ctx);
806                 PyErr_NoMemory();
807                 return NULL;
808         }
809         py_ret->mem_ctx = mem_ctx;
810         py_ret->dn = ret;
811         return (PyObject *)py_ret;
812 }
813
814 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
815 {
816         talloc_free(self->mem_ctx);
817         PyObject_Del(self);
818 }
819
820 static PyTypeObject PyLdbDn = {
821         .tp_name = "ldb.Dn",
822         .tp_methods = py_ldb_dn_methods,
823         .tp_str = (reprfunc)py_ldb_dn_get_linearized,
824         .tp_repr = (reprfunc)py_ldb_dn_repr,
825         .tp_compare = (cmpfunc)py_ldb_dn_compare,
826         .tp_as_sequence = &py_ldb_dn_seq,
827         .tp_doc = "A LDB distinguished name.",
828         .tp_new = py_ldb_dn_new,
829         .tp_dealloc = (destructor)py_ldb_dn_dealloc,
830         .tp_basicsize = sizeof(PyLdbDnObject),
831         .tp_flags = Py_TPFLAGS_DEFAULT,
832 };
833
834 /* Debug */
835 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
836 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
837 {
838         PyObject *fn = (PyObject *)context;
839         PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
840 }
841
842 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
843 {
844         PyObject *cb;
845         struct ldb_context *ldb_ctx;
846
847         if (!PyArg_ParseTuple(args, "O", &cb))
848                 return NULL;
849
850         Py_INCREF(cb);
851         /* FIXME: Where do we DECREF cb ? */
852         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
853         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
854                 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
855                 ldb_ctx);
856
857         Py_RETURN_NONE;
858 }
859
860 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
861 {
862         unsigned int perms;
863         if (!PyArg_ParseTuple(args, "I", &perms))
864                 return NULL;
865
866         ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
867
868         Py_RETURN_NONE;
869 }
870
871 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
872 {
873         char *modules_dir;
874         if (!PyArg_ParseTuple(args, "s", &modules_dir))
875                 return NULL;
876
877         ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
878
879         Py_RETURN_NONE;
880 }
881
882 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
883 {
884         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
885         int ldb_err;
886         ldb_err = ldb_transaction_start(ldb_ctx);
887         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
888         Py_RETURN_NONE;
889 }
890
891 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
892 {
893         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
894         int ldb_err;
895         ldb_err = ldb_transaction_commit(ldb_ctx);
896         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
897         Py_RETURN_NONE;
898 }
899
900 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
901 {
902         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
903         int ldb_err;
904         ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
905         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
906         Py_RETURN_NONE;
907 }
908
909 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
910 {
911         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
912         int ldb_err;
913         ldb_err = ldb_transaction_cancel(ldb_ctx);
914         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
915         Py_RETURN_NONE;
916 }
917
918 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
919 {
920         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
921         int ldb_err;
922         ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
923         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
924         Py_RETURN_NONE;
925 }
926
927 static PyObject *py_ldb_repr(PyLdbObject *self)
928 {
929         return PyString_FromFormat("<ldb connection>");
930 }
931
932 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
933 {
934         struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
935         if (dn == NULL)
936                 Py_RETURN_NONE;
937         return py_ldb_dn_copy(dn);
938 }
939
940
941 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
942 {
943         struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
944         if (dn == NULL)
945                 Py_RETURN_NONE;
946         return py_ldb_dn_copy(dn);
947 }
948
949 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
950 {
951         struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
952         if (dn == NULL)
953                 Py_RETURN_NONE;
954         return py_ldb_dn_copy(dn);
955 }
956
957 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
958 {
959         struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
960         if (dn == NULL)
961                 Py_RETURN_NONE;
962         return py_ldb_dn_copy(dn);
963 }
964
965 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, 
966                                         const char *paramname)
967 {
968         const char **ret;
969         Py_ssize_t i;
970         if (!PyList_Check(list)) {
971                 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
972                 return NULL;
973         }
974         ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
975         if (ret == NULL) {
976                 PyErr_NoMemory();
977                 return NULL;
978         }
979
980         for (i = 0; i < PyList_Size(list); i++) {
981                 PyObject *item = PyList_GetItem(list, i);
982                 if (!PyString_Check(item)) {
983                         PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
984                         return NULL;
985                 }
986                 ret[i] = talloc_strndup(ret, PyString_AsString(item),
987                                         PyString_Size(item));
988         }
989         ret[i] = NULL;
990         return ret;
991 }
992
993 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
994 {
995         const char * const kwnames[] = { "url", "flags", "options", NULL };
996         char *url = NULL;
997         PyObject *py_options = Py_None;
998         const char **options;
999         unsigned int flags = 0;
1000         int ret;
1001         struct ldb_context *ldb;
1002
1003         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1004                                          discard_const_p(char *, kwnames),
1005                                          &url, &flags, &py_options))
1006                 return -1;
1007
1008         ldb = pyldb_Ldb_AsLdbContext(self);
1009
1010         if (py_options == Py_None) {
1011                 options = NULL;
1012         } else {
1013                 options = PyList_AsStringList(ldb, py_options, "options");
1014                 if (options == NULL)
1015                         return -1;
1016         }
1017
1018         if (url != NULL) {
1019                 ret = ldb_connect(ldb, url, flags, options);
1020                 if (ret != LDB_SUCCESS) {
1021                         PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1022                         return -1;
1023                 }
1024         }
1025
1026         talloc_free(options);
1027         return 0;
1028 }
1029
1030 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1031 {
1032         PyLdbObject *ret;
1033         struct ldb_context *ldb;
1034         ret = (PyLdbObject *)type->tp_alloc(type, 0);
1035         if (ret == NULL) {
1036                 PyErr_NoMemory();
1037                 return NULL;
1038         }
1039         ret->mem_ctx = talloc_new(NULL);
1040         ldb = ldb_init(ret->mem_ctx, NULL);
1041
1042         if (ldb == NULL) {
1043                 PyErr_NoMemory();
1044                 return NULL;
1045         }
1046
1047         ret->ldb_ctx = ldb;
1048         return (PyObject *)ret;
1049 }
1050
1051 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1052 {
1053         char *url;
1054         unsigned int flags = 0;
1055         PyObject *py_options = Py_None;
1056         int ret;
1057         const char **options;
1058         const char * const kwnames[] = { "url", "flags", "options", NULL };
1059         struct ldb_context *ldb_ctx;
1060
1061         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
1062                                          discard_const_p(char *, kwnames),
1063                                          &url, &flags, &py_options))
1064                 return NULL;
1065
1066         if (py_options == Py_None) {
1067                 options = NULL;
1068         } else {
1069                 options = PyList_AsStringList(NULL, py_options, "options");
1070                 if (options == NULL)
1071                         return NULL;
1072         }
1073
1074         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1075         ret = ldb_connect(ldb_ctx, url, flags, options);
1076         talloc_free(options);
1077
1078         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1079
1080         Py_RETURN_NONE;
1081 }
1082
1083 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1084 {
1085         PyObject *py_msg;
1086         PyObject *py_controls = Py_None;
1087         struct ldb_context *ldb_ctx;
1088         struct ldb_request *req;
1089         struct ldb_control **parsed_controls;
1090         struct ldb_message *msg;
1091         int ret;
1092         TALLOC_CTX *mem_ctx;
1093         bool validate=true;
1094         const char * const kwnames[] = { "message", "controls", "validate", NULL };
1095
1096         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1097                                          discard_const_p(char *, kwnames),
1098                                          &py_msg, &py_controls, &validate))
1099                 return NULL;
1100
1101         mem_ctx = talloc_new(NULL);
1102         if (mem_ctx == NULL) {
1103                 PyErr_NoMemory();
1104                 return NULL;
1105         }
1106         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1107
1108         if (py_controls == Py_None) {
1109                 parsed_controls = NULL;
1110         } else {
1111                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1112                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1113                 talloc_free(controls);
1114         }
1115
1116         if (!PyLdbMessage_Check(py_msg)) {
1117                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1118                 talloc_free(mem_ctx);
1119                 return NULL;
1120         }
1121         msg = pyldb_Message_AsMessage(py_msg);
1122
1123         if (validate) {
1124                 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1125                 if (ret != LDB_SUCCESS) {
1126                         PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1127                         talloc_free(mem_ctx);
1128                         return NULL;
1129                 }
1130         }
1131
1132         ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1133                                 NULL, ldb_op_default_callback, NULL);
1134         if (ret != LDB_SUCCESS) {
1135                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1136                 talloc_free(mem_ctx);
1137                 return NULL;
1138         }
1139
1140         /* do request and autostart a transaction */
1141         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1142
1143         ret = ldb_transaction_start(ldb_ctx);
1144         if (ret != LDB_SUCCESS) {
1145                 talloc_free(mem_ctx);
1146                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1147                 return NULL;
1148         }
1149
1150         ret = ldb_request(ldb_ctx, req);
1151         if (ret == LDB_SUCCESS) {
1152                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1153         }
1154
1155         if (ret == LDB_SUCCESS) {
1156                 ret = ldb_transaction_commit(ldb_ctx);
1157         } else {
1158                 ldb_transaction_cancel(ldb_ctx);
1159         }
1160
1161         talloc_free(mem_ctx);
1162         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1163
1164         Py_RETURN_NONE;
1165 }
1166
1167
1168 /**
1169  * Obtain a ldb message from a Python Dictionary object.
1170  *
1171  * @param mem_ctx Memory context
1172  * @param py_obj Python Dictionary object
1173  * @param ldb_ctx LDB context
1174  * @param mod_flags Flags to be set on every message element
1175  * @return ldb_message on success or NULL on failure
1176  */
1177 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1178                                             PyObject *py_obj,
1179                                             struct ldb_context *ldb_ctx,
1180                                             unsigned int mod_flags)
1181 {
1182         struct ldb_message *msg;
1183         unsigned int msg_pos = 0;
1184         Py_ssize_t dict_pos = 0;
1185         PyObject *key, *value;
1186         struct ldb_message_element *msg_el;
1187         PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1188
1189         msg = ldb_msg_new(mem_ctx);
1190         if (msg == NULL) {
1191                 PyErr_NoMemory();
1192                 return NULL;
1193         }
1194         msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1195
1196         if (dn_value) {
1197                 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1198                         PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1199                         return NULL;
1200                 }
1201                 if (msg->dn == NULL) {
1202                         PyErr_SetString(PyExc_TypeError, "dn set but not found");
1203                         return NULL;
1204                 }
1205         } else {
1206                 PyErr_SetString(PyExc_TypeError, "no dn set");
1207                 return NULL;
1208         }
1209
1210         while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1211                 char *key_str = PyString_AsString(key);
1212                 if (ldb_attr_cmp(key_str, "dn") != 0) {
1213                         msg_el = PyObject_AsMessageElement(msg->elements, value,
1214                                                            mod_flags, key_str);
1215                         if (msg_el == NULL) {
1216                                 PyErr_SetString(PyExc_TypeError, "unable to import element");
1217                                 return NULL;
1218                         }
1219                         memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1220                         msg_pos++;
1221                 }
1222         }
1223
1224         msg->num_elements = msg_pos;
1225
1226         return msg;
1227 }
1228
1229 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1230 {
1231         PyObject *py_obj;
1232         int ret;
1233         struct ldb_context *ldb_ctx;
1234         struct ldb_request *req;
1235         struct ldb_message *msg = NULL;
1236         PyObject *py_controls = Py_None;
1237         TALLOC_CTX *mem_ctx;
1238         struct ldb_control **parsed_controls;
1239         const char * const kwnames[] = { "message", "controls", NULL };
1240
1241         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1242                                          discard_const_p(char *, kwnames),
1243                                          &py_obj, &py_controls))
1244                 return NULL;
1245
1246         mem_ctx = talloc_new(NULL);
1247         if (mem_ctx == NULL) {
1248                 PyErr_NoMemory();
1249                 return NULL;
1250         }
1251         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1252
1253         if (py_controls == Py_None) {
1254                 parsed_controls = NULL;
1255         } else {
1256                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1257                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1258                 talloc_free(controls);
1259         }
1260
1261         if (PyLdbMessage_Check(py_obj)) {
1262                 msg = pyldb_Message_AsMessage(py_obj);
1263         } else if (PyDict_Check(py_obj)) {
1264                 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1265         } else {
1266                 PyErr_SetString(PyExc_TypeError,
1267                                 "Dictionary or LdbMessage object expected!");
1268         }
1269
1270         if (!msg) {
1271                 /* we should have a PyErr already set */
1272                 talloc_free(mem_ctx);
1273                 return NULL;
1274         }
1275
1276         ret = ldb_msg_sanity_check(ldb_ctx, msg);
1277         if (ret != LDB_SUCCESS) {
1278                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1279                 talloc_free(mem_ctx);
1280                 return NULL;
1281         }
1282
1283         ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1284                                 NULL, ldb_op_default_callback, NULL);
1285         if (ret != LDB_SUCCESS) {
1286                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1287                 talloc_free(mem_ctx);
1288                 return NULL;
1289         }
1290
1291         /* do request and autostart a transaction */
1292         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1293
1294         ret = ldb_transaction_start(ldb_ctx);
1295         if (ret != LDB_SUCCESS) {
1296                 talloc_free(mem_ctx);
1297                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1298                 return NULL;
1299         }
1300
1301         ret = ldb_request(ldb_ctx, req);
1302         if (ret == LDB_SUCCESS) {
1303                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1304         }
1305
1306         if (ret == LDB_SUCCESS) {
1307                 ret = ldb_transaction_commit(ldb_ctx);
1308         } else {
1309                 ldb_transaction_cancel(ldb_ctx);
1310         }
1311
1312         talloc_free(mem_ctx);
1313         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1314
1315         Py_RETURN_NONE;
1316 }
1317
1318 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1319 {
1320         PyObject *py_dn;
1321         struct ldb_dn *dn;
1322         int ret;
1323         struct ldb_context *ldb_ctx;
1324         struct ldb_request *req;
1325         PyObject *py_controls = Py_None;
1326         TALLOC_CTX *mem_ctx;
1327         struct ldb_control **parsed_controls;
1328         const char * const kwnames[] = { "dn", "controls", NULL };
1329
1330         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1331                                          discard_const_p(char *, kwnames),
1332                                          &py_dn, &py_controls))
1333                 return NULL;
1334
1335         mem_ctx = talloc_new(NULL);
1336         if (mem_ctx == NULL) {
1337                 PyErr_NoMemory();
1338                 return NULL;
1339         }
1340         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1341
1342         if (py_controls == Py_None) {
1343                 parsed_controls = NULL;
1344         } else {
1345                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1346                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1347                 talloc_free(controls);
1348         }
1349
1350         if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1351                 talloc_free(mem_ctx);
1352                 return NULL;
1353         }
1354
1355         ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1356                                 NULL, ldb_op_default_callback, NULL);
1357         if (ret != LDB_SUCCESS) {
1358                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1359                 talloc_free(mem_ctx);
1360                 return NULL;
1361         }
1362
1363         /* do request and autostart a transaction */
1364         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1365
1366         ret = ldb_transaction_start(ldb_ctx);
1367         if (ret != LDB_SUCCESS) {
1368                 talloc_free(mem_ctx);
1369                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1370                 return NULL;
1371         }
1372
1373         ret = ldb_request(ldb_ctx, req);
1374         if (ret == LDB_SUCCESS) {
1375                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1376         }
1377
1378         if (ret == LDB_SUCCESS) {
1379                 ret = ldb_transaction_commit(ldb_ctx);
1380         } else {
1381                 ldb_transaction_cancel(ldb_ctx);
1382         }
1383
1384         talloc_free(mem_ctx);
1385         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1386
1387         Py_RETURN_NONE;
1388 }
1389
1390 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1391 {
1392         PyObject *py_dn1, *py_dn2;
1393         struct ldb_dn *dn1, *dn2;
1394         int ret;
1395         TALLOC_CTX *mem_ctx;
1396         PyObject *py_controls = Py_None;
1397         struct ldb_control **parsed_controls;
1398         struct ldb_context *ldb_ctx;
1399         struct ldb_request *req;
1400         const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1401
1402         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1403
1404         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1405                                          discard_const_p(char *, kwnames),
1406                                          &py_dn1, &py_dn2, &py_controls))
1407                 return NULL;
1408
1409
1410         mem_ctx = talloc_new(NULL);
1411         if (mem_ctx == NULL) {
1412                 PyErr_NoMemory();
1413                 return NULL;
1414         }
1415
1416         if (py_controls == Py_None) {
1417                 parsed_controls = NULL;
1418         } else {
1419                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1420                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1421                 talloc_free(controls);
1422         }
1423
1424
1425         if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1426                 talloc_free(mem_ctx);
1427                 return NULL;
1428         }
1429
1430         if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1431                 talloc_free(mem_ctx);
1432                 return NULL;
1433         }
1434
1435         ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1436                                 NULL, ldb_op_default_callback, NULL);
1437         if (ret != LDB_SUCCESS) {
1438                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1439                 talloc_free(mem_ctx);
1440                 return NULL;
1441         }
1442
1443         /* do request and autostart a transaction */
1444         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1445
1446         ret = ldb_transaction_start(ldb_ctx);
1447         if (ret != LDB_SUCCESS) {
1448                 talloc_free(mem_ctx);
1449                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1450                 return NULL;
1451         }
1452
1453         ret = ldb_request(ldb_ctx, req);
1454         if (ret == LDB_SUCCESS) {
1455                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1456         }
1457
1458         if (ret == LDB_SUCCESS) {
1459                 ret = ldb_transaction_commit(ldb_ctx);
1460         } else {
1461                 ldb_transaction_cancel(ldb_ctx);
1462         }
1463
1464         talloc_free(mem_ctx);
1465         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1466
1467         Py_RETURN_NONE;
1468 }
1469
1470 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1471 {
1472         char *name;
1473         if (!PyArg_ParseTuple(args, "s", &name))
1474                 return NULL;
1475
1476         ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1477
1478         Py_RETURN_NONE;
1479 }
1480
1481 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1482 {
1483         char *attribute, *syntax;
1484         unsigned int flags;
1485         int ret;
1486         struct ldb_context *ldb_ctx;
1487
1488         if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1489                 return NULL;
1490
1491         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1492         ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1493
1494         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1495
1496         Py_RETURN_NONE;
1497 }
1498
1499 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1500 {
1501         if (ldif == NULL) {
1502                 Py_RETURN_NONE;
1503         } else {
1504         /* We don't want this attached to the 'ldb' any more */
1505                 return Py_BuildValue(discard_const_p(char, "(iO)"),
1506                                      ldif->changetype,
1507                                      PyLdbMessage_FromMessage(ldif->msg));
1508         }
1509 }
1510
1511
1512 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1513 {
1514         int changetype;
1515         PyObject *py_msg;
1516         struct ldb_ldif ldif;
1517         PyObject *ret;
1518         char *string;
1519         TALLOC_CTX *mem_ctx;
1520
1521         if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1522                 return NULL;
1523
1524         if (!PyLdbMessage_Check(py_msg)) {
1525                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1526                 return NULL;
1527         }
1528
1529         ldif.msg = pyldb_Message_AsMessage(py_msg);
1530         ldif.changetype = changetype;
1531
1532         mem_ctx = talloc_new(NULL);
1533
1534         string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1535         if (!string) {
1536                 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1537                 return NULL;
1538         }
1539
1540         ret = PyString_FromString(string);
1541
1542         talloc_free(mem_ctx);
1543
1544         return ret;
1545 }
1546
1547 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1548 {
1549         PyObject *list;
1550         struct ldb_ldif *ldif;
1551         const char *s;
1552
1553         TALLOC_CTX *mem_ctx;
1554
1555         if (!PyArg_ParseTuple(args, "s", &s))
1556                 return NULL;
1557
1558         mem_ctx = talloc_new(NULL);
1559         if (!mem_ctx) {
1560                 Py_RETURN_NONE;
1561         }
1562
1563         list = PyList_New(0);
1564         while (s && *s != '\0') {
1565                 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1566                 talloc_steal(mem_ctx, ldif);
1567                 if (ldif) {
1568                         PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1569                 } else {
1570                         PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1571                         talloc_free(mem_ctx);
1572                         return NULL;
1573                 }
1574         }
1575         talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1576         return PyObject_GetIter(list);
1577 }
1578
1579 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1580 {
1581         int ldb_ret;
1582         PyObject *py_msg_old;
1583         PyObject *py_msg_new;
1584         struct ldb_message *diff;
1585         struct ldb_context *ldb;
1586         PyObject *py_ret;
1587
1588         if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1589                 return NULL;
1590
1591         if (!PyLdbMessage_Check(py_msg_old)) {
1592                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1593                 return NULL;
1594         }
1595
1596         if (!PyLdbMessage_Check(py_msg_new)) {
1597                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1598                 return NULL;
1599         }
1600
1601         ldb = pyldb_Ldb_AsLdbContext(self);
1602         ldb_ret = ldb_msg_difference(ldb, ldb,
1603                                      pyldb_Message_AsMessage(py_msg_old),
1604                                      pyldb_Message_AsMessage(py_msg_new),
1605                                      &diff);
1606         if (ldb_ret != LDB_SUCCESS) {
1607                 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1608                 return NULL;
1609         }
1610
1611         py_ret = PyLdbMessage_FromMessage(diff);
1612
1613         talloc_unlink(ldb, diff);
1614
1615         return py_ret;
1616 }
1617
1618 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1619 {
1620         const struct ldb_schema_attribute *a;
1621         struct ldb_val old_val;
1622         struct ldb_val new_val;
1623         TALLOC_CTX *mem_ctx;
1624         PyObject *ret;
1625         char *element_name;
1626         PyObject *val;
1627
1628         if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1629                 return NULL;
1630
1631         old_val.data = (uint8_t *)PyString_AsString(val);
1632         old_val.length = PyString_Size(val);
1633
1634         if (old_val.data == NULL) {
1635                 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1636                 return NULL;
1637         }
1638
1639         a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1640
1641         if (a == NULL) {
1642                 Py_RETURN_NONE;
1643         }
1644
1645         mem_ctx = talloc_new(NULL);
1646         if (mem_ctx == NULL) {
1647                 PyErr_NoMemory();
1648                 return NULL;
1649         }
1650
1651         if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1652                 talloc_free(mem_ctx);
1653                 Py_RETURN_NONE;
1654         }
1655
1656         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1657
1658         talloc_free(mem_ctx);
1659
1660         return ret;
1661 }
1662
1663 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1664 {
1665         PyObject *py_base = Py_None;
1666         int scope = LDB_SCOPE_DEFAULT;
1667         char *expr = NULL;
1668         PyObject *py_attrs = Py_None;
1669         PyObject *py_controls = Py_None;
1670         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1671         int ret;
1672         struct ldb_result *res;
1673         struct ldb_request *req;
1674         const char **attrs;
1675         struct ldb_context *ldb_ctx;
1676         struct ldb_control **parsed_controls;
1677         struct ldb_dn *base;
1678         PyObject *py_ret;
1679         TALLOC_CTX *mem_ctx;
1680
1681         /* type "int" rather than "enum" for "scope" is intentional */
1682         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1683                                          discard_const_p(char *, kwnames),
1684                                          &py_base, &scope, &expr, &py_attrs, &py_controls))
1685                 return NULL;
1686
1687
1688         mem_ctx = talloc_new(NULL);
1689         if (mem_ctx == NULL) {
1690                 PyErr_NoMemory();
1691                 return NULL;
1692         }
1693         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1694
1695         if (py_attrs == Py_None) {
1696                 attrs = NULL;
1697         } else {
1698                 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1699                 if (attrs == NULL) {
1700                         talloc_free(mem_ctx);
1701                         return NULL;
1702                 }
1703         }
1704
1705         if (py_base == Py_None) {
1706                 base = ldb_get_default_basedn(ldb_ctx);
1707         } else {
1708                 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1709                         talloc_free(attrs);
1710                         return NULL;
1711                 }
1712         }
1713
1714         if (py_controls == Py_None) {
1715                 parsed_controls = NULL;
1716         } else {
1717                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1718                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1719                 talloc_free(controls);
1720         }
1721
1722         res = talloc_zero(mem_ctx, struct ldb_result);
1723         if (res == NULL) {
1724                 PyErr_NoMemory();
1725                 talloc_free(mem_ctx);
1726                 return NULL;
1727         }
1728
1729         ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1730                                    base,
1731                                    scope,
1732                                    expr,
1733                                    attrs,
1734                                    parsed_controls,
1735                                    res,
1736                                    ldb_search_default_callback,
1737                                    NULL);
1738
1739         if (ret != LDB_SUCCESS) {
1740                 talloc_free(mem_ctx);
1741                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1742                 return NULL;
1743         }
1744
1745         talloc_steal(req, attrs);
1746
1747         ret = ldb_request(ldb_ctx, req);
1748
1749         if (ret == LDB_SUCCESS) {
1750                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1751         }
1752
1753         if (ret != LDB_SUCCESS) {
1754                 talloc_free(mem_ctx);
1755                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1756                 return NULL;
1757         }
1758
1759         py_ret = PyLdbResult_FromResult(res);
1760
1761         talloc_free(mem_ctx);
1762
1763         return py_ret;
1764 }
1765
1766 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1767 {
1768         char *name;
1769         void *data;
1770
1771         if (!PyArg_ParseTuple(args, "s", &name))
1772                 return NULL;
1773
1774         data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1775
1776         if (data == NULL)
1777                 Py_RETURN_NONE;
1778
1779         /* FIXME: More interpretation */
1780
1781         return Py_True;
1782 }
1783
1784 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1785 {
1786         char *name;
1787         PyObject *data;
1788
1789         if (!PyArg_ParseTuple(args, "sO", &name, &data))
1790                 return NULL;
1791
1792         /* FIXME: More interpretation */
1793
1794         ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1795
1796         Py_RETURN_NONE;
1797 }
1798
1799 static PyObject *py_ldb_modules(PyLdbObject *self)
1800 {
1801         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1802         PyObject *ret = PyList_New(0);
1803         struct ldb_module *mod;
1804
1805         for (mod = ldb->modules; mod; mod = mod->next) {
1806                 PyList_Append(ret, PyLdbModule_FromModule(mod));
1807         }
1808
1809         return ret;
1810 }
1811
1812 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1813 {
1814         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1815         int type, ret;
1816         uint64_t value;
1817
1818         if (!PyArg_ParseTuple(args, "i", &type))
1819                 return NULL;
1820
1821         /* FIXME: More interpretation */
1822
1823         ret = ldb_sequence_number(ldb, type, &value);
1824
1825         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1826
1827         return PyLong_FromLongLong(value);
1828 }
1829 static PyMethodDef py_ldb_methods[] = {
1830         { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, 
1831                 "S.set_debug(callback) -> None\n"
1832                 "Set callback for LDB debug messages.\n"
1833                 "The callback should accept a debug level and debug text." },
1834         { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, 
1835                 "S.set_create_perms(mode) -> None\n"
1836                 "Set mode to use when creating new LDB files." },
1837         { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1838                 "S.set_modules_dir(path) -> None\n"
1839                 "Set path LDB should search for modules" },
1840         { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, 
1841                 "S.transaction_start() -> None\n"
1842                 "Start a new transaction." },
1843         { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1844                 "S.transaction_prepare_commit() -> None\n"
1845                 "prepare to commit a new transaction (2-stage commit)." },
1846         { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, 
1847                 "S.transaction_commit() -> None\n"
1848                 "commit a new transaction." },
1849         { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, 
1850                 "S.transaction_cancel() -> None\n"
1851                 "cancel a new transaction." },
1852         { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, 
1853                 NULL },
1854         { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1855                 NULL },
1856         { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1857                 NULL },
1858         { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1859                 NULL },
1860         { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1861                 NULL },
1862         { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, 
1863                 "S.connect(url, flags=0, options=None) -> None\n"
1864                 "Connect to a LDB URL." },
1865         { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1866                 "S.modify(message, controls=None, validate=False) -> None\n"
1867                 "Modify an entry." },
1868         { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1869                 "S.add(message, controls=None) -> None\n"
1870                 "Add an entry." },
1871         { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1872                 "S.delete(dn, controls=None) -> None\n"
1873                 "Remove an entry." },
1874         { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1875                 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1876                 "Rename an entry." },
1877         { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1878                 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1879                 "Search in a database.\n"
1880                 "\n"
1881                 ":param base: Optional base DN to search\n"
1882                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1883                 ":param expression: Optional search expression\n"
1884                 ":param attrs: Attributes to return (defaults to all)\n"
1885                 ":param controls: Optional list of controls\n"
1886                 ":return: Iterator over Message objects\n"
1887         },
1888         { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1889                 NULL },
1890         { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1891                 NULL },
1892         { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1893                 NULL },
1894         { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1895                 "S.parse_ldif(ldif) -> iter(messages)\n"
1896                 "Parse a string formatted using LDIF." },
1897         { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1898                 "S.write_ldif(message, changetype) -> ldif\n"
1899                 "Print the message as a string formatted using LDIF." },
1900         { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1901                 "S.msg_diff(Message) -> Message\n"
1902                 "Return an LDB Message of the difference between two Message objects." },
1903         { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1904                 "S.get_opaque(name) -> value\n"
1905                 "Get an opaque value set on this LDB connection. \n"
1906                 ":note: The returned value may not be useful in Python."
1907         },
1908         { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1909                 "S.set_opaque(name, value) -> None\n"
1910                 "Set an opaque value on this LDB connection. \n"
1911                 ":note: Passing incorrect values may cause crashes." },
1912         { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1913                 "S.modules() -> list\n"
1914                 "Return the list of modules on this LDB connection " },
1915         { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1916                 "S.sequence_number(type) -> value\n"
1917                 "Return the value of the sequence according to the requested type" },
1918         { NULL },
1919 };
1920
1921 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1922 {
1923         PyLdbModuleObject *ret;
1924
1925         ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1926         if (ret == NULL) {
1927                 PyErr_NoMemory();
1928                 return NULL;
1929         }
1930         ret->mem_ctx = talloc_new(NULL);
1931         ret->mod = talloc_reference(ret->mem_ctx, mod);
1932         return (PyObject *)ret;
1933 }
1934
1935 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1936 {
1937         return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1938 }
1939
1940 static PyGetSetDef py_ldb_getset[] = {
1941         { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1942         { NULL }
1943 };
1944
1945 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1946 {
1947         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1948         struct ldb_dn *dn;
1949         struct ldb_result *result;
1950         unsigned int count;
1951         int ret;
1952
1953         if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1954                 return -1;
1955         }
1956
1957         ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1958                          NULL);
1959         if (ret != LDB_SUCCESS) {
1960                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1961                 return -1;
1962         }
1963
1964         count = result->count;
1965
1966         talloc_free(result);
1967
1968         if (count > 1) {
1969                 PyErr_Format(PyExc_RuntimeError,
1970                              "Searching for [%s] dn gave %u results!",
1971                              ldb_dn_get_linearized(dn),
1972                              count);
1973                 return -1;
1974         }
1975
1976         return count;
1977 }
1978
1979 static PySequenceMethods py_ldb_seq = {
1980         .sq_contains = (objobjproc)py_ldb_contains,
1981 };
1982
1983 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1984 {
1985         PyLdbObject *ret;
1986
1987         ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1988         if (ret == NULL) {
1989                 PyErr_NoMemory();
1990                 return NULL;
1991         }
1992         ret->mem_ctx = talloc_new(NULL);
1993         ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1994         return (PyObject *)ret;
1995 }
1996
1997 static void py_ldb_dealloc(PyLdbObject *self)
1998 {
1999         talloc_free(self->mem_ctx);
2000         Py_TYPE(self)->tp_free(self);
2001 }
2002
2003 static PyTypeObject PyLdb = {
2004         .tp_name = "ldb.Ldb",
2005         .tp_methods = py_ldb_methods,
2006         .tp_repr = (reprfunc)py_ldb_repr,
2007         .tp_new = py_ldb_new,
2008         .tp_init = (initproc)py_ldb_init,
2009         .tp_dealloc = (destructor)py_ldb_dealloc,
2010         .tp_getset = py_ldb_getset,
2011         .tp_getattro = PyObject_GenericGetAttr,
2012         .tp_basicsize = sizeof(PyLdbObject),
2013         .tp_doc = "Connection to a LDB database.",
2014         .tp_as_sequence = &py_ldb_seq,
2015         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2016 };
2017
2018 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2019 {
2020         talloc_free(self->mem_ctx);
2021         Py_DECREF(self->msgs);
2022         Py_DECREF(self->referals);
2023         Py_DECREF(self->controls);
2024         Py_TYPE(self)->tp_free(self);
2025 }
2026
2027 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2028 {
2029         Py_INCREF(self->msgs);
2030         return self->msgs;
2031 }
2032
2033 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2034 {
2035         Py_INCREF(self->controls);
2036         return self->controls;
2037 }
2038
2039 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2040 {
2041         Py_INCREF(self->referals);
2042         return self->referals;
2043 }
2044
2045 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2046 {
2047         Py_ssize_t size;
2048         if (self->msgs == NULL) {
2049                 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2050                 return NULL;
2051         }
2052         size = PyList_Size(self->msgs);
2053         return PyInt_FromLong(size);
2054 }
2055
2056 static PyGetSetDef py_ldb_result_getset[] = {
2057         { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2058         { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2059         { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2060         { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2061         { NULL }
2062 };
2063
2064 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2065 {
2066         return PyObject_GetIter(self->msgs);
2067 }
2068
2069 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2070 {
2071         return PySequence_Size(self->msgs);
2072 }
2073
2074 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2075 {
2076         return PySequence_GetItem(self->msgs, idx);
2077 }
2078
2079 static PySequenceMethods py_ldb_result_seq = {
2080         .sq_length = (lenfunc)py_ldb_result_len,
2081         .sq_item = (ssizeargfunc)py_ldb_result_find,
2082 };
2083
2084 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2085 {
2086         return PyString_FromFormat("<ldb result>");
2087 }
2088
2089
2090 static PyTypeObject PyLdbResult = {
2091         .tp_name = "ldb.Result",
2092         .tp_repr = (reprfunc)py_ldb_result_repr,
2093         .tp_dealloc = (destructor)py_ldb_result_dealloc,
2094         .tp_iter = (getiterfunc)py_ldb_result_iter,
2095         .tp_getset = py_ldb_result_getset,
2096         .tp_getattro = PyObject_GenericGetAttr,
2097         .tp_basicsize = sizeof(PyLdbResultObject),
2098         .tp_as_sequence = &py_ldb_result_seq,
2099         .tp_doc = "LDB result.",
2100         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2101 };
2102
2103 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2104 {
2105         return PyString_FromFormat("<ldb module '%s'>",
2106                 pyldb_Module_AsModule(self)->ops->name);
2107 }
2108
2109 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2110 {
2111         return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
2112 }
2113
2114 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2115 {
2116         pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2117         Py_RETURN_NONE;
2118 }
2119
2120 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2121 {
2122         pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2123         Py_RETURN_NONE;
2124 }
2125
2126 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2127 {
2128         pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2129         Py_RETURN_NONE;
2130 }
2131
2132 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2133 {
2134         PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2135         int ret, scope;
2136         struct ldb_request *req;
2137         const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2138         struct ldb_module *mod;
2139         const char * const*attrs;
2140
2141         /* type "int" rather than "enum" for "scope" is intentional */
2142         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
2143                                          discard_const_p(char *, kwnames),
2144                                          &py_base, &scope, &py_tree, &py_attrs))
2145                 return NULL;
2146
2147         mod = self->mod;
2148
2149         if (py_attrs == Py_None) {
2150                 attrs = NULL;
2151         } else {
2152                 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
2153                 if (attrs == NULL)
2154                         return NULL;
2155         }
2156
2157         ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base), 
2158                              scope, NULL /* expr */, attrs,
2159                              NULL /* controls */, NULL, NULL, NULL);
2160
2161         talloc_steal(req, attrs);
2162
2163         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2164
2165         req->op.search.res = NULL;
2166
2167         ret = mod->ops->search(mod, req);
2168
2169         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2170
2171         py_ret = PyLdbResult_FromResult(req->op.search.res);
2172
2173         talloc_free(req);
2174
2175         return py_ret;
2176 }
2177
2178
2179 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2180 {
2181         struct ldb_request *req;
2182         PyObject *py_message;
2183         int ret;
2184         struct ldb_module *mod;
2185
2186         if (!PyArg_ParseTuple(args, "O", &py_message))
2187                 return NULL;
2188
2189         req = talloc_zero(NULL, struct ldb_request);
2190         req->operation = LDB_ADD;
2191         req->op.add.message = pyldb_Message_AsMessage(py_message);
2192
2193         mod = pyldb_Module_AsModule(self);
2194         ret = mod->ops->add(mod, req);
2195
2196         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2197
2198         Py_RETURN_NONE;
2199 }
2200
2201 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) 
2202 {
2203         int ret;
2204         struct ldb_request *req;
2205         PyObject *py_message;
2206         struct ldb_module *mod;
2207
2208         if (!PyArg_ParseTuple(args, "O", &py_message))
2209                 return NULL;
2210
2211         req = talloc_zero(NULL, struct ldb_request);
2212         req->operation = LDB_MODIFY;
2213         req->op.mod.message = pyldb_Message_AsMessage(py_message);
2214
2215         mod = pyldb_Module_AsModule(self);
2216         ret = mod->ops->modify(mod, req);
2217
2218         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2219
2220         Py_RETURN_NONE;
2221 }
2222
2223 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) 
2224 {
2225         int ret;
2226         struct ldb_request *req;
2227         PyObject *py_dn;
2228
2229         if (!PyArg_ParseTuple(args, "O", &py_dn))
2230                 return NULL;
2231
2232         req = talloc_zero(NULL, struct ldb_request);
2233         req->operation = LDB_DELETE;
2234         req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2235
2236         ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2237
2238         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2239
2240         Py_RETURN_NONE;
2241 }
2242
2243 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2244 {
2245         int ret;
2246         struct ldb_request *req;
2247         PyObject *py_dn1, *py_dn2;
2248
2249         if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
2250                 return NULL;
2251
2252         req = talloc_zero(NULL, struct ldb_request);
2253
2254         req->operation = LDB_RENAME;
2255         req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2256         req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2257
2258         ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2259
2260         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2261
2262         Py_RETURN_NONE;
2263 }
2264
2265 static PyMethodDef py_ldb_module_methods[] = {
2266         { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2267         { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2268         { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2269         { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2270         { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2271         { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2272         { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2273         { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2274         { NULL },
2275 };
2276
2277 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2278 {
2279         talloc_free(self->mem_ctx);
2280         PyObject_Del(self);
2281 }
2282
2283 static PyTypeObject PyLdbModule = {
2284         .tp_name = "ldb.LdbModule",
2285         .tp_methods = py_ldb_module_methods,
2286         .tp_repr = (reprfunc)py_ldb_module_repr,
2287         .tp_str = (reprfunc)py_ldb_module_str,
2288         .tp_basicsize = sizeof(PyLdbModuleObject),
2289         .tp_dealloc = (destructor)py_ldb_module_dealloc,
2290         .tp_flags = Py_TPFLAGS_DEFAULT,
2291         .tp_doc = "LDB module (extension)",
2292 };
2293
2294
2295 /**
2296  * Create a ldb_message_element from a Python object.
2297  *
2298  * This will accept any sequence objects that contains strings, or 
2299  * a string object.
2300  *
2301  * A reference to set_obj will be borrowed. 
2302  *
2303  * @param mem_ctx Memory context
2304  * @param set_obj Python object to convert
2305  * @param flags ldb_message_element flags to set
2306  * @param attr_name Name of the attribute
2307  * @return New ldb_message_element, allocated as child of mem_ctx
2308  */
2309 static struct ldb_message_element *PyObject_AsMessageElement(
2310                                                       TALLOC_CTX *mem_ctx,
2311                                                       PyObject *set_obj,
2312                                                       unsigned int flags,
2313                                                       const char *attr_name)
2314 {
2315         struct ldb_message_element *me;
2316
2317         if (pyldb_MessageElement_Check(set_obj)) {
2318                 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2319                 /* We have to talloc_reference() the memory context, not the pointer
2320                  * which may not actually be it's own context */
2321                 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2322                         return pyldb_MessageElement_AsMessageElement(set_obj);
2323                 }
2324                 return NULL;
2325         }
2326
2327         me = talloc(mem_ctx, struct ldb_message_element);
2328         if (me == NULL) {
2329                 PyErr_NoMemory();
2330                 return NULL;
2331         }
2332
2333         me->name = talloc_strdup(me, attr_name);
2334         me->flags = flags;
2335         if (PyString_Check(set_obj)) {
2336                 me->num_values = 1;
2337                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2338                 me->values[0].length = PyString_Size(set_obj);
2339                 me->values[0].data = talloc_memdup(me, 
2340                         (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2341         } else if (PySequence_Check(set_obj)) {
2342                 Py_ssize_t i;
2343                 me->num_values = PySequence_Size(set_obj);
2344                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2345                 for (i = 0; i < me->num_values; i++) {
2346                         PyObject *obj = PySequence_GetItem(set_obj, i);
2347                         if (!PyString_Check(obj)) {
2348                                 PyErr_Format(PyExc_TypeError,
2349                                              "Expected string as element %zd in list", i);
2350                                 talloc_free(me);
2351                                 return NULL;
2352                         }
2353
2354                         me->values[i].length = PyString_Size(obj);
2355                         me->values[i].data = talloc_memdup(me, 
2356                                 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2357                 }
2358         } else {
2359                 PyErr_Format(PyExc_TypeError,
2360                              "String or List type expected for '%s' attribute", attr_name);
2361                 talloc_free(me);
2362                 me = NULL;
2363         }
2364
2365         return me;
2366 }
2367
2368
2369 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2370                                         struct ldb_message_element *me)
2371 {
2372         Py_ssize_t i;
2373         PyObject *result;
2374
2375         /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2376         result = PyList_New(me->num_values);
2377
2378         for (i = 0; i < me->num_values; i++) {
2379                 PyList_SetItem(result, i,
2380                         PyObject_FromLdbValue(&me->values[i]));
2381         }
2382
2383         return result;
2384 }
2385
2386 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2387 {
2388         unsigned int i;
2389         if (!PyArg_ParseTuple(args, "I", &i))
2390                 return NULL;
2391         if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2392                 Py_RETURN_NONE;
2393
2394         return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2395 }
2396
2397 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2398 {
2399         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2400         return PyInt_FromLong(el->flags);
2401 }
2402
2403 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2404 {
2405         unsigned int flags;
2406         struct ldb_message_element *el;
2407         if (!PyArg_ParseTuple(args, "I", &flags))
2408                 return NULL;
2409
2410         el = pyldb_MessageElement_AsMessageElement(self);
2411         el->flags = flags;
2412         Py_RETURN_NONE;
2413 }
2414
2415 static PyMethodDef py_ldb_msg_element_methods[] = {
2416         { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2417         { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2418         { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2419         { NULL },
2420 };
2421
2422 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2423 {
2424         return pyldb_MessageElement_AsMessageElement(self)->num_values;
2425 }
2426
2427 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2428 {
2429         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2430         if (idx < 0 || idx >= el->num_values) {
2431                 PyErr_SetString(PyExc_IndexError, "Out of range");
2432                 return NULL;
2433         }
2434         return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2435 }
2436
2437 static PySequenceMethods py_ldb_msg_element_seq = {
2438         .sq_length = (lenfunc)py_ldb_msg_element_len,
2439         .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2440 };
2441
2442 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2443 {
2444         int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2445                                                                           pyldb_MessageElement_AsMessageElement(other));
2446         return SIGN(ret);
2447 }
2448
2449 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2450 {
2451         PyObject *el = ldb_msg_element_to_set(NULL,
2452                                               pyldb_MessageElement_AsMessageElement(self));
2453         return PyObject_GetIter(el);
2454 }
2455
2456 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2457 {
2458         PyLdbMessageElementObject *ret;
2459         ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2460         if (ret == NULL) {
2461                 PyErr_NoMemory();
2462                 return NULL;
2463         }
2464         ret->mem_ctx = talloc_new(NULL);
2465         if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2466                 PyErr_NoMemory();
2467                 return NULL;
2468         }
2469         ret->el = el;
2470         return (PyObject *)ret;
2471 }
2472
2473 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2474 {
2475         PyObject *py_elements = NULL;
2476         struct ldb_message_element *el;
2477         unsigned int flags = 0;
2478         char *name = NULL;
2479         const char * const kwnames[] = { "elements", "flags", "name", NULL };
2480         PyLdbMessageElementObject *ret;
2481         TALLOC_CTX *mem_ctx;
2482
2483         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2484                                          discard_const_p(char *, kwnames),
2485                                          &py_elements, &flags, &name))
2486                 return NULL;
2487
2488         mem_ctx = talloc_new(NULL);
2489         if (mem_ctx == NULL) {
2490                 PyErr_NoMemory();
2491                 return NULL;
2492         }
2493
2494         el = talloc_zero(mem_ctx, struct ldb_message_element);
2495         if (el == NULL) {
2496                 PyErr_NoMemory();
2497                 talloc_free(mem_ctx);
2498                 return NULL;
2499         }
2500
2501         if (py_elements != NULL) {
2502                 Py_ssize_t i;
2503                 if (PyString_Check(py_elements)) {
2504                         el->num_values = 1;
2505                         el->values = talloc_array(el, struct ldb_val, 1);
2506                         if (el->values == NULL) {
2507                                 talloc_free(mem_ctx);
2508                                 PyErr_NoMemory();
2509                                 return NULL;
2510                         }
2511                         el->values[0].length = PyString_Size(py_elements);
2512                         el->values[0].data = talloc_memdup(el->values, 
2513                                 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2514                 } else if (PySequence_Check(py_elements)) {
2515                         el->num_values = PySequence_Size(py_elements);
2516                         el->values = talloc_array(el, struct ldb_val, el->num_values);
2517                         if (el->values == NULL) {
2518                                 talloc_free(mem_ctx);
2519                                 PyErr_NoMemory();
2520                                 return NULL;
2521                         }
2522                         for (i = 0; i < el->num_values; i++) {
2523                                 PyObject *item = PySequence_GetItem(py_elements, i);
2524                                 if (item == NULL) {
2525                                         talloc_free(mem_ctx);
2526                                         return NULL;
2527                                 }
2528                                 if (!PyString_Check(item)) {
2529                                         PyErr_Format(PyExc_TypeError, 
2530                                                      "Expected string as element %zd in list", i);
2531                                         talloc_free(mem_ctx);
2532                                         return NULL;
2533                                 }
2534                                 el->values[i].length = PyString_Size(item);
2535                                 el->values[i].data = talloc_memdup(el,
2536                                         (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2537                         }
2538                 } else {
2539                         PyErr_SetString(PyExc_TypeError, 
2540                                         "Expected string or list");
2541                         talloc_free(mem_ctx);
2542                         return NULL;
2543                 }
2544         }
2545
2546         el->flags = flags;
2547         el->name = talloc_strdup(el, name);
2548
2549         ret = PyObject_New(PyLdbMessageElementObject, type);
2550         if (ret == NULL) {
2551                 talloc_free(mem_ctx);
2552                 return NULL;
2553         }
2554
2555         ret->mem_ctx = mem_ctx;
2556         ret->el = el;
2557         return (PyObject *)ret;
2558 }
2559
2560 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2561 {
2562         char *element_str = NULL;
2563         Py_ssize_t i;
2564         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2565         PyObject *ret;
2566
2567         for (i = 0; i < el->num_values; i++) {
2568                 PyObject *o = py_ldb_msg_element_find(self, i);
2569                 if (element_str == NULL)
2570                         element_str = talloc_strdup(NULL, PyObject_REPR(o));
2571                 else
2572                         element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2573         }
2574
2575         if (element_str != NULL) {
2576                 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2577                 talloc_free(element_str);
2578         } else {
2579                 ret = PyString_FromString("MessageElement([])");
2580         }
2581
2582         return ret;
2583 }
2584
2585 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2586 {
2587         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2588
2589         if (el->num_values == 1)
2590                 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2591         else
2592                 Py_RETURN_NONE;
2593 }
2594
2595 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2596 {
2597         talloc_free(self->mem_ctx);
2598         PyObject_Del(self);
2599 }
2600
2601 static PyTypeObject PyLdbMessageElement = {
2602         .tp_name = "ldb.MessageElement",
2603         .tp_basicsize = sizeof(PyLdbMessageElementObject),
2604         .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2605         .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2606         .tp_str = (reprfunc)py_ldb_msg_element_str,
2607         .tp_methods = py_ldb_msg_element_methods,
2608         .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2609         .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2610         .tp_as_sequence = &py_ldb_msg_element_seq,
2611         .tp_new = py_ldb_msg_element_new,
2612         .tp_flags = Py_TPFLAGS_DEFAULT,
2613         .tp_doc = "An element of a Message",
2614 };
2615
2616
2617 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2618 {
2619         PyObject *py_ldb;
2620         PyObject *py_dict;
2621         PyObject *py_ret;
2622         struct ldb_message *msg;
2623         struct ldb_context *ldb_ctx;
2624         unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2625
2626         if (!PyArg_ParseTuple(args, "O!O!|I",
2627                               &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2628                               &mod_flags)) {
2629                 return NULL;
2630         }
2631
2632         if (!PyLdb_Check(py_ldb)) {
2633                 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
2634                 return NULL;
2635         }
2636
2637         /* mask only flags we are going to use */
2638         mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2639         if (!mod_flags) {
2640                 PyErr_SetString(PyExc_ValueError,
2641                                 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2642                                 " expected as mod_flag value");
2643                 return NULL;
2644         }
2645
2646         ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2647
2648         msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2649         if (!msg) {
2650                 return NULL;
2651         }
2652
2653         py_ret = PyLdbMessage_FromMessage(msg);
2654
2655         talloc_unlink(ldb_ctx, msg);
2656
2657         return py_ret;
2658 }
2659
2660 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2661 {
2662         char *name;
2663         if (!PyArg_ParseTuple(args, "s", &name))
2664                 return NULL;
2665
2666         ldb_msg_remove_attr(self->msg, name);
2667
2668         Py_RETURN_NONE;
2669 }
2670
2671 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2672 {
2673         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2674         Py_ssize_t i, j = 0;
2675         PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2676         if (msg->dn != NULL) {
2677                 PyList_SetItem(obj, j, PyString_FromString("dn"));
2678                 j++;
2679         }
2680         for (i = 0; i < msg->num_elements; i++) {
2681                 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2682                 j++;
2683         }
2684         return obj;
2685 }
2686
2687 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2688 {
2689         struct ldb_message_element *el;
2690         char *name;
2691         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2692         if (!PyString_Check(py_name)) {
2693                 PyErr_SetNone(PyExc_TypeError);
2694                 return NULL;
2695         }
2696         name = PyString_AsString(py_name);
2697         if (!ldb_attr_cmp(name, "dn"))
2698                 return pyldb_Dn_FromDn(msg->dn);
2699         el = ldb_msg_find_element(msg, name);
2700         if (el == NULL) {
2701                 return NULL;
2702         }
2703         return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2704 }
2705
2706 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2707 {
2708         PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2709         if (ret == NULL) {
2710                 PyErr_SetString(PyExc_KeyError, "No such element");
2711                 return NULL;
2712         }
2713         return ret;
2714 }
2715
2716 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2717 {
2718         PyObject *def = NULL;
2719         const char *kwnames[] = { "name", "default", "idx", NULL };
2720         const char *name = NULL;
2721         int idx = -1;
2722         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2723         struct ldb_message_element *el;
2724
2725         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2726                                          discard_const_p(char *, kwnames), &name, &def, &idx)) {
2727                 return NULL;
2728         }
2729
2730         if (strcasecmp(name, "dn") == 0) {
2731                 return pyldb_Dn_FromDn(msg->dn);
2732         }
2733
2734         el = ldb_msg_find_element(msg, name);
2735
2736         if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2737                 if (def != NULL) {
2738                         return def;
2739                 }
2740                 Py_RETURN_NONE;
2741         }
2742
2743         if (idx == -1) {
2744                 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2745         }
2746
2747         return PyObject_FromLdbValue(&el->values[idx]);
2748 }
2749
2750 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2751 {
2752         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2753         Py_ssize_t i, j = 0;
2754         PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2755         if (msg->dn != NULL) {
2756                 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2757                 j++;
2758         }
2759         for (i = 0; i < msg->num_elements; i++, j++) {
2760                 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2761                 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2762                 PyList_SetItem(l, j, value);
2763         }
2764         return l;
2765 }
2766
2767 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2768 {
2769         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2770         Py_ssize_t i = 0;
2771         PyObject *l = PyList_New(msg->num_elements);
2772         for (i = 0; i < msg->num_elements; i++) {
2773                 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2774         }
2775         return l;
2776 }
2777
2778 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2779 {
2780         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2781         PyLdbMessageElementObject *py_element;
2782         int i, ret;
2783         struct ldb_message_element *el;
2784         struct ldb_message_element *el_new;
2785
2786         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2787                 return NULL;
2788
2789         el = py_element->el;
2790         if (el == NULL) {
2791                 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
2792                 return NULL;
2793         }
2794
2795         ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
2796         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2797
2798         /* now deep copy all attribute values */
2799         el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
2800         if (el_new->values == NULL) {
2801                 PyErr_NoMemory();
2802                 return NULL;
2803         }
2804         el_new->num_values = el->num_values;
2805
2806         for (i = 0; i < el->num_values; i++) {
2807                 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
2808                 if (el_new->values[i].data == NULL
2809                                 && el->values[i].length != 0) {
2810                         PyErr_NoMemory();
2811                         return NULL;
2812                 }
2813         }
2814
2815         Py_RETURN_NONE;
2816 }
2817
2818 static PyMethodDef py_ldb_msg_methods[] = {
2819         { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2820                 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2821                 "Class method to create ldb.Message object from Dictionary.\n"
2822                 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2823         { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, 
2824                 "S.keys() -> list\n\n"
2825                 "Return sequence of all attribute names." },
2826         { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, 
2827                 "S.remove(name)\n\n"
2828                 "Remove all entries for attributes with the specified name."},
2829         { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2830           "msg.get(name,default=None,idx=None) -> string\n"
2831           "idx is the index into the values array\n"
2832           "if idx is None, then a list is returned\n"
2833           "if idx is not None, then the element with that index is returned\n"
2834           "if you pass the special name 'dn' then the DN object is returned\n"},
2835         { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2836         { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2837         { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2838                 "S.add(element)\n\n"
2839                 "Add an element to this message." },
2840         { NULL },
2841 };
2842
2843 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2844 {
2845         PyObject *list, *iter;
2846
2847         list = py_ldb_msg_keys(self);
2848         iter = PyObject_GetIter(list);
2849         Py_DECREF(list);
2850         return iter;
2851 }
2852
2853 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2854 {
2855         char *attr_name;
2856
2857         if (!PyString_Check(name)) {
2858                 PyErr_SetNone(PyExc_TypeError);
2859                 return -1;
2860         }
2861
2862         attr_name = PyString_AsString(name);
2863         if (value == NULL) {
2864                 /* delitem */
2865                 ldb_msg_remove_attr(self->msg, attr_name);
2866         } else {
2867                 int ret;
2868                 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2869                                                                            value, 0, attr_name);
2870                 if (el == NULL) {
2871                         return -1;
2872                 }
2873                 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2874                 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2875                 if (ret != LDB_SUCCESS) {
2876                         PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
2877                         return -1;
2878                 }
2879         }
2880         return 0;
2881 }
2882
2883 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2884 {
2885         return pyldb_Message_AsMessage(self)->num_elements;
2886 }
2887
2888 static PyMappingMethods py_ldb_msg_mapping = {
2889         .mp_length = (lenfunc)py_ldb_msg_length,
2890         .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2891         .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2892 };
2893
2894 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2895 {
2896         const char * const kwnames[] = { "dn", NULL };
2897         struct ldb_message *ret;
2898         TALLOC_CTX *mem_ctx;
2899         PyObject *pydn = NULL;
2900         PyLdbMessageObject *py_ret;
2901
2902         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2903                                          discard_const_p(char *, kwnames),
2904                                          &pydn))
2905                 return NULL;
2906
2907         mem_ctx = talloc_new(NULL);
2908         if (mem_ctx == NULL) {
2909                 PyErr_NoMemory();
2910                 return NULL;
2911         }
2912
2913         ret = ldb_msg_new(mem_ctx);
2914         if (ret == NULL) {
2915                 talloc_free(mem_ctx);
2916                 PyErr_NoMemory();
2917                 return NULL;
2918         }
2919
2920         if (pydn != NULL) {
2921                 struct ldb_dn *dn;
2922                 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2923                         talloc_free(mem_ctx);
2924                         return NULL;
2925                 }
2926                 ret->dn = talloc_reference(ret, dn);
2927         }
2928
2929         py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2930         if (py_ret == NULL) {
2931                 PyErr_NoMemory();
2932                 talloc_free(mem_ctx);
2933                 return NULL;
2934         }
2935
2936         py_ret->mem_ctx = mem_ctx;
2937         py_ret->msg = ret;
2938         return (PyObject *)py_ret;
2939 }
2940
2941 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2942 {
2943         PyLdbMessageObject *ret;
2944
2945         ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2946         if (ret == NULL) {
2947                 PyErr_NoMemory();
2948                 return NULL;
2949         }
2950         ret->mem_ctx = talloc_new(NULL);
2951         ret->msg = talloc_reference(ret->mem_ctx, msg);
2952         return (PyObject *)ret;
2953 }
2954
2955 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2956 {
2957         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2958         return pyldb_Dn_FromDn(msg->dn);
2959 }
2960
2961 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2962 {
2963         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2964         if (!pyldb_Dn_Check(value)) {
2965                 PyErr_SetNone(PyExc_TypeError);
2966                 return -1;
2967         }
2968
2969         msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2970         return 0;
2971 }
2972
2973 static PyGetSetDef py_ldb_msg_getset[] = {
2974         { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2975         { NULL }
2976 };
2977
2978 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2979 {
2980         PyObject *dict = PyDict_New(), *ret;
2981         if (PyDict_Update(dict, (PyObject *)self) != 0)
2982                 return NULL;
2983         ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2984         Py_DECREF(dict);
2985         return ret;
2986 }
2987
2988 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2989 {
2990         talloc_free(self->mem_ctx);
2991         PyObject_Del(self);
2992 }
2993
2994 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2995                               PyLdbMessageObject *py_msg2)
2996 {
2997         struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
2998                            *msg2 = pyldb_Message_AsMessage(py_msg2);
2999         unsigned int i;
3000         int ret;
3001
3002         if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3003                 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3004                 if (ret != 0) {
3005                         return SIGN(ret);
3006                 }
3007         }
3008
3009         ret = msg1->num_elements - msg2->num_elements;
3010         if (ret != 0) {
3011                 return SIGN(ret);
3012         }
3013
3014         for (i = 0; i < msg1->num_elements; i++) {
3015                 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3016                                                    &msg2->elements[i]);
3017                 if (ret != 0) {
3018                         return SIGN(ret);
3019                 }
3020
3021                 ret = ldb_msg_element_compare(&msg1->elements[i],
3022                                               &msg2->elements[i]);
3023                 if (ret != 0) {
3024                         return SIGN(ret);
3025                 }
3026         }
3027
3028         return 0;
3029 }
3030
3031 static PyTypeObject PyLdbMessage = {
3032         .tp_name = "ldb.Message",
3033         .tp_methods = py_ldb_msg_methods,
3034         .tp_getset = py_ldb_msg_getset,
3035         .tp_as_mapping = &py_ldb_msg_mapping,
3036         .tp_basicsize = sizeof(PyLdbMessageObject),
3037         .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3038         .tp_new = py_ldb_msg_new,
3039         .tp_repr = (reprfunc)py_ldb_msg_repr,
3040         .tp_flags = Py_TPFLAGS_DEFAULT,
3041         .tp_iter = (getiterfunc)py_ldb_msg_iter,
3042         .tp_compare = (cmpfunc)py_ldb_msg_compare,
3043         .tp_doc = "A LDB Message",
3044 };
3045
3046 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3047 {
3048         PyLdbTreeObject *ret;
3049
3050         ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3051         if (ret == NULL) {
3052                 PyErr_NoMemory();
3053                 return NULL;
3054         }
3055
3056         ret->mem_ctx = talloc_new(NULL);
3057         ret->tree = talloc_reference(ret->mem_ctx, tree);
3058         return (PyObject *)ret;
3059 }
3060
3061 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3062 {
3063         talloc_free(self->mem_ctx);
3064         PyObject_Del(self);
3065 }
3066
3067 static PyTypeObject PyLdbTree = {
3068         .tp_name = "ldb.Tree",
3069         .tp_basicsize = sizeof(PyLdbTreeObject),
3070         .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3071         .tp_flags = Py_TPFLAGS_DEFAULT,
3072         .tp_doc = "A search tree",
3073 };
3074
3075 /* Ldb_module */
3076 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3077 {
3078         PyObject *py_ldb = (PyObject *)mod->private_data;
3079         PyObject *py_result, *py_base, *py_attrs, *py_tree;
3080
3081         py_base = pyldb_Dn_FromDn(req->op.search.base);
3082
3083         if (py_base == NULL)
3084                 return LDB_ERR_OPERATIONS_ERROR;
3085
3086         py_tree = PyLdbTree_FromTree(req->op.search.tree);
3087
3088         if (py_tree == NULL)
3089                 return LDB_ERR_OPERATIONS_ERROR;
3090
3091         if (req->op.search.attrs == NULL) {
3092                 py_attrs = Py_None;
3093         } else {
3094                 int i, len;
3095                 for (len = 0; req->op.search.attrs[len]; len++);
3096                 py_attrs = PyList_New(len);
3097                 for (i = 0; i < len; i++)
3098                         PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
3099         }
3100
3101         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3102                                         discard_const_p(char, "OiOO"),
3103                                         py_base, req->op.search.scope, py_tree, py_attrs);
3104
3105         Py_DECREF(py_attrs);
3106         Py_DECREF(py_tree);
3107         Py_DECREF(py_base);
3108
3109         if (py_result == NULL) {
3110                 return LDB_ERR_PYTHON_EXCEPTION;
3111         }
3112
3113         req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3114         if (req->op.search.res == NULL) {
3115                 return LDB_ERR_PYTHON_EXCEPTION;
3116         }
3117
3118         Py_DECREF(py_result);
3119
3120         return LDB_SUCCESS;
3121 }
3122
3123 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3124 {
3125         PyObject *py_ldb = (PyObject *)mod->private_data;
3126         PyObject *py_result, *py_msg;
3127
3128         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3129
3130         if (py_msg == NULL) {
3131                 return LDB_ERR_OPERATIONS_ERROR;
3132         }
3133
3134         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3135                                         discard_const_p(char, "O"),
3136                                         py_msg);
3137
3138         Py_DECREF(py_msg);
3139
3140         if (py_result == NULL) {
3141                 return LDB_ERR_PYTHON_EXCEPTION;
3142         }
3143
3144         Py_DECREF(py_result);
3145
3146         return LDB_SUCCESS;
3147 }
3148
3149 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3150 {
3151         PyObject *py_ldb = (PyObject *)mod->private_data;
3152         PyObject *py_result, *py_msg;
3153
3154         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3155
3156         if (py_msg == NULL) {
3157                 return LDB_ERR_OPERATIONS_ERROR;
3158         }
3159
3160         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3161                                         discard_const_p(char, "O"),
3162                                         py_msg);
3163
3164         Py_DECREF(py_msg);
3165
3166         if (py_result == NULL) {
3167                 return LDB_ERR_PYTHON_EXCEPTION;
3168         }
3169
3170         Py_DECREF(py_result);
3171
3172         return LDB_SUCCESS;
3173 }
3174
3175 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3176 {
3177         PyObject *py_ldb = (PyObject *)mod->private_data;
3178         PyObject *py_result, *py_dn;
3179
3180         py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3181
3182         if (py_dn == NULL)
3183                 return LDB_ERR_OPERATIONS_ERROR;
3184
3185         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3186                                         discard_const_p(char, "O"),
3187                                         py_dn);
3188
3189         if (py_result == NULL) {
3190                 return LDB_ERR_PYTHON_EXCEPTION;
3191         }
3192
3193         Py_DECREF(py_result);
3194
3195         return LDB_SUCCESS;
3196 }
3197
3198 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3199 {
3200         PyObject *py_ldb = (PyObject *)mod->private_data;
3201         PyObject *py_result, *py_olddn, *py_newdn;
3202
3203         py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3204
3205         if (py_olddn == NULL)
3206                 return LDB_ERR_OPERATIONS_ERROR;
3207
3208         py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3209
3210         if (py_newdn == NULL)
3211                 return LDB_ERR_OPERATIONS_ERROR;
3212
3213         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3214                                         discard_const_p(char, "OO"),
3215                                         py_olddn, py_newdn);
3216
3217         Py_DECREF(py_olddn);
3218         Py_DECREF(py_newdn);
3219
3220         if (py_result == NULL) {
3221                 return LDB_ERR_PYTHON_EXCEPTION;
3222         }
3223
3224         Py_DECREF(py_result);
3225
3226         return LDB_SUCCESS;
3227 }
3228
3229 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3230 {
3231         PyObject *py_ldb = (PyObject *)mod->private_data;
3232         PyObject *py_result;
3233
3234         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3235                                         discard_const_p(char, ""));
3236
3237         Py_XDECREF(py_result);
3238
3239         return LDB_ERR_OPERATIONS_ERROR;
3240 }
3241
3242 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3243 {
3244         PyObject *py_ldb = (PyObject *)mod->private_data;
3245         PyObject *py_result;
3246
3247         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3248                                         discard_const_p(char, ""));
3249
3250         Py_XDECREF(py_result);
3251
3252         return LDB_ERR_OPERATIONS_ERROR;
3253 }
3254
3255 static int py_module_start_transaction(struct ldb_module *mod)
3256 {
3257         PyObject *py_ldb = (PyObject *)mod->private_data;
3258         PyObject *py_result;
3259
3260         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3261                                         discard_const_p(char, ""));
3262
3263         if (py_result == NULL) {
3264                 return LDB_ERR_PYTHON_EXCEPTION;
3265         }
3266
3267         Py_DECREF(py_result);
3268
3269         return LDB_SUCCESS;
3270 }
3271
3272 static int py_module_end_transaction(struct ldb_module *mod)
3273 {
3274         PyObject *py_ldb = (PyObject *)mod->private_data;
3275         PyObject *py_result;
3276
3277         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3278                                         discard_const_p(char, ""));
3279
3280         if (py_result == NULL) {
3281                 return LDB_ERR_PYTHON_EXCEPTION;
3282         }
3283
3284         Py_DECREF(py_result);
3285
3286         return LDB_SUCCESS;
3287 }
3288
3289 static int py_module_del_transaction(struct ldb_module *mod)
3290 {
3291         PyObject *py_ldb = (PyObject *)mod->private_data;
3292         PyObject *py_result;
3293
3294         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3295                                         discard_const_p(char, ""));
3296
3297         if (py_result == NULL) {
3298                 return LDB_ERR_PYTHON_EXCEPTION;
3299         }
3300
3301         Py_DECREF(py_result);
3302
3303         return LDB_SUCCESS;
3304 }
3305
3306 static int py_module_destructor(struct ldb_module *mod)
3307 {
3308         Py_DECREF((PyObject *)mod->private_data);
3309         return 0;
3310 }
3311
3312 static int py_module_init(struct ldb_module *mod)
3313 {
3314         PyObject *py_class = (PyObject *)mod->ops->private_data;
3315         PyObject *py_result, *py_next, *py_ldb;
3316
3317         py_ldb = PyLdb_FromLdbContext(mod->ldb);
3318
3319         if (py_ldb == NULL)
3320                 return LDB_ERR_OPERATIONS_ERROR;
3321
3322         py_next = PyLdbModule_FromModule(mod->next);
3323
3324         if (py_next == NULL)
3325                 return LDB_ERR_OPERATIONS_ERROR;
3326
3327         py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3328                                           py_ldb, py_next);
3329
3330         if (py_result == NULL) {
3331                 return LDB_ERR_PYTHON_EXCEPTION;
3332         }
3333
3334         mod->private_data = py_result;
3335
3336         talloc_set_destructor(mod, py_module_destructor);
3337
3338         return ldb_next_init(mod);
3339 }
3340
3341 static PyObject *py_register_module(PyObject *module, PyObject *args)
3342 {
3343         int ret;
3344         struct ldb_module_ops *ops;
3345         PyObject *input;
3346
3347         if (!PyArg_ParseTuple(args, "O", &input))
3348                 return NULL;
3349
3350         ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3351         if (ops == NULL) {
3352                 PyErr_NoMemory();
3353                 return NULL;
3354         }
3355
3356         ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3357
3358         Py_INCREF(input);
3359         ops->private_data = input;
3360         ops->init_context = py_module_init;
3361         ops->search = py_module_search;
3362         ops->add = py_module_add;
3363         ops->modify = py_module_modify;
3364         ops->del = py_module_del;
3365         ops->rename = py_module_rename;
3366         ops->request = py_module_request;
3367         ops->extended = py_module_extended;
3368         ops->start_transaction = py_module_start_transaction;
3369         ops->end_transaction = py_module_end_transaction;
3370         ops->del_transaction = py_module_del_transaction;
3371
3372         ret = ldb_register_module(ops);
3373
3374         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3375
3376         Py_RETURN_NONE;
3377 }
3378
3379 static PyObject *py_timestring(PyObject *module, PyObject *args)
3380 {
3381         /* most times "time_t" is a signed integer type with 32 or 64 bit:
3382          * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3383         long int t_val;
3384         char *tresult;
3385         PyObject *ret;
3386         if (!PyArg_ParseTuple(args, "l", &t_val))
3387                 return NULL;
3388         tresult = ldb_timestring(NULL, (time_t) t_val);
3389         ret = PyString_FromString(tresult);
3390         talloc_free(tresult);
3391         return ret;
3392 }
3393
3394 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3395 {
3396         char *str;
3397         if (!PyArg_ParseTuple(args, "s", &str))
3398                 return NULL;
3399
3400         return PyInt_FromLong(ldb_string_to_time(str));
3401 }
3402
3403 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3404 {
3405         char *name;
3406         if (!PyArg_ParseTuple(args, "s", &name))
3407                 return NULL;
3408         return PyBool_FromLong(ldb_valid_attr_name(name));
3409 }
3410
3411 /*
3412   encode a string using RFC2254 rules
3413  */
3414 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3415 {
3416         char *str, *encoded;
3417         int size = 0;
3418         struct ldb_val val;
3419         PyObject *ret;
3420
3421         if (!PyArg_ParseTuple(args, "s#", &str, &size))
3422                 return NULL;
3423         val.data = (uint8_t *)str;
3424         val.length = size;
3425
3426         encoded = ldb_binary_encode(NULL, val);
3427         if (encoded == NULL) {
3428                 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3429                 return NULL;
3430         }
3431         ret = PyString_FromString(encoded);
3432         talloc_free(encoded);
3433         return ret;
3434 }
3435
3436 /*
3437   decode a string using RFC2254 rules
3438  */
3439 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3440 {
3441         char *str;
3442         struct ldb_val val;
3443         PyObject *ret;
3444
3445         if (!PyArg_ParseTuple(args, "s", &str))
3446                 return NULL;
3447
3448         val = ldb_binary_decode(NULL, str);
3449         if (val.data == NULL) {
3450                 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3451                 return NULL;
3452         }
3453         ret = Py_BuildValue("s#", val.data, val.length);
3454         talloc_free(val.data);
3455         return ret;
3456 }
3457
3458 static PyMethodDef py_ldb_global_methods[] = {
3459         { "register_module", py_register_module, METH_VARARGS, 
3460                 "S.register_module(module) -> None\n\n"
3461                 "Register a LDB module."},
3462         { "timestring", py_timestring, METH_VARARGS, 
3463                 "S.timestring(int) -> string\n\n"
3464                 "Generate a LDAP time string from a UNIX timestamp" },
3465         { "string_to_time", py_string_to_time, METH_VARARGS,
3466                 "S.string_to_time(string) -> int\n\n"
3467                 "Parse a LDAP time string into a UNIX timestamp." },
3468         { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3469                 "S.valid_attr_name(name) -> bool\n\nn"
3470                 "Check whether the supplied name is a valid attribute name." },
3471         { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3472                 "S.open() -> Ldb\n\n"
3473                 "Open a new LDB context." },
3474         { "binary_encode", py_binary_encode, METH_VARARGS,
3475                 "S.binary_encode(string) -> string\n\n"
3476                 "Perform a RFC2254 binary encoding on a string" },
3477         { "binary_decode", py_binary_decode, METH_VARARGS,
3478                 "S.binary_decode(string) -> string\n\n"
3479                 "Perform a RFC2254 binary decode on a string" },
3480         { NULL }
3481 };
3482
3483 void initldb(void)
3484 {
3485         PyObject *m;
3486
3487         if (PyType_Ready(&PyLdbDn) < 0)
3488                 return;
3489
3490         if (PyType_Ready(&PyLdbMessage) < 0)
3491                 return;
3492
3493         if (PyType_Ready(&PyLdbMessageElement) < 0)
3494                 return;
3495
3496         if (PyType_Ready(&PyLdb) < 0)
3497                 return;
3498
3499         if (PyType_Ready(&PyLdbModule) < 0)
3500                 return;
3501
3502         if (PyType_Ready(&PyLdbTree) < 0)
3503                 return;
3504
3505         if (PyType_Ready(&PyLdbResult) < 0)
3506                 return;
3507
3508         if (PyType_Ready(&PyLdbControl) < 0)
3509                 return;
3510
3511         m = Py_InitModule3("ldb", py_ldb_global_methods, 
3512                 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3513         if (m == NULL)
3514                 return;
3515
3516         PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3517         PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3518         PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3519         PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3520         PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3521         PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3522         PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3523
3524         PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3525         PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3526         PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3527         PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3528
3529         PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3530         PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3531         PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3532
3533         PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3534         PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3535         PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3536         PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3537         PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3538         PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3539         PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3540         PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3541         PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3542         PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3543         PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3544         PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3545         PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3546         PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3547         PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3548         PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3549         PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3550         PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3551         PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3552         PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3553         PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3554         PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3555         PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3556         PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3557         PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3558         PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3559         PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3560         PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3561         PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3562         PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3563         PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3564         PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3565         PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3566         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3567         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3568         PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3569         PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3570         PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3571         PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3572
3573         PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3574         PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3575         PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3576         PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3577
3578         PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3579
3580         PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3581         PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3582
3583         Py_INCREF(&PyLdb);
3584         Py_INCREF(&PyLdbDn);
3585         Py_INCREF(&PyLdbModule);
3586         Py_INCREF(&PyLdbMessage);
3587         Py_INCREF(&PyLdbMessageElement);
3588         Py_INCREF(&PyLdbTree);
3589         Py_INCREF(&PyLdbResult);
3590         Py_INCREF(&PyLdbControl);
3591
3592         PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3593         PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3594         PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3595         PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3596         PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3597         PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3598         PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3599
3600         PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3601
3602 #define ADD_LDB_STRING(val)  PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3603
3604         ADD_LDB_STRING(SYNTAX_DN);
3605         ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3606         ADD_LDB_STRING(SYNTAX_INTEGER);
3607         ADD_LDB_STRING(SYNTAX_BOOLEAN);
3608         ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3609         ADD_LDB_STRING(SYNTAX_UTC_TIME);
3610         ADD_LDB_STRING(OID_COMPARATOR_AND);
3611         ADD_LDB_STRING(OID_COMPARATOR_OR);
3612 }