pyldb: Type-check arguments parsed with PyArg_ParseTuple*
[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 static 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, "O!s",
125                                          discard_const_p(char *, kwnames),
126                                          &PyLdb, &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, *ret;
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         ret = PyObject_GetIter(list);
1577         Py_DECREF(list);
1578         return ret;
1579 }
1580
1581 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1582 {
1583         int ldb_ret;
1584         PyObject *py_msg_old;
1585         PyObject *py_msg_new;
1586         struct ldb_message *diff;
1587         struct ldb_context *ldb;
1588         PyObject *py_ret;
1589
1590         if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1591                 return NULL;
1592
1593         if (!PyLdbMessage_Check(py_msg_old)) {
1594                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1595                 return NULL;
1596         }
1597
1598         if (!PyLdbMessage_Check(py_msg_new)) {
1599                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1600                 return NULL;
1601         }
1602
1603         ldb = pyldb_Ldb_AsLdbContext(self);
1604         ldb_ret = ldb_msg_difference(ldb, ldb,
1605                                      pyldb_Message_AsMessage(py_msg_old),
1606                                      pyldb_Message_AsMessage(py_msg_new),
1607                                      &diff);
1608         if (ldb_ret != LDB_SUCCESS) {
1609                 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1610                 return NULL;
1611         }
1612
1613         py_ret = PyLdbMessage_FromMessage(diff);
1614
1615         talloc_unlink(ldb, diff);
1616
1617         return py_ret;
1618 }
1619
1620 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1621 {
1622         const struct ldb_schema_attribute *a;
1623         struct ldb_val old_val;
1624         struct ldb_val new_val;
1625         TALLOC_CTX *mem_ctx;
1626         PyObject *ret;
1627         char *element_name;
1628         PyObject *val;
1629
1630         if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1631                 return NULL;
1632
1633         old_val.data = (uint8_t *)PyString_AsString(val);
1634         old_val.length = PyString_Size(val);
1635
1636         if (old_val.data == NULL) {
1637                 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1638                 return NULL;
1639         }
1640
1641         a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1642
1643         if (a == NULL) {
1644                 Py_RETURN_NONE;
1645         }
1646
1647         mem_ctx = talloc_new(NULL);
1648         if (mem_ctx == NULL) {
1649                 PyErr_NoMemory();
1650                 return NULL;
1651         }
1652
1653         if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1654                 talloc_free(mem_ctx);
1655                 Py_RETURN_NONE;
1656         }
1657
1658         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
1659
1660         talloc_free(mem_ctx);
1661
1662         return ret;
1663 }
1664
1665 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1666 {
1667         PyObject *py_base = Py_None;
1668         int scope = LDB_SCOPE_DEFAULT;
1669         char *expr = NULL;
1670         PyObject *py_attrs = Py_None;
1671         PyObject *py_controls = Py_None;
1672         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1673         int ret;
1674         struct ldb_result *res;
1675         struct ldb_request *req;
1676         const char **attrs;
1677         struct ldb_context *ldb_ctx;
1678         struct ldb_control **parsed_controls;
1679         struct ldb_dn *base;
1680         PyObject *py_ret;
1681         TALLOC_CTX *mem_ctx;
1682
1683         /* type "int" rather than "enum" for "scope" is intentional */
1684         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1685                                          discard_const_p(char *, kwnames),
1686                                          &py_base, &scope, &expr, &py_attrs, &py_controls))
1687                 return NULL;
1688
1689
1690         mem_ctx = talloc_new(NULL);
1691         if (mem_ctx == NULL) {
1692                 PyErr_NoMemory();
1693                 return NULL;
1694         }
1695         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1696
1697         if (py_attrs == Py_None) {
1698                 attrs = NULL;
1699         } else {
1700                 attrs = PyList_AsStringList(mem_ctx, py_attrs, "attrs");
1701                 if (attrs == NULL) {
1702                         talloc_free(mem_ctx);
1703                         return NULL;
1704                 }
1705         }
1706
1707         if (py_base == Py_None) {
1708                 base = ldb_get_default_basedn(ldb_ctx);
1709         } else {
1710                 if (!pyldb_Object_AsDn(ldb_ctx, py_base, ldb_ctx, &base)) {
1711                         talloc_free(attrs);
1712                         return NULL;
1713                 }
1714         }
1715
1716         if (py_controls == Py_None) {
1717                 parsed_controls = NULL;
1718         } else {
1719                 const char **controls = PyList_AsStringList(mem_ctx, py_controls, "controls");
1720                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1721                 talloc_free(controls);
1722         }
1723
1724         res = talloc_zero(mem_ctx, struct ldb_result);
1725         if (res == NULL) {
1726                 PyErr_NoMemory();
1727                 talloc_free(mem_ctx);
1728                 return NULL;
1729         }
1730
1731         ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1732                                    base,
1733                                    scope,
1734                                    expr,
1735                                    attrs,
1736                                    parsed_controls,
1737                                    res,
1738                                    ldb_search_default_callback,
1739                                    NULL);
1740
1741         if (ret != LDB_SUCCESS) {
1742                 talloc_free(mem_ctx);
1743                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1744                 return NULL;
1745         }
1746
1747         talloc_steal(req, attrs);
1748
1749         ret = ldb_request(ldb_ctx, req);
1750
1751         if (ret == LDB_SUCCESS) {
1752                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1753         }
1754
1755         if (ret != LDB_SUCCESS) {
1756                 talloc_free(mem_ctx);
1757                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1758                 return NULL;
1759         }
1760
1761         py_ret = PyLdbResult_FromResult(res);
1762
1763         talloc_free(mem_ctx);
1764
1765         return py_ret;
1766 }
1767
1768 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
1769 {
1770         char *name;
1771         void *data;
1772
1773         if (!PyArg_ParseTuple(args, "s", &name))
1774                 return NULL;
1775
1776         data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
1777
1778         if (data == NULL)
1779                 Py_RETURN_NONE;
1780
1781         /* FIXME: More interpretation */
1782
1783         return Py_True;
1784 }
1785
1786 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
1787 {
1788         char *name;
1789         PyObject *data;
1790
1791         if (!PyArg_ParseTuple(args, "sO", &name, &data))
1792                 return NULL;
1793
1794         /* FIXME: More interpretation */
1795
1796         ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
1797
1798         Py_RETURN_NONE;
1799 }
1800
1801 static PyObject *py_ldb_modules(PyLdbObject *self)
1802 {
1803         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1804         PyObject *ret = PyList_New(0);
1805         struct ldb_module *mod;
1806
1807         for (mod = ldb->modules; mod; mod = mod->next) {
1808                 PyList_Append(ret, PyLdbModule_FromModule(mod));
1809         }
1810
1811         return ret;
1812 }
1813
1814 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
1815 {
1816         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
1817         int type, ret;
1818         uint64_t value;
1819
1820         if (!PyArg_ParseTuple(args, "i", &type))
1821                 return NULL;
1822
1823         /* FIXME: More interpretation */
1824
1825         ret = ldb_sequence_number(ldb, type, &value);
1826
1827         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
1828
1829         return PyLong_FromLongLong(value);
1830 }
1831 static PyMethodDef py_ldb_methods[] = {
1832         { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, 
1833                 "S.set_debug(callback) -> None\n"
1834                 "Set callback for LDB debug messages.\n"
1835                 "The callback should accept a debug level and debug text." },
1836         { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, 
1837                 "S.set_create_perms(mode) -> None\n"
1838                 "Set mode to use when creating new LDB files." },
1839         { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
1840                 "S.set_modules_dir(path) -> None\n"
1841                 "Set path LDB should search for modules" },
1842         { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, 
1843                 "S.transaction_start() -> None\n"
1844                 "Start a new transaction." },
1845         { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
1846                 "S.transaction_prepare_commit() -> None\n"
1847                 "prepare to commit a new transaction (2-stage commit)." },
1848         { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, 
1849                 "S.transaction_commit() -> None\n"
1850                 "commit a new transaction." },
1851         { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, 
1852                 "S.transaction_cancel() -> None\n"
1853                 "cancel a new transaction." },
1854         { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, 
1855                 NULL },
1856         { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
1857                 NULL },
1858         { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
1859                 NULL },
1860         { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
1861                 NULL },
1862         { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
1863                 NULL },
1864         { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, 
1865                 "S.connect(url, flags=0, options=None) -> None\n"
1866                 "Connect to a LDB URL." },
1867         { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
1868                 "S.modify(message, controls=None, validate=False) -> None\n"
1869                 "Modify an entry." },
1870         { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
1871                 "S.add(message, controls=None) -> None\n"
1872                 "Add an entry." },
1873         { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
1874                 "S.delete(dn, controls=None) -> None\n"
1875                 "Remove an entry." },
1876         { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
1877                 "S.rename(old_dn, new_dn, controls=None) -> None\n"
1878                 "Rename an entry." },
1879         { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
1880                 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
1881                 "Search in a database.\n"
1882                 "\n"
1883                 ":param base: Optional base DN to search\n"
1884                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
1885                 ":param expression: Optional search expression\n"
1886                 ":param attrs: Attributes to return (defaults to all)\n"
1887                 ":param controls: Optional list of controls\n"
1888                 ":return: Iterator over Message objects\n"
1889         },
1890         { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
1891                 NULL },
1892         { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
1893                 NULL },
1894         { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
1895                 NULL },
1896         { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
1897                 "S.parse_ldif(ldif) -> iter(messages)\n"
1898                 "Parse a string formatted using LDIF." },
1899         { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
1900                 "S.write_ldif(message, changetype) -> ldif\n"
1901                 "Print the message as a string formatted using LDIF." },
1902         { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
1903                 "S.msg_diff(Message) -> Message\n"
1904                 "Return an LDB Message of the difference between two Message objects." },
1905         { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
1906                 "S.get_opaque(name) -> value\n"
1907                 "Get an opaque value set on this LDB connection. \n"
1908                 ":note: The returned value may not be useful in Python."
1909         },
1910         { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
1911                 "S.set_opaque(name, value) -> None\n"
1912                 "Set an opaque value on this LDB connection. \n"
1913                 ":note: Passing incorrect values may cause crashes." },
1914         { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
1915                 "S.modules() -> list\n"
1916                 "Return the list of modules on this LDB connection " },
1917         { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
1918                 "S.sequence_number(type) -> value\n"
1919                 "Return the value of the sequence according to the requested type" },
1920         { NULL },
1921 };
1922
1923 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1924 {
1925         PyLdbModuleObject *ret;
1926
1927         ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1928         if (ret == NULL) {
1929                 PyErr_NoMemory();
1930                 return NULL;
1931         }
1932         ret->mem_ctx = talloc_new(NULL);
1933         ret->mod = talloc_reference(ret->mem_ctx, mod);
1934         return (PyObject *)ret;
1935 }
1936
1937 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1938 {
1939         return PyLdbModule_FromModule(pyldb_Ldb_AsLdbContext(self)->modules);
1940 }
1941
1942 static PyGetSetDef py_ldb_getset[] = {
1943         { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1944         { NULL }
1945 };
1946
1947 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1948 {
1949         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1950         struct ldb_dn *dn;
1951         struct ldb_result *result;
1952         unsigned int count;
1953         int ret;
1954
1955         if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
1956                 return -1;
1957         }
1958
1959         ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
1960                          NULL);
1961         if (ret != LDB_SUCCESS) {
1962                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1963                 return -1;
1964         }
1965
1966         count = result->count;
1967
1968         talloc_free(result);
1969
1970         if (count > 1) {
1971                 PyErr_Format(PyExc_RuntimeError,
1972                              "Searching for [%s] dn gave %u results!",
1973                              ldb_dn_get_linearized(dn),
1974                              count);
1975                 return -1;
1976         }
1977
1978         return count;
1979 }
1980
1981 static PySequenceMethods py_ldb_seq = {
1982         .sq_contains = (objobjproc)py_ldb_contains,
1983 };
1984
1985 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1986 {
1987         PyLdbObject *ret;
1988
1989         ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1990         if (ret == NULL) {
1991                 PyErr_NoMemory();
1992                 return NULL;
1993         }
1994         ret->mem_ctx = talloc_new(NULL);
1995         ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1996         return (PyObject *)ret;
1997 }
1998
1999 static void py_ldb_dealloc(PyLdbObject *self)
2000 {
2001         talloc_free(self->mem_ctx);
2002         Py_TYPE(self)->tp_free(self);
2003 }
2004
2005 static PyTypeObject PyLdb = {
2006         .tp_name = "ldb.Ldb",
2007         .tp_methods = py_ldb_methods,
2008         .tp_repr = (reprfunc)py_ldb_repr,
2009         .tp_new = py_ldb_new,
2010         .tp_init = (initproc)py_ldb_init,
2011         .tp_dealloc = (destructor)py_ldb_dealloc,
2012         .tp_getset = py_ldb_getset,
2013         .tp_getattro = PyObject_GenericGetAttr,
2014         .tp_basicsize = sizeof(PyLdbObject),
2015         .tp_doc = "Connection to a LDB database.",
2016         .tp_as_sequence = &py_ldb_seq,
2017         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2018 };
2019
2020 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2021 {
2022         talloc_free(self->mem_ctx);
2023         Py_DECREF(self->msgs);
2024         Py_DECREF(self->referals);
2025         Py_DECREF(self->controls);
2026         Py_TYPE(self)->tp_free(self);
2027 }
2028
2029 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2030 {
2031         Py_INCREF(self->msgs);
2032         return self->msgs;
2033 }
2034
2035 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2036 {
2037         Py_INCREF(self->controls);
2038         return self->controls;
2039 }
2040
2041 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2042 {
2043         Py_INCREF(self->referals);
2044         return self->referals;
2045 }
2046
2047 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2048 {
2049         Py_ssize_t size;
2050         if (self->msgs == NULL) {
2051                 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2052                 return NULL;
2053         }
2054         size = PyList_Size(self->msgs);
2055         return PyInt_FromLong(size);
2056 }
2057
2058 static PyGetSetDef py_ldb_result_getset[] = {
2059         { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2060         { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2061         { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2062         { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2063         { NULL }
2064 };
2065
2066 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2067 {
2068         return PyObject_GetIter(self->msgs);
2069 }
2070
2071 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2072 {
2073         return PySequence_Size(self->msgs);
2074 }
2075
2076 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2077 {
2078         return PySequence_GetItem(self->msgs, idx);
2079 }
2080
2081 static PySequenceMethods py_ldb_result_seq = {
2082         .sq_length = (lenfunc)py_ldb_result_len,
2083         .sq_item = (ssizeargfunc)py_ldb_result_find,
2084 };
2085
2086 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2087 {
2088         return PyString_FromFormat("<ldb result>");
2089 }
2090
2091
2092 static PyTypeObject PyLdbResult = {
2093         .tp_name = "ldb.Result",
2094         .tp_repr = (reprfunc)py_ldb_result_repr,
2095         .tp_dealloc = (destructor)py_ldb_result_dealloc,
2096         .tp_iter = (getiterfunc)py_ldb_result_iter,
2097         .tp_getset = py_ldb_result_getset,
2098         .tp_getattro = PyObject_GenericGetAttr,
2099         .tp_basicsize = sizeof(PyLdbResultObject),
2100         .tp_as_sequence = &py_ldb_result_seq,
2101         .tp_doc = "LDB result.",
2102         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2103 };
2104
2105 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2106 {
2107         return PyString_FromFormat("<ldb module '%s'>",
2108                 pyldb_Module_AsModule(self)->ops->name);
2109 }
2110
2111 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2112 {
2113         return PyString_FromString(pyldb_Module_AsModule(self)->ops->name);
2114 }
2115
2116 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2117 {
2118         pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2119         Py_RETURN_NONE;
2120 }
2121
2122 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2123 {
2124         pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2125         Py_RETURN_NONE;
2126 }
2127
2128 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2129 {
2130         pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2131         Py_RETURN_NONE;
2132 }
2133
2134 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2135 {
2136         PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2137         int ret, scope;
2138         struct ldb_request *req;
2139         const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2140         struct ldb_module *mod;
2141         const char * const*attrs;
2142
2143         /* type "int" rather than "enum" for "scope" is intentional */
2144         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2145                                          discard_const_p(char *, kwnames),
2146                                          &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2147                 return NULL;
2148
2149         mod = self->mod;
2150
2151         if (py_attrs == Py_None) {
2152                 attrs = NULL;
2153         } else {
2154                 attrs = PyList_AsStringList(NULL, py_attrs, "attrs");
2155                 if (attrs == NULL)
2156                         return NULL;
2157         }
2158
2159         ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base), 
2160                              scope, NULL /* expr */, attrs,
2161                              NULL /* controls */, NULL, NULL, NULL);
2162
2163         talloc_steal(req, attrs);
2164
2165         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2166
2167         req->op.search.res = NULL;
2168
2169         ret = mod->ops->search(mod, req);
2170
2171         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2172
2173         py_ret = PyLdbResult_FromResult(req->op.search.res);
2174
2175         talloc_free(req);
2176
2177         return py_ret;
2178 }
2179
2180
2181 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2182 {
2183         struct ldb_request *req;
2184         PyObject *py_message;
2185         int ret;
2186         struct ldb_module *mod;
2187
2188         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2189                 return NULL;
2190
2191         req = talloc_zero(NULL, struct ldb_request);
2192         req->operation = LDB_ADD;
2193         req->op.add.message = pyldb_Message_AsMessage(py_message);
2194
2195         mod = pyldb_Module_AsModule(self);
2196         ret = mod->ops->add(mod, req);
2197
2198         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2199
2200         Py_RETURN_NONE;
2201 }
2202
2203 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) 
2204 {
2205         int ret;
2206         struct ldb_request *req;
2207         PyObject *py_message;
2208         struct ldb_module *mod;
2209
2210         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2211                 return NULL;
2212
2213         req = talloc_zero(NULL, struct ldb_request);
2214         req->operation = LDB_MODIFY;
2215         req->op.mod.message = pyldb_Message_AsMessage(py_message);
2216
2217         mod = pyldb_Module_AsModule(self);
2218         ret = mod->ops->modify(mod, req);
2219
2220         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2221
2222         Py_RETURN_NONE;
2223 }
2224
2225 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) 
2226 {
2227         int ret;
2228         struct ldb_request *req;
2229         PyObject *py_dn;
2230
2231         if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2232                 return NULL;
2233
2234         req = talloc_zero(NULL, struct ldb_request);
2235         req->operation = LDB_DELETE;
2236         req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2237
2238         ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2239
2240         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2241
2242         Py_RETURN_NONE;
2243 }
2244
2245 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2246 {
2247         int ret;
2248         struct ldb_request *req;
2249         PyObject *py_dn1, *py_dn2;
2250
2251         if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2252                 return NULL;
2253
2254         req = talloc_zero(NULL, struct ldb_request);
2255
2256         req->operation = LDB_RENAME;
2257         req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2258         req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2259
2260         ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2261
2262         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2263
2264         Py_RETURN_NONE;
2265 }
2266
2267 static PyMethodDef py_ldb_module_methods[] = {
2268         { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2269         { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2270         { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2271         { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2272         { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2273         { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2274         { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2275         { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2276         { NULL },
2277 };
2278
2279 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2280 {
2281         talloc_free(self->mem_ctx);
2282         PyObject_Del(self);
2283 }
2284
2285 static PyTypeObject PyLdbModule = {
2286         .tp_name = "ldb.LdbModule",
2287         .tp_methods = py_ldb_module_methods,
2288         .tp_repr = (reprfunc)py_ldb_module_repr,
2289         .tp_str = (reprfunc)py_ldb_module_str,
2290         .tp_basicsize = sizeof(PyLdbModuleObject),
2291         .tp_dealloc = (destructor)py_ldb_module_dealloc,
2292         .tp_flags = Py_TPFLAGS_DEFAULT,
2293         .tp_doc = "LDB module (extension)",
2294 };
2295
2296
2297 /**
2298  * Create a ldb_message_element from a Python object.
2299  *
2300  * This will accept any sequence objects that contains strings, or 
2301  * a string object.
2302  *
2303  * A reference to set_obj will be borrowed. 
2304  *
2305  * @param mem_ctx Memory context
2306  * @param set_obj Python object to convert
2307  * @param flags ldb_message_element flags to set
2308  * @param attr_name Name of the attribute
2309  * @return New ldb_message_element, allocated as child of mem_ctx
2310  */
2311 static struct ldb_message_element *PyObject_AsMessageElement(
2312                                                       TALLOC_CTX *mem_ctx,
2313                                                       PyObject *set_obj,
2314                                                       unsigned int flags,
2315                                                       const char *attr_name)
2316 {
2317         struct ldb_message_element *me;
2318
2319         if (pyldb_MessageElement_Check(set_obj)) {
2320                 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2321                 /* We have to talloc_reference() the memory context, not the pointer
2322                  * which may not actually be it's own context */
2323                 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2324                         return pyldb_MessageElement_AsMessageElement(set_obj);
2325                 }
2326                 return NULL;
2327         }
2328
2329         me = talloc(mem_ctx, struct ldb_message_element);
2330         if (me == NULL) {
2331                 PyErr_NoMemory();
2332                 return NULL;
2333         }
2334
2335         me->name = talloc_strdup(me, attr_name);
2336         me->flags = flags;
2337         if (PyString_Check(set_obj)) {
2338                 me->num_values = 1;
2339                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2340                 me->values[0].length = PyString_Size(set_obj);
2341                 me->values[0].data = talloc_memdup(me, 
2342                         (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2343         } else if (PySequence_Check(set_obj)) {
2344                 Py_ssize_t i;
2345                 me->num_values = PySequence_Size(set_obj);
2346                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2347                 for (i = 0; i < me->num_values; i++) {
2348                         PyObject *obj = PySequence_GetItem(set_obj, i);
2349                         if (!PyString_Check(obj)) {
2350                                 PyErr_Format(PyExc_TypeError,
2351                                              "Expected string as element %zd in list", i);
2352                                 talloc_free(me);
2353                                 return NULL;
2354                         }
2355
2356                         me->values[i].length = PyString_Size(obj);
2357                         me->values[i].data = talloc_memdup(me, 
2358                                 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2359                 }
2360         } else {
2361                 PyErr_Format(PyExc_TypeError,
2362                              "String or List type expected for '%s' attribute", attr_name);
2363                 talloc_free(me);
2364                 me = NULL;
2365         }
2366
2367         return me;
2368 }
2369
2370
2371 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2372                                         struct ldb_message_element *me)
2373 {
2374         Py_ssize_t i;
2375         PyObject *result;
2376
2377         /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2378         result = PyList_New(me->num_values);
2379
2380         for (i = 0; i < me->num_values; i++) {
2381                 PyList_SetItem(result, i,
2382                         PyObject_FromLdbValue(&me->values[i]));
2383         }
2384
2385         return result;
2386 }
2387
2388 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2389 {
2390         unsigned int i;
2391         if (!PyArg_ParseTuple(args, "I", &i))
2392                 return NULL;
2393         if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2394                 Py_RETURN_NONE;
2395
2396         return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2397 }
2398
2399 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2400 {
2401         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2402         return PyInt_FromLong(el->flags);
2403 }
2404
2405 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2406 {
2407         unsigned int flags;
2408         struct ldb_message_element *el;
2409         if (!PyArg_ParseTuple(args, "I", &flags))
2410                 return NULL;
2411
2412         el = pyldb_MessageElement_AsMessageElement(self);
2413         el->flags = flags;
2414         Py_RETURN_NONE;
2415 }
2416
2417 static PyMethodDef py_ldb_msg_element_methods[] = {
2418         { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2419         { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2420         { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2421         { NULL },
2422 };
2423
2424 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2425 {
2426         return pyldb_MessageElement_AsMessageElement(self)->num_values;
2427 }
2428
2429 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2430 {
2431         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2432         if (idx < 0 || idx >= el->num_values) {
2433                 PyErr_SetString(PyExc_IndexError, "Out of range");
2434                 return NULL;
2435         }
2436         return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2437 }
2438
2439 static PySequenceMethods py_ldb_msg_element_seq = {
2440         .sq_length = (lenfunc)py_ldb_msg_element_len,
2441         .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2442 };
2443
2444 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2445 {
2446         int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2447                                                                           pyldb_MessageElement_AsMessageElement(other));
2448         return SIGN(ret);
2449 }
2450
2451 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2452 {
2453         PyObject *el = ldb_msg_element_to_set(NULL,
2454                                               pyldb_MessageElement_AsMessageElement(self));
2455         PyObject *ret = PyObject_GetIter(el);
2456         Py_DECREF(el);
2457         return ret;
2458 }
2459
2460 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2461 {
2462         PyLdbMessageElementObject *ret;
2463         ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2464         if (ret == NULL) {
2465                 PyErr_NoMemory();
2466                 return NULL;
2467         }
2468         ret->mem_ctx = talloc_new(NULL);
2469         if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2470                 PyErr_NoMemory();
2471                 return NULL;
2472         }
2473         ret->el = el;
2474         return (PyObject *)ret;
2475 }
2476
2477 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2478 {
2479         PyObject *py_elements = NULL;
2480         struct ldb_message_element *el;
2481         unsigned int flags = 0;
2482         char *name = NULL;
2483         const char * const kwnames[] = { "elements", "flags", "name", NULL };
2484         PyLdbMessageElementObject *ret;
2485         TALLOC_CTX *mem_ctx;
2486
2487         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2488                                          discard_const_p(char *, kwnames),
2489                                          &py_elements, &flags, &name))
2490                 return NULL;
2491
2492         mem_ctx = talloc_new(NULL);
2493         if (mem_ctx == NULL) {
2494                 PyErr_NoMemory();
2495                 return NULL;
2496         }
2497
2498         el = talloc_zero(mem_ctx, struct ldb_message_element);
2499         if (el == NULL) {
2500                 PyErr_NoMemory();
2501                 talloc_free(mem_ctx);
2502                 return NULL;
2503         }
2504
2505         if (py_elements != NULL) {
2506                 Py_ssize_t i;
2507                 if (PyString_Check(py_elements)) {
2508                         el->num_values = 1;
2509                         el->values = talloc_array(el, struct ldb_val, 1);
2510                         if (el->values == NULL) {
2511                                 talloc_free(mem_ctx);
2512                                 PyErr_NoMemory();
2513                                 return NULL;
2514                         }
2515                         el->values[0].length = PyString_Size(py_elements);
2516                         el->values[0].data = talloc_memdup(el->values, 
2517                                 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2518                 } else if (PySequence_Check(py_elements)) {
2519                         el->num_values = PySequence_Size(py_elements);
2520                         el->values = talloc_array(el, struct ldb_val, el->num_values);
2521                         if (el->values == NULL) {
2522                                 talloc_free(mem_ctx);
2523                                 PyErr_NoMemory();
2524                                 return NULL;
2525                         }
2526                         for (i = 0; i < el->num_values; i++) {
2527                                 PyObject *item = PySequence_GetItem(py_elements, i);
2528                                 if (item == NULL) {
2529                                         talloc_free(mem_ctx);
2530                                         return NULL;
2531                                 }
2532                                 if (!PyString_Check(item)) {
2533                                         PyErr_Format(PyExc_TypeError, 
2534                                                      "Expected string as element %zd in list", i);
2535                                         talloc_free(mem_ctx);
2536                                         return NULL;
2537                                 }
2538                                 el->values[i].length = PyString_Size(item);
2539                                 el->values[i].data = talloc_memdup(el,
2540                                         (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2541                         }
2542                 } else {
2543                         PyErr_SetString(PyExc_TypeError, 
2544                                         "Expected string or list");
2545                         talloc_free(mem_ctx);
2546                         return NULL;
2547                 }
2548         }
2549
2550         el->flags = flags;
2551         el->name = talloc_strdup(el, name);
2552
2553         ret = PyObject_New(PyLdbMessageElementObject, type);
2554         if (ret == NULL) {
2555                 talloc_free(mem_ctx);
2556                 return NULL;
2557         }
2558
2559         ret->mem_ctx = mem_ctx;
2560         ret->el = el;
2561         return (PyObject *)ret;
2562 }
2563
2564 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2565 {
2566         char *element_str = NULL;
2567         Py_ssize_t i;
2568         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2569         PyObject *ret, *repr;
2570
2571         for (i = 0; i < el->num_values; i++) {
2572                 PyObject *o = py_ldb_msg_element_find(self, i);
2573                 repr = PyObject_Repr(o);
2574                 if (element_str == NULL)
2575                         element_str = talloc_strdup(NULL, PyString_AsString(repr));
2576                 else
2577                         element_str = talloc_asprintf_append(element_str, ",%s", PyString_AsString(repr));
2578                 Py_DECREF(repr);
2579         }
2580
2581         if (element_str != NULL) {
2582                 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2583                 talloc_free(element_str);
2584         } else {
2585                 ret = PyString_FromString("MessageElement([])");
2586         }
2587
2588         return ret;
2589 }
2590
2591 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2592 {
2593         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2594
2595         if (el->num_values == 1)
2596                 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2597         else
2598                 Py_RETURN_NONE;
2599 }
2600
2601 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2602 {
2603         talloc_free(self->mem_ctx);
2604         PyObject_Del(self);
2605 }
2606
2607 static PyTypeObject PyLdbMessageElement = {
2608         .tp_name = "ldb.MessageElement",
2609         .tp_basicsize = sizeof(PyLdbMessageElementObject),
2610         .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2611         .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2612         .tp_str = (reprfunc)py_ldb_msg_element_str,
2613         .tp_methods = py_ldb_msg_element_methods,
2614         .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2615         .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2616         .tp_as_sequence = &py_ldb_msg_element_seq,
2617         .tp_new = py_ldb_msg_element_new,
2618         .tp_flags = Py_TPFLAGS_DEFAULT,
2619         .tp_doc = "An element of a Message",
2620 };
2621
2622
2623 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2624 {
2625         PyObject *py_ldb;
2626         PyObject *py_dict;
2627         PyObject *py_ret;
2628         struct ldb_message *msg;
2629         struct ldb_context *ldb_ctx;
2630         unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2631
2632         if (!PyArg_ParseTuple(args, "O!O!|I",
2633                               &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2634                               &mod_flags)) {
2635                 return NULL;
2636         }
2637
2638         if (!PyLdb_Check(py_ldb)) {
2639                 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
2640                 return NULL;
2641         }
2642
2643         /* mask only flags we are going to use */
2644         mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2645         if (!mod_flags) {
2646                 PyErr_SetString(PyExc_ValueError,
2647                                 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2648                                 " expected as mod_flag value");
2649                 return NULL;
2650         }
2651
2652         ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2653
2654         msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2655         if (!msg) {
2656                 return NULL;
2657         }
2658
2659         py_ret = PyLdbMessage_FromMessage(msg);
2660
2661         talloc_unlink(ldb_ctx, msg);
2662
2663         return py_ret;
2664 }
2665
2666 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2667 {
2668         char *name;
2669         if (!PyArg_ParseTuple(args, "s", &name))
2670                 return NULL;
2671
2672         ldb_msg_remove_attr(self->msg, name);
2673
2674         Py_RETURN_NONE;
2675 }
2676
2677 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2678 {
2679         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2680         Py_ssize_t i, j = 0;
2681         PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2682         if (msg->dn != NULL) {
2683                 PyList_SetItem(obj, j, PyString_FromString("dn"));
2684                 j++;
2685         }
2686         for (i = 0; i < msg->num_elements; i++) {
2687                 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2688                 j++;
2689         }
2690         return obj;
2691 }
2692
2693 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2694 {
2695         struct ldb_message_element *el;
2696         char *name;
2697         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2698         if (!PyString_Check(py_name)) {
2699                 PyErr_SetNone(PyExc_TypeError);
2700                 return NULL;
2701         }
2702         name = PyString_AsString(py_name);
2703         if (!ldb_attr_cmp(name, "dn"))
2704                 return pyldb_Dn_FromDn(msg->dn);
2705         el = ldb_msg_find_element(msg, name);
2706         if (el == NULL) {
2707                 return NULL;
2708         }
2709         return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2710 }
2711
2712 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2713 {
2714         PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2715         if (ret == NULL) {
2716                 PyErr_SetString(PyExc_KeyError, "No such element");
2717                 return NULL;
2718         }
2719         return ret;
2720 }
2721
2722 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
2723 {
2724         PyObject *def = NULL;
2725         const char *kwnames[] = { "name", "default", "idx", NULL };
2726         const char *name = NULL;
2727         int idx = -1;
2728         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2729         struct ldb_message_element *el;
2730
2731         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
2732                                          discard_const_p(char *, kwnames), &name, &def, &idx)) {
2733                 return NULL;
2734         }
2735
2736         if (strcasecmp(name, "dn") == 0) {
2737                 return pyldb_Dn_FromDn(msg->dn);
2738         }
2739
2740         el = ldb_msg_find_element(msg, name);
2741
2742         if (el == NULL || (idx != -1 && el->num_values <= idx)) {
2743                 if (def != NULL) {
2744                         return def;
2745                 }
2746                 Py_RETURN_NONE;
2747         }
2748
2749         if (idx == -1) {
2750                 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2751         }
2752
2753         return PyObject_FromLdbValue(&el->values[idx]);
2754 }
2755
2756 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2757 {
2758         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2759         Py_ssize_t i, j = 0;
2760         PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2761         if (msg->dn != NULL) {
2762                 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2763                 j++;
2764         }
2765         for (i = 0; i < msg->num_elements; i++, j++) {
2766                 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2767                 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2768                 PyList_SetItem(l, j, value);
2769         }
2770         return l;
2771 }
2772
2773 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2774 {
2775         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2776         Py_ssize_t i = 0;
2777         PyObject *l = PyList_New(msg->num_elements);
2778         for (i = 0; i < msg->num_elements; i++) {
2779                 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2780         }
2781         return l;
2782 }
2783
2784 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2785 {
2786         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2787         PyLdbMessageElementObject *py_element;
2788         int i, ret;
2789         struct ldb_message_element *el;
2790         struct ldb_message_element *el_new;
2791
2792         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2793                 return NULL;
2794
2795         el = py_element->el;
2796         if (el == NULL) {
2797                 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
2798                 return NULL;
2799         }
2800
2801         ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
2802         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2803
2804         /* now deep copy all attribute values */
2805         el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
2806         if (el_new->values == NULL) {
2807                 PyErr_NoMemory();
2808                 return NULL;
2809         }
2810         el_new->num_values = el->num_values;
2811
2812         for (i = 0; i < el->num_values; i++) {
2813                 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
2814                 if (el_new->values[i].data == NULL
2815                                 && el->values[i].length != 0) {
2816                         PyErr_NoMemory();
2817                         return NULL;
2818                 }
2819         }
2820
2821         Py_RETURN_NONE;
2822 }
2823
2824 static PyMethodDef py_ldb_msg_methods[] = {
2825         { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2826                 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2827                 "Class method to create ldb.Message object from Dictionary.\n"
2828                 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2829         { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, 
2830                 "S.keys() -> list\n\n"
2831                 "Return sequence of all attribute names." },
2832         { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, 
2833                 "S.remove(name)\n\n"
2834                 "Remove all entries for attributes with the specified name."},
2835         { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
2836           "msg.get(name,default=None,idx=None) -> string\n"
2837           "idx is the index into the values array\n"
2838           "if idx is None, then a list is returned\n"
2839           "if idx is not None, then the element with that index is returned\n"
2840           "if you pass the special name 'dn' then the DN object is returned\n"},
2841         { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2842         { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2843         { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2844                 "S.add(element)\n\n"
2845                 "Add an element to this message." },
2846         { NULL },
2847 };
2848
2849 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2850 {
2851         PyObject *list, *iter;
2852
2853         list = py_ldb_msg_keys(self);
2854         iter = PyObject_GetIter(list);
2855         Py_DECREF(list);
2856         return iter;
2857 }
2858
2859 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2860 {
2861         char *attr_name;
2862
2863         if (!PyString_Check(name)) {
2864                 PyErr_SetNone(PyExc_TypeError);
2865                 return -1;
2866         }
2867
2868         attr_name = PyString_AsString(name);
2869         if (value == NULL) {
2870                 /* delitem */
2871                 ldb_msg_remove_attr(self->msg, attr_name);
2872         } else {
2873                 int ret;
2874                 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2875                                                                            value, 0, attr_name);
2876                 if (el == NULL) {
2877                         return -1;
2878                 }
2879                 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2880                 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2881                 if (ret != LDB_SUCCESS) {
2882                         PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
2883                         return -1;
2884                 }
2885         }
2886         return 0;
2887 }
2888
2889 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2890 {
2891         return pyldb_Message_AsMessage(self)->num_elements;
2892 }
2893
2894 static PyMappingMethods py_ldb_msg_mapping = {
2895         .mp_length = (lenfunc)py_ldb_msg_length,
2896         .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2897         .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2898 };
2899
2900 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2901 {
2902         const char * const kwnames[] = { "dn", NULL };
2903         struct ldb_message *ret;
2904         TALLOC_CTX *mem_ctx;
2905         PyObject *pydn = NULL;
2906         PyLdbMessageObject *py_ret;
2907
2908         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2909                                          discard_const_p(char *, kwnames),
2910                                          &pydn))
2911                 return NULL;
2912
2913         mem_ctx = talloc_new(NULL);
2914         if (mem_ctx == NULL) {
2915                 PyErr_NoMemory();
2916                 return NULL;
2917         }
2918
2919         ret = ldb_msg_new(mem_ctx);
2920         if (ret == NULL) {
2921                 talloc_free(mem_ctx);
2922                 PyErr_NoMemory();
2923                 return NULL;
2924         }
2925
2926         if (pydn != NULL) {
2927                 struct ldb_dn *dn;
2928                 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2929                         talloc_free(mem_ctx);
2930                         return NULL;
2931                 }
2932                 ret->dn = talloc_reference(ret, dn);
2933         }
2934
2935         py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2936         if (py_ret == NULL) {
2937                 PyErr_NoMemory();
2938                 talloc_free(mem_ctx);
2939                 return NULL;
2940         }
2941
2942         py_ret->mem_ctx = mem_ctx;
2943         py_ret->msg = ret;
2944         return (PyObject *)py_ret;
2945 }
2946
2947 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2948 {
2949         PyLdbMessageObject *ret;
2950
2951         ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2952         if (ret == NULL) {
2953                 PyErr_NoMemory();
2954                 return NULL;
2955         }
2956         ret->mem_ctx = talloc_new(NULL);
2957         ret->msg = talloc_reference(ret->mem_ctx, msg);
2958         return (PyObject *)ret;
2959 }
2960
2961 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2962 {
2963         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2964         return pyldb_Dn_FromDn(msg->dn);
2965 }
2966
2967 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2968 {
2969         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2970         if (!pyldb_Dn_Check(value)) {
2971                 PyErr_SetNone(PyExc_TypeError);
2972                 return -1;
2973         }
2974
2975         msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2976         return 0;
2977 }
2978
2979 static PyGetSetDef py_ldb_msg_getset[] = {
2980         { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2981         { NULL }
2982 };
2983
2984 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2985 {
2986         PyObject *dict = PyDict_New(), *ret;
2987         if (PyDict_Update(dict, (PyObject *)self) != 0)
2988                 return NULL;
2989         ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2990         Py_DECREF(dict);
2991         return ret;
2992 }
2993
2994 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2995 {
2996         talloc_free(self->mem_ctx);
2997         PyObject_Del(self);
2998 }
2999
3000 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
3001                               PyLdbMessageObject *py_msg2)
3002 {
3003         struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
3004                            *msg2 = pyldb_Message_AsMessage(py_msg2);
3005         unsigned int i;
3006         int ret;
3007
3008         if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3009                 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3010                 if (ret != 0) {
3011                         return SIGN(ret);
3012                 }
3013         }
3014
3015         ret = msg1->num_elements - msg2->num_elements;
3016         if (ret != 0) {
3017                 return SIGN(ret);
3018         }
3019
3020         for (i = 0; i < msg1->num_elements; i++) {
3021                 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3022                                                    &msg2->elements[i]);
3023                 if (ret != 0) {
3024                         return SIGN(ret);
3025                 }
3026
3027                 ret = ldb_msg_element_compare(&msg1->elements[i],
3028                                               &msg2->elements[i]);
3029                 if (ret != 0) {
3030                         return SIGN(ret);
3031                 }
3032         }
3033
3034         return 0;
3035 }
3036
3037 static PyTypeObject PyLdbMessage = {
3038         .tp_name = "ldb.Message",
3039         .tp_methods = py_ldb_msg_methods,
3040         .tp_getset = py_ldb_msg_getset,
3041         .tp_as_mapping = &py_ldb_msg_mapping,
3042         .tp_basicsize = sizeof(PyLdbMessageObject),
3043         .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3044         .tp_new = py_ldb_msg_new,
3045         .tp_repr = (reprfunc)py_ldb_msg_repr,
3046         .tp_flags = Py_TPFLAGS_DEFAULT,
3047         .tp_iter = (getiterfunc)py_ldb_msg_iter,
3048         .tp_compare = (cmpfunc)py_ldb_msg_compare,
3049         .tp_doc = "A LDB Message",
3050 };
3051
3052 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3053 {
3054         PyLdbTreeObject *ret;
3055
3056         ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3057         if (ret == NULL) {
3058                 PyErr_NoMemory();
3059                 return NULL;
3060         }
3061
3062         ret->mem_ctx = talloc_new(NULL);
3063         ret->tree = talloc_reference(ret->mem_ctx, tree);
3064         return (PyObject *)ret;
3065 }
3066
3067 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3068 {
3069         talloc_free(self->mem_ctx);
3070         PyObject_Del(self);
3071 }
3072
3073 static PyTypeObject PyLdbTree = {
3074         .tp_name = "ldb.Tree",
3075         .tp_basicsize = sizeof(PyLdbTreeObject),
3076         .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3077         .tp_flags = Py_TPFLAGS_DEFAULT,
3078         .tp_doc = "A search tree",
3079 };
3080
3081 /* Ldb_module */
3082 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3083 {
3084         PyObject *py_ldb = (PyObject *)mod->private_data;
3085         PyObject *py_result, *py_base, *py_attrs, *py_tree;
3086
3087         py_base = pyldb_Dn_FromDn(req->op.search.base);
3088
3089         if (py_base == NULL)
3090                 return LDB_ERR_OPERATIONS_ERROR;
3091
3092         py_tree = PyLdbTree_FromTree(req->op.search.tree);
3093
3094         if (py_tree == NULL)
3095                 return LDB_ERR_OPERATIONS_ERROR;
3096
3097         if (req->op.search.attrs == NULL) {
3098                 py_attrs = Py_None;
3099         } else {
3100                 int i, len;
3101                 for (len = 0; req->op.search.attrs[len]; len++);
3102                 py_attrs = PyList_New(len);
3103                 for (i = 0; i < len; i++)
3104                         PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
3105         }
3106
3107         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3108                                         discard_const_p(char, "OiOO"),
3109                                         py_base, req->op.search.scope, py_tree, py_attrs);
3110
3111         Py_DECREF(py_attrs);
3112         Py_DECREF(py_tree);
3113         Py_DECREF(py_base);
3114
3115         if (py_result == NULL) {
3116                 return LDB_ERR_PYTHON_EXCEPTION;
3117         }
3118
3119         req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3120         if (req->op.search.res == NULL) {
3121                 return LDB_ERR_PYTHON_EXCEPTION;
3122         }
3123
3124         Py_DECREF(py_result);
3125
3126         return LDB_SUCCESS;
3127 }
3128
3129 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3130 {
3131         PyObject *py_ldb = (PyObject *)mod->private_data;
3132         PyObject *py_result, *py_msg;
3133
3134         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3135
3136         if (py_msg == NULL) {
3137                 return LDB_ERR_OPERATIONS_ERROR;
3138         }
3139
3140         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3141                                         discard_const_p(char, "O"),
3142                                         py_msg);
3143
3144         Py_DECREF(py_msg);
3145
3146         if (py_result == NULL) {
3147                 return LDB_ERR_PYTHON_EXCEPTION;
3148         }
3149
3150         Py_DECREF(py_result);
3151
3152         return LDB_SUCCESS;
3153 }
3154
3155 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3156 {
3157         PyObject *py_ldb = (PyObject *)mod->private_data;
3158         PyObject *py_result, *py_msg;
3159
3160         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3161
3162         if (py_msg == NULL) {
3163                 return LDB_ERR_OPERATIONS_ERROR;
3164         }
3165
3166         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3167                                         discard_const_p(char, "O"),
3168                                         py_msg);
3169
3170         Py_DECREF(py_msg);
3171
3172         if (py_result == NULL) {
3173                 return LDB_ERR_PYTHON_EXCEPTION;
3174         }
3175
3176         Py_DECREF(py_result);
3177
3178         return LDB_SUCCESS;
3179 }
3180
3181 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3182 {
3183         PyObject *py_ldb = (PyObject *)mod->private_data;
3184         PyObject *py_result, *py_dn;
3185
3186         py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3187
3188         if (py_dn == NULL)
3189                 return LDB_ERR_OPERATIONS_ERROR;
3190
3191         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3192                                         discard_const_p(char, "O"),
3193                                         py_dn);
3194
3195         if (py_result == NULL) {
3196                 return LDB_ERR_PYTHON_EXCEPTION;
3197         }
3198
3199         Py_DECREF(py_result);
3200
3201         return LDB_SUCCESS;
3202 }
3203
3204 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3205 {
3206         PyObject *py_ldb = (PyObject *)mod->private_data;
3207         PyObject *py_result, *py_olddn, *py_newdn;
3208
3209         py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3210
3211         if (py_olddn == NULL)
3212                 return LDB_ERR_OPERATIONS_ERROR;
3213
3214         py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3215
3216         if (py_newdn == NULL)
3217                 return LDB_ERR_OPERATIONS_ERROR;
3218
3219         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3220                                         discard_const_p(char, "OO"),
3221                                         py_olddn, py_newdn);
3222
3223         Py_DECREF(py_olddn);
3224         Py_DECREF(py_newdn);
3225
3226         if (py_result == NULL) {
3227                 return LDB_ERR_PYTHON_EXCEPTION;
3228         }
3229
3230         Py_DECREF(py_result);
3231
3232         return LDB_SUCCESS;
3233 }
3234
3235 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3236 {
3237         PyObject *py_ldb = (PyObject *)mod->private_data;
3238         PyObject *py_result;
3239
3240         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3241                                         discard_const_p(char, ""));
3242
3243         Py_XDECREF(py_result);
3244
3245         return LDB_ERR_OPERATIONS_ERROR;
3246 }
3247
3248 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3249 {
3250         PyObject *py_ldb = (PyObject *)mod->private_data;
3251         PyObject *py_result;
3252
3253         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3254                                         discard_const_p(char, ""));
3255
3256         Py_XDECREF(py_result);
3257
3258         return LDB_ERR_OPERATIONS_ERROR;
3259 }
3260
3261 static int py_module_start_transaction(struct ldb_module *mod)
3262 {
3263         PyObject *py_ldb = (PyObject *)mod->private_data;
3264         PyObject *py_result;
3265
3266         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3267                                         discard_const_p(char, ""));
3268
3269         if (py_result == NULL) {
3270                 return LDB_ERR_PYTHON_EXCEPTION;
3271         }
3272
3273         Py_DECREF(py_result);
3274
3275         return LDB_SUCCESS;
3276 }
3277
3278 static int py_module_end_transaction(struct ldb_module *mod)
3279 {
3280         PyObject *py_ldb = (PyObject *)mod->private_data;
3281         PyObject *py_result;
3282
3283         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3284                                         discard_const_p(char, ""));
3285
3286         if (py_result == NULL) {
3287                 return LDB_ERR_PYTHON_EXCEPTION;
3288         }
3289
3290         Py_DECREF(py_result);
3291
3292         return LDB_SUCCESS;
3293 }
3294
3295 static int py_module_del_transaction(struct ldb_module *mod)
3296 {
3297         PyObject *py_ldb = (PyObject *)mod->private_data;
3298         PyObject *py_result;
3299
3300         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3301                                         discard_const_p(char, ""));
3302
3303         if (py_result == NULL) {
3304                 return LDB_ERR_PYTHON_EXCEPTION;
3305         }
3306
3307         Py_DECREF(py_result);
3308
3309         return LDB_SUCCESS;
3310 }
3311
3312 static int py_module_destructor(struct ldb_module *mod)
3313 {
3314         Py_DECREF((PyObject *)mod->private_data);
3315         return 0;
3316 }
3317
3318 static int py_module_init(struct ldb_module *mod)
3319 {
3320         PyObject *py_class = (PyObject *)mod->ops->private_data;
3321         PyObject *py_result, *py_next, *py_ldb;
3322
3323         py_ldb = PyLdb_FromLdbContext(mod->ldb);
3324
3325         if (py_ldb == NULL)
3326                 return LDB_ERR_OPERATIONS_ERROR;
3327
3328         py_next = PyLdbModule_FromModule(mod->next);
3329
3330         if (py_next == NULL)
3331                 return LDB_ERR_OPERATIONS_ERROR;
3332
3333         py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3334                                           py_ldb, py_next);
3335
3336         if (py_result == NULL) {
3337                 return LDB_ERR_PYTHON_EXCEPTION;
3338         }
3339
3340         mod->private_data = py_result;
3341
3342         talloc_set_destructor(mod, py_module_destructor);
3343
3344         return ldb_next_init(mod);
3345 }
3346
3347 static PyObject *py_register_module(PyObject *module, PyObject *args)
3348 {
3349         int ret;
3350         struct ldb_module_ops *ops;
3351         PyObject *input;
3352
3353         if (!PyArg_ParseTuple(args, "O", &input))
3354                 return NULL;
3355
3356         ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3357         if (ops == NULL) {
3358                 PyErr_NoMemory();
3359                 return NULL;
3360         }
3361
3362         ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3363
3364         Py_INCREF(input);
3365         ops->private_data = input;
3366         ops->init_context = py_module_init;
3367         ops->search = py_module_search;
3368         ops->add = py_module_add;
3369         ops->modify = py_module_modify;
3370         ops->del = py_module_del;
3371         ops->rename = py_module_rename;
3372         ops->request = py_module_request;
3373         ops->extended = py_module_extended;
3374         ops->start_transaction = py_module_start_transaction;
3375         ops->end_transaction = py_module_end_transaction;
3376         ops->del_transaction = py_module_del_transaction;
3377
3378         ret = ldb_register_module(ops);
3379
3380         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3381
3382         Py_RETURN_NONE;
3383 }
3384
3385 static PyObject *py_timestring(PyObject *module, PyObject *args)
3386 {
3387         /* most times "time_t" is a signed integer type with 32 or 64 bit:
3388          * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3389         long int t_val;
3390         char *tresult;
3391         PyObject *ret;
3392         if (!PyArg_ParseTuple(args, "l", &t_val))
3393                 return NULL;
3394         tresult = ldb_timestring(NULL, (time_t) t_val);
3395         ret = PyString_FromString(tresult);
3396         talloc_free(tresult);
3397         return ret;
3398 }
3399
3400 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3401 {
3402         char *str;
3403         if (!PyArg_ParseTuple(args, "s", &str))
3404                 return NULL;
3405
3406         return PyInt_FromLong(ldb_string_to_time(str));
3407 }
3408
3409 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3410 {
3411         char *name;
3412         if (!PyArg_ParseTuple(args, "s", &name))
3413                 return NULL;
3414         return PyBool_FromLong(ldb_valid_attr_name(name));
3415 }
3416
3417 /*
3418   encode a string using RFC2254 rules
3419  */
3420 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3421 {
3422         char *str, *encoded;
3423         int size = 0;
3424         struct ldb_val val;
3425         PyObject *ret;
3426
3427         if (!PyArg_ParseTuple(args, "s#", &str, &size))
3428                 return NULL;
3429         val.data = (uint8_t *)str;
3430         val.length = size;
3431
3432         encoded = ldb_binary_encode(NULL, val);
3433         if (encoded == NULL) {
3434                 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3435                 return NULL;
3436         }
3437         ret = PyString_FromString(encoded);
3438         talloc_free(encoded);
3439         return ret;
3440 }
3441
3442 /*
3443   decode a string using RFC2254 rules
3444  */
3445 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3446 {
3447         char *str;
3448         struct ldb_val val;
3449         PyObject *ret;
3450
3451         if (!PyArg_ParseTuple(args, "s", &str))
3452                 return NULL;
3453
3454         val = ldb_binary_decode(NULL, str);
3455         if (val.data == NULL) {
3456                 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3457                 return NULL;
3458         }
3459         ret = Py_BuildValue("s#", val.data, val.length);
3460         talloc_free(val.data);
3461         return ret;
3462 }
3463
3464 static PyMethodDef py_ldb_global_methods[] = {
3465         { "register_module", py_register_module, METH_VARARGS, 
3466                 "S.register_module(module) -> None\n\n"
3467                 "Register a LDB module."},
3468         { "timestring", py_timestring, METH_VARARGS, 
3469                 "S.timestring(int) -> string\n\n"
3470                 "Generate a LDAP time string from a UNIX timestamp" },
3471         { "string_to_time", py_string_to_time, METH_VARARGS,
3472                 "S.string_to_time(string) -> int\n\n"
3473                 "Parse a LDAP time string into a UNIX timestamp." },
3474         { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3475                 "S.valid_attr_name(name) -> bool\n\nn"
3476                 "Check whether the supplied name is a valid attribute name." },
3477         { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3478                 "S.open() -> Ldb\n\n"
3479                 "Open a new LDB context." },
3480         { "binary_encode", py_binary_encode, METH_VARARGS,
3481                 "S.binary_encode(string) -> string\n\n"
3482                 "Perform a RFC2254 binary encoding on a string" },
3483         { "binary_decode", py_binary_decode, METH_VARARGS,
3484                 "S.binary_decode(string) -> string\n\n"
3485                 "Perform a RFC2254 binary decode on a string" },
3486         { NULL }
3487 };
3488
3489 void initldb(void)
3490 {
3491         PyObject *m;
3492
3493         if (PyType_Ready(&PyLdbDn) < 0)
3494                 return;
3495
3496         if (PyType_Ready(&PyLdbMessage) < 0)
3497                 return;
3498
3499         if (PyType_Ready(&PyLdbMessageElement) < 0)
3500                 return;
3501
3502         if (PyType_Ready(&PyLdb) < 0)
3503                 return;
3504
3505         if (PyType_Ready(&PyLdbModule) < 0)
3506                 return;
3507
3508         if (PyType_Ready(&PyLdbTree) < 0)
3509                 return;
3510
3511         if (PyType_Ready(&PyLdbResult) < 0)
3512                 return;
3513
3514         if (PyType_Ready(&PyLdbControl) < 0)
3515                 return;
3516
3517         m = Py_InitModule3("ldb", py_ldb_global_methods, 
3518                 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3519         if (m == NULL)
3520                 return;
3521
3522         PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3523         PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3524         PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3525         PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3526         PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3527         PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3528         PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3529
3530         PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3531         PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3532         PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3533         PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3534
3535         PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3536         PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3537         PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3538
3539         PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3540         PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3541         PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3542         PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3543         PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3544         PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3545         PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3546         PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3547         PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3548         PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3549         PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3550         PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3551         PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3552         PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3553         PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3554         PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3555         PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3556         PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3557         PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3558         PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3559         PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3560         PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3561         PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3562         PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3563         PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3564         PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3565         PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3566         PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3567         PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3568         PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3569         PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3570         PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3571         PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3572         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3573         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3574         PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3575         PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3576         PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3577         PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3578
3579         PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3580         PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3581         PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3582         PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3583
3584         PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3585
3586         PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3587         PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3588
3589         Py_INCREF(&PyLdb);
3590         Py_INCREF(&PyLdbDn);
3591         Py_INCREF(&PyLdbModule);
3592         Py_INCREF(&PyLdbMessage);
3593         Py_INCREF(&PyLdbMessageElement);
3594         Py_INCREF(&PyLdbTree);
3595         Py_INCREF(&PyLdbResult);
3596         Py_INCREF(&PyLdbControl);
3597
3598         PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3599         PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3600         PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3601         PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3602         PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3603         PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3604         PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3605
3606         PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3607
3608 #define ADD_LDB_STRING(val)  PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3609
3610         ADD_LDB_STRING(SYNTAX_DN);
3611         ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3612         ADD_LDB_STRING(SYNTAX_INTEGER);
3613         ADD_LDB_STRING(SYNTAX_BOOLEAN);
3614         ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3615         ADD_LDB_STRING(SYNTAX_UTC_TIME);
3616         ADD_LDB_STRING(OID_COMPARATOR_AND);
3617         ADD_LDB_STRING(OID_COMPARATOR_OR);
3618 }