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