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