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