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