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