pyldb: Expose extra flags
[sfrench/samba-autobuild/.git] / lib / ldb / pyldb.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Python interface to ldb.
5
6    Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7    Copyright (C) 2006 Simo Sorce <idra@samba.org>
8    Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9    Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10    Copyright (C) 2009-2011 Andrew Tridgell
11    Copyright (C) 2009-2011 Andrew Bartlett
12
13     ** NOTE! The following LGPL license applies to the ldb
14     ** library. This does NOT imply that all of Samba is released
15     ** under the LGPL
16
17    This library is free software; you can redistribute it and/or
18    modify it under the terms of the GNU Lesser General Public
19    License as published by the Free Software Foundation; either
20    version 3 of the License, or (at your option) any later version.
21
22    This library is distributed in the hope that it will be useful,
23    but WITHOUT ANY WARRANTY; without even the implied warranty of
24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25    Lesser General Public License for more details.
26
27    You should have received a copy of the GNU Lesser General Public
28    License along with this library; if not, see <http://www.gnu.org/licenses/>.
29 */
30
31 #include <Python.h>
32 #include "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 = NULL;
514         Py_ssize_t size = 0;
515
516         if (!PyArg_ParseTuple(args, "sz#", &name, (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         struct ldb_dn *last_dn = NULL;
1673
1674         TALLOC_CTX *mem_ctx;
1675
1676         if (!PyArg_ParseTuple(args, "s", &s))
1677                 return NULL;
1678
1679         mem_ctx = talloc_new(NULL);
1680         if (!mem_ctx) {
1681                 Py_RETURN_NONE;
1682         }
1683
1684         list = PyList_New(0);
1685         while (s && *s != '\0') {
1686                 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1687                 talloc_steal(mem_ctx, ldif);
1688                 if (ldif) {
1689                         PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1690                         last_dn = ldif->msg->dn;
1691                 } else {
1692                         const char *last_dn_str = NULL;
1693                         const char *err_string = NULL;
1694                         if (last_dn == NULL) {
1695                                 PyErr_SetString(PyExc_ValueError,
1696                                                 "unable to parse LDIF "
1697                                                 "string at first chunk");
1698                                 talloc_free(mem_ctx);
1699                                 return NULL;
1700                         }
1701
1702                         last_dn_str
1703                                 = ldb_dn_get_linearized(last_dn);
1704
1705                         err_string
1706                                 = talloc_asprintf(mem_ctx,
1707                                                   "unable to parse ldif "
1708                                                   "string AFTER %s",
1709                                                   last_dn_str);
1710
1711                         PyErr_SetString(PyExc_ValueError,
1712                                         err_string);
1713                         talloc_free(mem_ctx);
1714                         return NULL;
1715                 }
1716         }
1717         talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1718         ret = PyObject_GetIter(list);
1719         Py_DECREF(list);
1720         return ret;
1721 }
1722
1723 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1724 {
1725         int ldb_ret;
1726         PyObject *py_msg_old;
1727         PyObject *py_msg_new;
1728         struct ldb_message *diff;
1729         struct ldb_context *ldb;
1730         PyObject *py_ret;
1731
1732         if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1733                 return NULL;
1734
1735         if (!PyLdbMessage_Check(py_msg_old)) {
1736                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1737                 return NULL;
1738         }
1739
1740         if (!PyLdbMessage_Check(py_msg_new)) {
1741                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1742                 return NULL;
1743         }
1744
1745         ldb = pyldb_Ldb_AsLdbContext(self);
1746         ldb_ret = ldb_msg_difference(ldb, ldb,
1747                                      pyldb_Message_AsMessage(py_msg_old),
1748                                      pyldb_Message_AsMessage(py_msg_new),
1749                                      &diff);
1750         if (ldb_ret != LDB_SUCCESS) {
1751                 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1752                 return NULL;
1753         }
1754
1755         py_ret = PyLdbMessage_FromMessage(diff);
1756
1757         talloc_unlink(ldb, diff);
1758
1759         return py_ret;
1760 }
1761
1762 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1763 {
1764         const struct ldb_schema_attribute *a;
1765         struct ldb_val old_val;
1766         struct ldb_val new_val;
1767         TALLOC_CTX *mem_ctx;
1768         PyObject *ret;
1769         char *element_name;
1770         PyObject *val;
1771         Py_ssize_t size;
1772         int result;
1773
1774         if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1775                 return NULL;
1776
1777         result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1778         old_val.length = size;
1779
1780         if (result != 0) {
1781                 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1782                 return NULL;
1783         }
1784
1785         a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1786
1787         if (a == NULL) {
1788                 Py_RETURN_NONE;
1789         }
1790
1791         mem_ctx = talloc_new(NULL);
1792         if (mem_ctx == NULL) {
1793                 PyErr_NoMemory();
1794                 return NULL;
1795         }
1796
1797         if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1798                 talloc_free(mem_ctx);
1799                 Py_RETURN_NONE;
1800         }
1801
1802         ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1803
1804         talloc_free(mem_ctx);
1805
1806         return ret;
1807 }
1808
1809 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1810 {
1811         PyObject *py_base = Py_None;
1812         int scope = LDB_SCOPE_DEFAULT;
1813         char *expr = NULL;
1814         PyObject *py_attrs = Py_None;
1815         PyObject *py_controls = Py_None;
1816         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1817         int ret;
1818         struct ldb_result *res;
1819         struct ldb_request *req;
1820         const char **attrs;
1821         struct ldb_context *ldb_ctx;
1822         struct ldb_control **parsed_controls;
1823         struct ldb_dn *base;
1824         PyObject *py_ret;
1825         TALLOC_CTX *mem_ctx;
1826
1827         /* type "int" rather than "enum" for "scope" is intentional */
1828         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1829                                          discard_const_p(char *, kwnames),
1830                                          &py_base, &scope, &expr, &py_attrs, &py_controls))
1831                 return NULL;
1832
1833
1834         mem_ctx = talloc_new(NULL);
1835         if (mem_ctx == NULL) {
1836                 PyErr_NoMemory();
1837                 return NULL;
1838         }
1839         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1840
1841         if (py_attrs == Py_None) {
1842                 attrs = NULL;
1843         } else {
1844                 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1845                 if (attrs == NULL) {
1846                         talloc_free(mem_ctx);
1847                         return NULL;
1848                 }
1849         }
1850
1851         if (py_base == Py_None) {
1852                 base = ldb_get_default_basedn(ldb_ctx);
1853         } else {
1854                 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1855                         talloc_free(mem_ctx);
1856                         return NULL;
1857                 }
1858         }
1859
1860         if (py_controls == Py_None) {
1861                 parsed_controls = NULL;
1862         } else {
1863                 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1864                 if (controls == NULL) {
1865                         talloc_free(mem_ctx);
1866                         return NULL;
1867                 }
1868                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1869                 talloc_free(controls);
1870         }
1871
1872         res = talloc_zero(mem_ctx, struct ldb_result);
1873         if (res == NULL) {
1874                 PyErr_NoMemory();
1875                 talloc_free(mem_ctx);
1876                 return NULL;
1877         }
1878
1879         ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1880                                    base,
1881                                    scope,
1882                                    expr,
1883                                    attrs,
1884                                    parsed_controls,
1885                                    res,
1886                                    ldb_search_default_callback,
1887                                    NULL);
1888
1889         if (ret != LDB_SUCCESS) {
1890                 talloc_free(mem_ctx);
1891                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1892                 return NULL;
1893         }
1894
1895         talloc_steal(req, attrs);
1896
1897         ret = ldb_request(ldb_ctx, req);
1898
1899         if (ret == LDB_SUCCESS) {
1900                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1901         }
1902
1903         if (ret != LDB_SUCCESS) {
1904                 talloc_free(mem_ctx);
1905                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1906                 return NULL;
1907         }
1908
1909         py_ret = PyLdbResult_FromResult(res);
1910
1911         talloc_free(mem_ctx);
1912
1913         return py_ret;
1914 }
1915
1916 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
1917 {
1918         if (reply->py_iter != NULL) {
1919                 DLIST_REMOVE(reply->py_iter->state.next, reply);
1920                 if (reply->py_iter->state.result == reply) {
1921                         reply->py_iter->state.result = NULL;
1922                 }
1923                 reply->py_iter = NULL;
1924         }
1925
1926         if (reply->obj != NULL) {
1927                 Py_DECREF(reply->obj);
1928                 reply->obj = NULL;
1929         }
1930
1931         return 0;
1932 }
1933
1934 static int py_ldb_search_iterator_callback(struct ldb_request *req,
1935                                            struct ldb_reply *ares)
1936 {
1937         PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
1938         struct ldb_result result = { .msgs = NULL };
1939         struct py_ldb_search_iterator_reply *reply = NULL;
1940
1941         if (ares == NULL) {
1942                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1943         }
1944
1945         if (ares->error != LDB_SUCCESS) {
1946                 int ret = ares->error;
1947                 TALLOC_FREE(ares);
1948                 return ldb_request_done(req, ret);
1949         }
1950
1951         reply = talloc_zero(py_iter->mem_ctx,
1952                             struct py_ldb_search_iterator_reply);
1953         if (reply == NULL) {
1954                 TALLOC_FREE(ares);
1955                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1956         }
1957         reply->py_iter = py_iter;
1958         talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
1959
1960         switch (ares->type) {
1961         case LDB_REPLY_ENTRY:
1962                 reply->obj = PyLdbMessage_FromMessage(ares->message);
1963                 if (reply->obj == NULL) {
1964                         TALLOC_FREE(ares);
1965                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1966                 }
1967                 DLIST_ADD_END(py_iter->state.next, reply);
1968                 TALLOC_FREE(ares);
1969                 return LDB_SUCCESS;
1970
1971         case LDB_REPLY_REFERRAL:
1972                 reply->obj = PyStr_FromString(ares->referral);
1973                 if (reply->obj == NULL) {
1974                         TALLOC_FREE(ares);
1975                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1976                 }
1977                 DLIST_ADD_END(py_iter->state.next, reply);
1978                 TALLOC_FREE(ares);
1979                 return LDB_SUCCESS;
1980
1981         case LDB_REPLY_DONE:
1982                 result = (struct ldb_result) { .controls = ares->controls };
1983                 reply->obj = PyLdbResult_FromResult(&result);
1984                 if (reply->obj == NULL) {
1985                         TALLOC_FREE(ares);
1986                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1987                 }
1988                 py_iter->state.result = reply;
1989                 TALLOC_FREE(ares);
1990                 return ldb_request_done(req, LDB_SUCCESS);
1991         }
1992
1993         TALLOC_FREE(ares);
1994         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1995 }
1996
1997 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1998 {
1999         PyObject *py_base = Py_None;
2000         int scope = LDB_SCOPE_DEFAULT;
2001         int timeout = 0;
2002         char *expr = NULL;
2003         PyObject *py_attrs = Py_None;
2004         PyObject *py_controls = Py_None;
2005         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
2006         int ret;
2007         const char **attrs;
2008         struct ldb_context *ldb_ctx;
2009         struct ldb_control **parsed_controls;
2010         struct ldb_dn *base;
2011         PyLdbSearchIteratorObject *py_iter;
2012
2013         /* type "int" rather than "enum" for "scope" is intentional */
2014         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
2015                                          discard_const_p(char *, kwnames),
2016                                          &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
2017                 return NULL;
2018
2019         py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
2020         if (py_iter == NULL) {
2021                 PyErr_NoMemory();
2022                 return NULL;
2023         }
2024         py_iter->ldb = self;
2025         Py_INCREF(self);
2026         ZERO_STRUCT(py_iter->state);
2027         py_iter->mem_ctx = talloc_new(NULL);
2028         if (py_iter->mem_ctx == NULL) {
2029                 Py_DECREF(py_iter);
2030                 PyErr_NoMemory();
2031                 return NULL;
2032         }
2033
2034         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2035
2036         if (py_attrs == Py_None) {
2037                 attrs = NULL;
2038         } else {
2039                 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2040                 if (attrs == NULL) {
2041                         Py_DECREF(py_iter);
2042                         PyErr_NoMemory();
2043                         return NULL;
2044                 }
2045         }
2046
2047         if (py_base == Py_None) {
2048                 base = ldb_get_default_basedn(ldb_ctx);
2049         } else {
2050                 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2051                         Py_DECREF(py_iter);
2052                         PyErr_NoMemory();
2053                         return NULL;
2054                 }
2055         }
2056
2057         if (py_controls == Py_None) {
2058                 parsed_controls = NULL;
2059         } else {
2060                 const char **controls = NULL;
2061
2062                 controls = PyList_AsStrList(py_iter->mem_ctx,
2063                                             py_controls, "controls");
2064                 if (controls == NULL) {
2065                         Py_DECREF(py_iter);
2066                         PyErr_NoMemory();
2067                         return NULL;
2068                 }
2069
2070                 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2071                                                             py_iter->mem_ctx,
2072                                                             controls);
2073                 if (controls[0] != NULL && parsed_controls == NULL) {
2074                         Py_DECREF(py_iter);
2075                         PyErr_NoMemory();
2076                         return NULL;
2077                 }
2078                 talloc_free(controls);
2079         }
2080
2081         ret = ldb_build_search_req(&py_iter->state.req,
2082                                    ldb_ctx,
2083                                    py_iter->mem_ctx,
2084                                    base,
2085                                    scope,
2086                                    expr,
2087                                    attrs,
2088                                    parsed_controls,
2089                                    py_iter,
2090                                    py_ldb_search_iterator_callback,
2091                                    NULL);
2092         if (ret != LDB_SUCCESS) {
2093                 Py_DECREF(py_iter);
2094                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2095                 return NULL;
2096         }
2097
2098         ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2099
2100         ret = ldb_request(ldb_ctx, py_iter->state.req);
2101         if (ret != LDB_SUCCESS) {
2102                 Py_DECREF(py_iter);
2103                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2104                 return NULL;
2105         }
2106
2107         return (PyObject *)py_iter;
2108 }
2109
2110 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2111 {
2112         char *name;
2113         void *data;
2114
2115         if (!PyArg_ParseTuple(args, "s", &name))
2116                 return NULL;
2117
2118         data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
2119
2120         if (data == NULL)
2121                 Py_RETURN_NONE;
2122
2123         /* FIXME: More interpretation */
2124
2125         Py_RETURN_TRUE;
2126 }
2127
2128 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2129 {
2130         char *name;
2131         PyObject *data;
2132
2133         if (!PyArg_ParseTuple(args, "sO", &name, &data))
2134                 return NULL;
2135
2136         /* FIXME: More interpretation */
2137
2138         ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
2139
2140         Py_RETURN_NONE;
2141 }
2142
2143 static PyObject *py_ldb_modules(PyLdbObject *self)
2144 {
2145         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2146         PyObject *ret = PyList_New(0);
2147         struct ldb_module *mod;
2148
2149         for (mod = ldb->modules; mod; mod = mod->next) {
2150                 PyList_Append(ret, PyLdbModule_FromModule(mod));
2151         }
2152
2153         return ret;
2154 }
2155
2156 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2157 {
2158         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2159         int type, ret;
2160         uint64_t value;
2161
2162         if (!PyArg_ParseTuple(args, "i", &type))
2163                 return NULL;
2164
2165         /* FIXME: More interpretation */
2166
2167         ret = ldb_sequence_number(ldb, type, &value);
2168
2169         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2170
2171         return PyLong_FromLongLong(value);
2172 }
2173
2174
2175 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2176         .name             = "TEST",
2177         .read_fn          = ldb_handler_copy,
2178         .write_clear_fn   = ldb_handler_copy,
2179         .write_hex_fn     = ldb_handler_copy,
2180 };
2181
2182 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self)
2183 {
2184         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2185         int ret;
2186
2187         ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2188
2189         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2190
2191         Py_RETURN_NONE;
2192 }
2193
2194
2195 static PyMethodDef py_ldb_methods[] = {
2196         { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, 
2197                 "S.set_debug(callback) -> None\n"
2198                 "Set callback for LDB debug messages.\n"
2199                 "The callback should accept a debug level and debug text." },
2200         { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, 
2201                 "S.set_create_perms(mode) -> None\n"
2202                 "Set mode to use when creating new LDB files." },
2203         { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2204                 "S.set_modules_dir(path) -> None\n"
2205                 "Set path LDB should search for modules" },
2206         { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, 
2207                 "S.transaction_start() -> None\n"
2208                 "Start a new transaction." },
2209         { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2210                 "S.transaction_prepare_commit() -> None\n"
2211                 "prepare to commit a new transaction (2-stage commit)." },
2212         { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, 
2213                 "S.transaction_commit() -> None\n"
2214                 "commit a new transaction." },
2215         { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, 
2216                 "S.transaction_cancel() -> None\n"
2217                 "cancel a new transaction." },
2218         { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, 
2219                 NULL },
2220         { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2221                 NULL },
2222         { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2223                 NULL },
2224         { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2225                 NULL },
2226         { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2227                 NULL },
2228         { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, 
2229                 "S.connect(url, flags=0, options=None) -> None\n"
2230                 "Connect to a LDB URL." },
2231         { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
2232                 "S.modify(message, controls=None, validate=False) -> None\n"
2233                 "Modify an entry." },
2234         { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
2235                 "S.add(message, controls=None) -> None\n"
2236                 "Add an entry." },
2237         { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
2238                 "S.delete(dn, controls=None) -> None\n"
2239                 "Remove an entry." },
2240         { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
2241                 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2242                 "Rename an entry." },
2243         { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
2244                 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2245                 "Search in a database.\n"
2246                 "\n"
2247                 ":param base: Optional base DN to search\n"
2248                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2249                 ":param expression: Optional search expression\n"
2250                 ":param attrs: Attributes to return (defaults to all)\n"
2251                 ":param controls: Optional list of controls\n"
2252                 ":return: ldb.Result object\n"
2253         },
2254         { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS,
2255                 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2256                 "Search in a database.\n"
2257                 "\n"
2258                 ":param base: Optional base DN to search\n"
2259                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2260                 ":param expression: Optional search expression\n"
2261                 ":param attrs: Attributes to return (defaults to all)\n"
2262                 ":param controls: Optional list of controls\n"
2263                 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2264                 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2265         },
2266         { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2267                 NULL },
2268         { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2269                 NULL },
2270         { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2271                 NULL },
2272         { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2273                 "S.parse_ldif(ldif) -> iter(messages)\n"
2274                 "Parse a string formatted using LDIF." },
2275         { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2276                 "S.write_ldif(message, changetype) -> ldif\n"
2277                 "Print the message as a string formatted using LDIF." },
2278         { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2279                 "S.msg_diff(Message) -> Message\n"
2280                 "Return an LDB Message of the difference between two Message objects." },
2281         { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2282                 "S.get_opaque(name) -> value\n"
2283                 "Get an opaque value set on this LDB connection. \n"
2284                 ":note: The returned value may not be useful in Python."
2285         },
2286         { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2287                 "S.set_opaque(name, value) -> None\n"
2288                 "Set an opaque value on this LDB connection. \n"
2289                 ":note: Passing incorrect values may cause crashes." },
2290         { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2291                 "S.modules() -> list\n"
2292                 "Return the list of modules on this LDB connection " },
2293         { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2294                 "S.sequence_number(type) -> value\n"
2295                 "Return the value of the sequence according to the requested type" },
2296         { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2297                 "S._register_test_extensions() -> None\n"
2298                 "Register internal extensions used in testing" },
2299         { NULL },
2300 };
2301
2302 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2303 {
2304         PyLdbModuleObject *ret;
2305
2306         ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2307         if (ret == NULL) {
2308                 PyErr_NoMemory();
2309                 return NULL;
2310         }
2311         ret->mem_ctx = talloc_new(NULL);
2312         ret->mod = talloc_reference(ret->mem_ctx, mod);
2313         return (PyObject *)ret;
2314 }
2315
2316 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2317 {
2318         struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2319         if (mod == NULL) {
2320                 Py_RETURN_NONE;
2321         }
2322         return PyLdbModule_FromModule(mod);
2323 }
2324
2325 static PyGetSetDef py_ldb_getset[] = {
2326         { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
2327         { NULL }
2328 };
2329
2330 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2331 {
2332         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2333         struct ldb_dn *dn;
2334         struct ldb_result *result;
2335         unsigned int count;
2336         int ret;
2337
2338         if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2339                 return -1;
2340         }
2341
2342         ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2343                          NULL);
2344         if (ret != LDB_SUCCESS) {
2345                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2346                 return -1;
2347         }
2348
2349         count = result->count;
2350
2351         talloc_free(result);
2352
2353         if (count > 1) {
2354                 PyErr_Format(PyExc_RuntimeError,
2355                              "Searching for [%s] dn gave %u results!",
2356                              ldb_dn_get_linearized(dn),
2357                              count);
2358                 return -1;
2359         }
2360
2361         return count;
2362 }
2363
2364 static PySequenceMethods py_ldb_seq = {
2365         .sq_contains = (objobjproc)py_ldb_contains,
2366 };
2367
2368 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2369 {
2370         PyLdbObject *ret;
2371
2372         ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2373         if (ret == NULL) {
2374                 PyErr_NoMemory();
2375                 return NULL;
2376         }
2377         ret->mem_ctx = talloc_new(NULL);
2378         ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2379         return (PyObject *)ret;
2380 }
2381
2382 static void py_ldb_dealloc(PyLdbObject *self)
2383 {
2384         talloc_free(self->mem_ctx);
2385         Py_TYPE(self)->tp_free(self);
2386 }
2387
2388 static PyTypeObject PyLdb = {
2389         .tp_name = "ldb.Ldb",
2390         .tp_methods = py_ldb_methods,
2391         .tp_repr = (reprfunc)py_ldb_repr,
2392         .tp_new = py_ldb_new,
2393         .tp_init = (initproc)py_ldb_init,
2394         .tp_dealloc = (destructor)py_ldb_dealloc,
2395         .tp_getset = py_ldb_getset,
2396         .tp_getattro = PyObject_GenericGetAttr,
2397         .tp_basicsize = sizeof(PyLdbObject),
2398         .tp_doc = "Connection to a LDB database.",
2399         .tp_as_sequence = &py_ldb_seq,
2400         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2401 };
2402
2403 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2404 {
2405         talloc_free(self->mem_ctx);
2406         Py_DECREF(self->msgs);
2407         Py_DECREF(self->referals);
2408         Py_DECREF(self->controls);
2409         Py_TYPE(self)->tp_free(self);
2410 }
2411
2412 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2413 {
2414         Py_INCREF(self->msgs);
2415         return self->msgs;
2416 }
2417
2418 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2419 {
2420         Py_INCREF(self->controls);
2421         return self->controls;
2422 }
2423
2424 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2425 {
2426         Py_INCREF(self->referals);
2427         return self->referals;
2428 }
2429
2430 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2431 {
2432         Py_ssize_t size;
2433         if (self->msgs == NULL) {
2434                 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2435                 return NULL;
2436         }
2437         size = PyList_Size(self->msgs);
2438         return PyInt_FromLong(size);
2439 }
2440
2441 static PyGetSetDef py_ldb_result_getset[] = {
2442         { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2443         { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2444         { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2445         { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2446         { NULL }
2447 };
2448
2449 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2450 {
2451         return PyObject_GetIter(self->msgs);
2452 }
2453
2454 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2455 {
2456         return PySequence_Size(self->msgs);
2457 }
2458
2459 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2460 {
2461         return PySequence_GetItem(self->msgs, idx);
2462 }
2463
2464 static PySequenceMethods py_ldb_result_seq = {
2465         .sq_length = (lenfunc)py_ldb_result_len,
2466         .sq_item = (ssizeargfunc)py_ldb_result_find,
2467 };
2468
2469 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2470 {
2471         return PyStr_FromString("<ldb result>");
2472 }
2473
2474
2475 static PyTypeObject PyLdbResult = {
2476         .tp_name = "ldb.Result",
2477         .tp_repr = (reprfunc)py_ldb_result_repr,
2478         .tp_dealloc = (destructor)py_ldb_result_dealloc,
2479         .tp_iter = (getiterfunc)py_ldb_result_iter,
2480         .tp_getset = py_ldb_result_getset,
2481         .tp_getattro = PyObject_GenericGetAttr,
2482         .tp_basicsize = sizeof(PyLdbResultObject),
2483         .tp_as_sequence = &py_ldb_result_seq,
2484         .tp_doc = "LDB result.",
2485         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2486 };
2487
2488 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2489 {
2490         Py_XDECREF(self->state.exception);
2491         TALLOC_FREE(self->mem_ctx);
2492         ZERO_STRUCT(self->state);
2493         Py_DECREF(self->ldb);
2494         Py_TYPE(self)->tp_free(self);
2495 }
2496
2497 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2498 {
2499         PyObject *py_ret = NULL;
2500
2501         if (self->state.req == NULL) {
2502                 PyErr_SetString(PyExc_RuntimeError,
2503                                 "ldb.SearchIterator request already finished");
2504                 return NULL;
2505         }
2506
2507         /*
2508          * TODO: do we want a non-blocking mode?
2509          * In future we may add an optional 'nonblocking'
2510          * argument to search_iterator().
2511          *
2512          * For now we keep it simple and wait for at
2513          * least one reply.
2514          */
2515
2516         while (self->state.next == NULL) {
2517                 int ret;
2518
2519                 if (self->state.result != NULL) {
2520                         /*
2521                          * We (already) got a final result from the server.
2522                          *
2523                          * We stop the iteration and let
2524                          * py_ldb_search_iterator_result() will deliver
2525                          * the result details.
2526                          */
2527                         TALLOC_FREE(self->state.req);
2528                         PyErr_SetNone(PyExc_StopIteration);
2529                         return NULL;
2530                 }
2531
2532                 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2533                 if (ret != LDB_SUCCESS) {
2534                         struct ldb_context *ldb_ctx;
2535                         TALLOC_FREE(self->state.req);
2536                         ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb);
2537                         /*
2538                          * We stop the iteration and let
2539                          * py_ldb_search_iterator_result() will deliver
2540                          * the exception.
2541                          */
2542                         self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2543                                                 ret, ldb_errstring(ldb_ctx));
2544                         PyErr_SetNone(PyExc_StopIteration);
2545                         return NULL;
2546                 }
2547         }
2548
2549         py_ret = self->state.next->obj;
2550         self->state.next->obj = NULL;
2551         /* no TALLOC_FREE() as self->state.next is a list */
2552         talloc_free(self->state.next);
2553         return py_ret;
2554 }
2555
2556 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self)
2557 {
2558         PyObject *py_ret = NULL;
2559
2560         if (self->state.req != NULL) {
2561                 PyErr_SetString(PyExc_RuntimeError,
2562                                 "ldb.SearchIterator request running");
2563                 return NULL;
2564         }
2565
2566         if (self->state.next != NULL) {
2567                 PyErr_SetString(PyExc_RuntimeError,
2568                                 "ldb.SearchIterator not fully consumed.");
2569                 return NULL;
2570         }
2571
2572         if (self->state.exception != NULL) {
2573                 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2574                 self->state.exception = NULL;
2575                 return NULL;
2576         }
2577
2578         if (self->state.result == NULL) {
2579                 PyErr_SetString(PyExc_RuntimeError,
2580                                 "ldb.SearchIterator result already consumed");
2581                 return NULL;
2582         }
2583
2584         py_ret = self->state.result->obj;
2585         self->state.result->obj = NULL;
2586         TALLOC_FREE(self->state.result);
2587         return py_ret;
2588 }
2589
2590 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self)
2591 {
2592         if (self->state.req == NULL) {
2593                 PyErr_SetString(PyExc_RuntimeError,
2594                                 "ldb.SearchIterator request already finished");
2595                 return NULL;
2596         }
2597
2598         Py_XDECREF(self->state.exception);
2599         TALLOC_FREE(self->mem_ctx);
2600         ZERO_STRUCT(self->state);
2601         Py_RETURN_NONE;
2602 }
2603
2604 static PyMethodDef py_ldb_search_iterator_methods[] = {
2605         { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2606                 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2607         { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2608                 "S.abandon()\n" },
2609         { NULL }
2610 };
2611
2612 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2613 {
2614         return PyStr_FromString("<ldb search iterator>");
2615 }
2616
2617 static PyTypeObject PyLdbSearchIterator = {
2618         .tp_name = "ldb.SearchIterator",
2619         .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2620         .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2621         .tp_iter = PyObject_SelfIter,
2622         .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2623         .tp_methods = py_ldb_search_iterator_methods,
2624         .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2625         .tp_doc = "LDB search_iterator.",
2626         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2627 };
2628
2629 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2630 {
2631         return PyStr_FromFormat("<ldb module '%s'>",
2632                 pyldb_Module_AsModule(self)->ops->name);
2633 }
2634
2635 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2636 {
2637         return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
2638 }
2639
2640 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2641 {
2642         pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2643         Py_RETURN_NONE;
2644 }
2645
2646 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2647 {
2648         pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2649         Py_RETURN_NONE;
2650 }
2651
2652 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2653 {
2654         pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2655         Py_RETURN_NONE;
2656 }
2657
2658 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2659 {
2660         PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2661         int ret, scope;
2662         struct ldb_request *req;
2663         const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2664         struct ldb_module *mod;
2665         const char * const*attrs;
2666
2667         /* type "int" rather than "enum" for "scope" is intentional */
2668         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2669                                          discard_const_p(char *, kwnames),
2670                                          &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2671                 return NULL;
2672
2673         mod = self->mod;
2674
2675         if (py_attrs == Py_None) {
2676                 attrs = NULL;
2677         } else {
2678                 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2679                 if (attrs == NULL)
2680                         return NULL;
2681         }
2682
2683         ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base), 
2684                              scope, NULL /* expr */, attrs,
2685                              NULL /* controls */, NULL, NULL, NULL);
2686
2687         talloc_steal(req, attrs);
2688
2689         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2690
2691         req->op.search.res = NULL;
2692
2693         ret = mod->ops->search(mod, req);
2694
2695         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2696
2697         py_ret = PyLdbResult_FromResult(req->op.search.res);
2698
2699         talloc_free(req);
2700
2701         return py_ret;
2702 }
2703
2704
2705 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2706 {
2707         struct ldb_request *req;
2708         PyObject *py_message;
2709         int ret;
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_ADD;
2717         req->op.add.message = pyldb_Message_AsMessage(py_message);
2718
2719         mod = pyldb_Module_AsModule(self);
2720         ret = mod->ops->add(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_modify(PyLdbModuleObject *self, PyObject *args) 
2728 {
2729         int ret;
2730         struct ldb_request *req;
2731         PyObject *py_message;
2732         struct ldb_module *mod;
2733
2734         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2735                 return NULL;
2736
2737         req = talloc_zero(NULL, struct ldb_request);
2738         req->operation = LDB_MODIFY;
2739         req->op.mod.message = pyldb_Message_AsMessage(py_message);
2740
2741         mod = pyldb_Module_AsModule(self);
2742         ret = mod->ops->modify(mod, req);
2743
2744         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2745
2746         Py_RETURN_NONE;
2747 }
2748
2749 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) 
2750 {
2751         int ret;
2752         struct ldb_request *req;
2753         PyObject *py_dn;
2754
2755         if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2756                 return NULL;
2757
2758         req = talloc_zero(NULL, struct ldb_request);
2759         req->operation = LDB_DELETE;
2760         req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2761
2762         ret = pyldb_Module_AsModule(self)->ops->del(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 PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2770 {
2771         int ret;
2772         struct ldb_request *req;
2773         PyObject *py_dn1, *py_dn2;
2774
2775         if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2776                 return NULL;
2777
2778         req = talloc_zero(NULL, struct ldb_request);
2779
2780         req->operation = LDB_RENAME;
2781         req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2782         req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2783
2784         ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2785
2786         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2787
2788         Py_RETURN_NONE;
2789 }
2790
2791 static PyMethodDef py_ldb_module_methods[] = {
2792         { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2793         { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2794         { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2795         { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2796         { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2797         { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2798         { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2799         { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2800         { NULL },
2801 };
2802
2803 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2804 {
2805         talloc_free(self->mem_ctx);
2806         PyObject_Del(self);
2807 }
2808
2809 static PyTypeObject PyLdbModule = {
2810         .tp_name = "ldb.LdbModule",
2811         .tp_methods = py_ldb_module_methods,
2812         .tp_repr = (reprfunc)py_ldb_module_repr,
2813         .tp_str = (reprfunc)py_ldb_module_str,
2814         .tp_basicsize = sizeof(PyLdbModuleObject),
2815         .tp_dealloc = (destructor)py_ldb_module_dealloc,
2816         .tp_flags = Py_TPFLAGS_DEFAULT,
2817         .tp_doc = "LDB module (extension)",
2818 };
2819
2820
2821 /**
2822  * Create a ldb_message_element from a Python object.
2823  *
2824  * This will accept any sequence objects that contains strings, or 
2825  * a string object.
2826  *
2827  * A reference to set_obj will be borrowed. 
2828  *
2829  * @param mem_ctx Memory context
2830  * @param set_obj Python object to convert
2831  * @param flags ldb_message_element flags to set
2832  * @param attr_name Name of the attribute
2833  * @return New ldb_message_element, allocated as child of mem_ctx
2834  */
2835 static struct ldb_message_element *PyObject_AsMessageElement(
2836                                                       TALLOC_CTX *mem_ctx,
2837                                                       PyObject *set_obj,
2838                                                       unsigned int flags,
2839                                                       const char *attr_name)
2840 {
2841         struct ldb_message_element *me;
2842         const char *msg = NULL;
2843         Py_ssize_t size;
2844         int result;
2845
2846         if (pyldb_MessageElement_Check(set_obj)) {
2847                 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2848                 /* We have to talloc_reference() the memory context, not the pointer
2849                  * which may not actually be it's own context */
2850                 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2851                         return pyldb_MessageElement_AsMessageElement(set_obj);
2852                 }
2853                 return NULL;
2854         }
2855
2856         me = talloc(mem_ctx, struct ldb_message_element);
2857         if (me == NULL) {
2858                 PyErr_NoMemory();
2859                 return NULL;
2860         }
2861
2862         me->name = talloc_strdup(me, attr_name);
2863         me->flags = flags;
2864         if (PyBytes_Check(set_obj) || PyStr_Check(set_obj)) {
2865                 me->num_values = 1;
2866                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2867                 if (PyBytes_Check(set_obj)) {
2868                         char *_msg = NULL;
2869                         result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
2870                         if (result != 0) {
2871                                 talloc_free(me);
2872                                 return NULL;
2873                         }
2874                         msg = _msg;
2875                 } else {
2876                         msg = PyStr_AsUTF8AndSize(set_obj, &size);
2877                         if (msg == NULL) {
2878                                 talloc_free(me);
2879                                 return NULL;
2880                         }
2881                 }
2882                 me->values[0].data = talloc_memdup(me,
2883                                                    (const uint8_t *)msg,
2884                                                    size+1);
2885                 me->values[0].length = size;
2886         } else if (PySequence_Check(set_obj)) {
2887                 Py_ssize_t i;
2888                 me->num_values = PySequence_Size(set_obj);
2889                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2890                 for (i = 0; i < me->num_values; i++) {
2891                         PyObject *obj = PySequence_GetItem(set_obj, i);
2892                         if (PyBytes_Check(obj)) {
2893                                 char *_msg = NULL;
2894                                 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
2895                                 if (result != 0) {
2896                                         talloc_free(me);
2897                                         return NULL;
2898                                 }
2899                                 msg = _msg;
2900                         } else if (PyStr_Check(obj)) {
2901                                 msg = PyStr_AsUTF8AndSize(obj, &size);
2902                                 if (msg == NULL) {
2903                                         talloc_free(me);
2904                                         return NULL;
2905                                 }
2906                         } else {
2907                                 PyErr_Format(PyExc_TypeError,
2908                                              "Expected string as element %zd in list", i);
2909                                 talloc_free(me);
2910                                 return NULL;
2911                         }
2912                         me->values[i].data = talloc_memdup(me,
2913                                                            (const uint8_t *)msg,
2914                                                            size+1);
2915                         me->values[i].length = size;
2916                 }
2917         } else {
2918                 PyErr_Format(PyExc_TypeError,
2919                              "String or List type expected for '%s' attribute", attr_name);
2920                 talloc_free(me);
2921                 me = NULL;
2922         }
2923
2924         return me;
2925 }
2926
2927
2928 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2929                                         struct ldb_message_element *me)
2930 {
2931         Py_ssize_t i;
2932         PyObject *result;
2933
2934         /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2935         result = PyList_New(me->num_values);
2936
2937         for (i = 0; i < me->num_values; i++) {
2938                 PyList_SetItem(result, i,
2939                         PyObject_FromLdbValue(&me->values[i]));
2940         }
2941
2942         return result;
2943 }
2944
2945 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2946 {
2947         unsigned int i;
2948         if (!PyArg_ParseTuple(args, "I", &i))
2949                 return NULL;
2950         if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2951                 Py_RETURN_NONE;
2952
2953         return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2954 }
2955
2956 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2957 {
2958         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2959         return PyInt_FromLong(el->flags);
2960 }
2961
2962 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2963 {
2964         unsigned int flags;
2965         struct ldb_message_element *el;
2966         if (!PyArg_ParseTuple(args, "I", &flags))
2967                 return NULL;
2968
2969         el = pyldb_MessageElement_AsMessageElement(self);
2970         el->flags = flags;
2971         Py_RETURN_NONE;
2972 }
2973
2974 static PyMethodDef py_ldb_msg_element_methods[] = {
2975         { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2976         { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2977         { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2978         { NULL },
2979 };
2980
2981 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2982 {
2983         return pyldb_MessageElement_AsMessageElement(self)->num_values;
2984 }
2985
2986 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2987 {
2988         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2989         if (idx < 0 || idx >= el->num_values) {
2990                 PyErr_SetString(PyExc_IndexError, "Out of range");
2991                 return NULL;
2992         }
2993         return PyBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2994 }
2995
2996 static PySequenceMethods py_ldb_msg_element_seq = {
2997         .sq_length = (lenfunc)py_ldb_msg_element_len,
2998         .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2999 };
3000
3001 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3002 {
3003         int ret;
3004         if (!pyldb_MessageElement_Check(other)) {
3005                 Py_INCREF(Py_NotImplemented);
3006                 return Py_NotImplemented;
3007         }
3008         ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3009                                                                           pyldb_MessageElement_AsMessageElement(other));
3010         return richcmp(ret, op);
3011 }
3012
3013 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3014 {
3015         PyObject *el = ldb_msg_element_to_set(NULL,
3016                                               pyldb_MessageElement_AsMessageElement(self));
3017         PyObject *ret = PyObject_GetIter(el);
3018         Py_DECREF(el);
3019         return ret;
3020 }
3021
3022 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3023 {
3024         PyLdbMessageElementObject *ret;
3025         ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3026         if (ret == NULL) {
3027                 PyErr_NoMemory();
3028                 return NULL;
3029         }
3030         ret->mem_ctx = talloc_new(NULL);
3031         if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
3032                 PyErr_NoMemory();
3033                 return NULL;
3034         }
3035         ret->el = el;
3036         return (PyObject *)ret;
3037 }
3038
3039 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3040 {
3041         PyObject *py_elements = NULL;
3042         struct ldb_message_element *el;
3043         unsigned int flags = 0;
3044         char *name = NULL;
3045         const char * const kwnames[] = { "elements", "flags", "name", NULL };
3046         PyLdbMessageElementObject *ret;
3047         TALLOC_CTX *mem_ctx;
3048         const char *msg = NULL;
3049         Py_ssize_t size;
3050         int result;
3051
3052         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3053                                          discard_const_p(char *, kwnames),
3054                                          &py_elements, &flags, &name))
3055                 return NULL;
3056
3057         mem_ctx = talloc_new(NULL);
3058         if (mem_ctx == NULL) {
3059                 PyErr_NoMemory();
3060                 return NULL;
3061         }
3062
3063         el = talloc_zero(mem_ctx, struct ldb_message_element);
3064         if (el == NULL) {
3065                 PyErr_NoMemory();
3066                 talloc_free(mem_ctx);
3067                 return NULL;
3068         }
3069
3070         if (py_elements != NULL) {
3071                 Py_ssize_t i;
3072                 if (PyBytes_Check(py_elements) || PyStr_Check(py_elements)) {
3073                         char *_msg = NULL;
3074                         el->num_values = 1;
3075                         el->values = talloc_array(el, struct ldb_val, 1);
3076                         if (el->values == NULL) {
3077                                 talloc_free(mem_ctx);
3078                                 PyErr_NoMemory();
3079                                 return NULL;
3080                         }
3081                         if (PyBytes_Check(py_elements)) {
3082                                 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3083                                 msg = _msg;
3084                         } else {
3085                                 msg = PyStr_AsUTF8AndSize(py_elements, &size);
3086                                 result = (msg == NULL) ? -1 : 0;
3087                         }
3088                         if (result != 0) {
3089                                 talloc_free(mem_ctx);
3090                                 return NULL;
3091                         }
3092                         el->values[0].data = talloc_memdup(el->values, 
3093                                 (const uint8_t *)msg, size + 1);
3094                         el->values[0].length = size;
3095                 } else if (PySequence_Check(py_elements)) {
3096                         el->num_values = PySequence_Size(py_elements);
3097                         el->values = talloc_array(el, struct ldb_val, el->num_values);
3098                         if (el->values == NULL) {
3099                                 talloc_free(mem_ctx);
3100                                 PyErr_NoMemory();
3101                                 return NULL;
3102                         }
3103                         for (i = 0; i < el->num_values; i++) {
3104                                 PyObject *item = PySequence_GetItem(py_elements, i);
3105                                 if (item == NULL) {
3106                                         talloc_free(mem_ctx);
3107                                         return NULL;
3108                                 }
3109                                 if (PyBytes_Check(item)) {
3110                                         char *_msg = NULL;
3111                                         result = PyBytes_AsStringAndSize(item, &_msg, &size);
3112                                         msg = _msg;
3113                                 } else if (PyStr_Check(item)) {
3114                                         msg = PyStr_AsUTF8AndSize(item, &size);
3115                                         result = (msg == NULL) ? -1 : 0;
3116                                 } else {
3117                                         PyErr_Format(PyExc_TypeError, 
3118                                                      "Expected string as element %zd in list", i);
3119                                         result = -1;
3120                                 }
3121                                 if (result != 0) {
3122                                         talloc_free(mem_ctx);
3123                                         return NULL;
3124                                 }
3125                                 el->values[i].data = talloc_memdup(el,
3126                                         (const uint8_t *)msg, size+1);
3127                                 el->values[i].length = size;
3128                         }
3129                 } else {
3130                         PyErr_SetString(PyExc_TypeError, 
3131                                         "Expected string or list");
3132                         talloc_free(mem_ctx);
3133                         return NULL;
3134                 }
3135         }
3136
3137         el->flags = flags;
3138         el->name = talloc_strdup(el, name);
3139
3140         ret = PyObject_New(PyLdbMessageElementObject, type);
3141         if (ret == NULL) {
3142                 talloc_free(mem_ctx);
3143                 return NULL;
3144         }
3145
3146         ret->mem_ctx = mem_ctx;
3147         ret->el = el;
3148         return (PyObject *)ret;
3149 }
3150
3151 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3152 {
3153         char *element_str = NULL;
3154         Py_ssize_t i;
3155         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3156         PyObject *ret, *repr;
3157
3158         for (i = 0; i < el->num_values; i++) {
3159                 PyObject *o = py_ldb_msg_element_find(self, i);
3160                 repr = PyObject_Repr(o);
3161                 if (element_str == NULL)
3162                         element_str = talloc_strdup(NULL, PyStr_AsUTF8(repr));
3163                 else
3164                         element_str = talloc_asprintf_append(element_str, ",%s", PyStr_AsUTF8(repr));
3165                 Py_DECREF(repr);
3166         }
3167
3168         if (element_str != NULL) {
3169                 ret = PyStr_FromFormat("MessageElement([%s])", element_str);
3170                 talloc_free(element_str);
3171         } else {
3172                 ret = PyStr_FromString("MessageElement([])");
3173         }
3174
3175         return ret;
3176 }
3177
3178 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3179 {
3180         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3181
3182         if (el->num_values == 1)
3183                 return PyStr_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3184         else
3185                 Py_RETURN_NONE;
3186 }
3187
3188 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3189 {
3190         talloc_free(self->mem_ctx);
3191         PyObject_Del(self);
3192 }
3193
3194 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3195 {
3196         return wrap_text("MessageElementTextWrapper", self);
3197 }
3198
3199 static PyGetSetDef py_ldb_msg_element_getset[] = {
3200         { discard_const_p(char, "text"), (getter)py_ldb_msg_element_get_text, NULL, NULL },
3201         { NULL }
3202 };
3203
3204 static PyTypeObject PyLdbMessageElement = {
3205         .tp_name = "ldb.MessageElement",
3206         .tp_basicsize = sizeof(PyLdbMessageElementObject),
3207         .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3208         .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3209         .tp_str = (reprfunc)py_ldb_msg_element_str,
3210         .tp_methods = py_ldb_msg_element_methods,
3211         .tp_getset = py_ldb_msg_element_getset,
3212         .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3213         .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3214         .tp_as_sequence = &py_ldb_msg_element_seq,
3215         .tp_new = py_ldb_msg_element_new,
3216         .tp_flags = Py_TPFLAGS_DEFAULT,
3217         .tp_doc = "An element of a Message",
3218 };
3219
3220
3221 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3222 {
3223         PyObject *py_ldb;
3224         PyObject *py_dict;
3225         PyObject *py_ret;
3226         struct ldb_message *msg;
3227         struct ldb_context *ldb_ctx;
3228         unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3229
3230         if (!PyArg_ParseTuple(args, "O!O!|I",
3231                               &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3232                               &mod_flags)) {
3233                 return NULL;
3234         }
3235
3236         if (!PyLdb_Check(py_ldb)) {
3237                 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
3238                 return NULL;
3239         }
3240
3241         /* mask only flags we are going to use */
3242         mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3243         if (!mod_flags) {
3244                 PyErr_SetString(PyExc_ValueError,
3245                                 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3246                                 " expected as mod_flag value");
3247                 return NULL;
3248         }
3249
3250         ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
3251
3252         msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3253         if (!msg) {
3254                 return NULL;
3255         }
3256
3257         py_ret = PyLdbMessage_FromMessage(msg);
3258
3259         talloc_unlink(ldb_ctx, msg);
3260
3261         return py_ret;
3262 }
3263
3264 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3265 {
3266         char *name;
3267         if (!PyArg_ParseTuple(args, "s", &name))
3268                 return NULL;
3269
3270         ldb_msg_remove_attr(self->msg, name);
3271
3272         Py_RETURN_NONE;
3273 }
3274
3275 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
3276 {
3277         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3278         Py_ssize_t i, j = 0;
3279         PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3280         if (msg->dn != NULL) {
3281                 PyList_SetItem(obj, j, PyStr_FromString("dn"));
3282                 j++;
3283         }
3284         for (i = 0; i < msg->num_elements; i++) {
3285                 PyList_SetItem(obj, j, PyStr_FromString(msg->elements[i].name));
3286                 j++;
3287         }
3288         return obj;
3289 }
3290
3291 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
3292 {
3293         struct ldb_message_element *el;
3294         char *name;
3295         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3296         name = PyStr_AsUTF8(py_name);
3297         if (name == NULL) {
3298                 PyErr_SetNone(PyExc_TypeError);
3299                 return NULL;
3300         }
3301         if (!ldb_attr_cmp(name, "dn"))
3302                 return pyldb_Dn_FromDn(msg->dn);
3303         el = ldb_msg_find_element(msg, name);
3304         if (el == NULL) {
3305                 return NULL;
3306         }
3307         return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3308 }
3309
3310 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3311 {
3312         PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
3313         if (ret == NULL) {
3314                 PyErr_SetString(PyExc_KeyError, "No such element");
3315                 return NULL;
3316         }
3317         return ret;
3318 }
3319
3320 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3321 {
3322         PyObject *def = NULL;
3323         const char *kwnames[] = { "name", "default", "idx", NULL };
3324         const char *name = NULL;
3325         int idx = -1;
3326         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3327         struct ldb_message_element *el;
3328
3329         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3330                                          discard_const_p(char *, kwnames), &name, &def, &idx)) {
3331                 return NULL;
3332         }
3333
3334         if (strcasecmp(name, "dn") == 0) {
3335                 return pyldb_Dn_FromDn(msg->dn);
3336         }
3337
3338         el = ldb_msg_find_element(msg, name);
3339
3340         if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3341                 if (def != NULL) {
3342                         Py_INCREF(def);
3343                         return def;
3344                 }
3345                 Py_RETURN_NONE;
3346         }
3347
3348         if (idx == -1) {
3349                 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3350         }
3351
3352         return PyObject_FromLdbValue(&el->values[idx]);
3353 }
3354
3355 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
3356 {
3357         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3358         Py_ssize_t i, j = 0;
3359         PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3360         if (msg->dn != NULL) {
3361                 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
3362                 j++;
3363         }
3364         for (i = 0; i < msg->num_elements; i++, j++) {
3365                 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3366                 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3367                 PyList_SetItem(l, j, value);
3368         }
3369         return l;
3370 }
3371
3372 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
3373 {
3374         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3375         Py_ssize_t i = 0;
3376         PyObject *l = PyList_New(msg->num_elements);
3377         for (i = 0; i < msg->num_elements; i++) {
3378                 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
3379         }
3380         return l;
3381 }
3382
3383 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3384 {
3385         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3386         PyLdbMessageElementObject *py_element;
3387         int i, ret;
3388         struct ldb_message_element *el;
3389         struct ldb_message_element *el_new;
3390
3391         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
3392                 return NULL;
3393
3394         el = py_element->el;
3395         if (el == NULL) {
3396                 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3397                 return NULL;
3398         }
3399
3400         ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3401         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3402
3403         /* now deep copy all attribute values */
3404         el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3405         if (el_new->values == NULL) {
3406                 PyErr_NoMemory();
3407                 return NULL;
3408         }
3409         el_new->num_values = el->num_values;
3410
3411         for (i = 0; i < el->num_values; i++) {
3412                 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
3413                 if (el_new->values[i].data == NULL
3414                                 && el->values[i].length != 0) {
3415                         PyErr_NoMemory();
3416                         return NULL;
3417                 }
3418         }
3419
3420         Py_RETURN_NONE;
3421 }
3422
3423 static PyMethodDef py_ldb_msg_methods[] = {
3424         { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
3425                 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3426                 "Class method to create ldb.Message object from Dictionary.\n"
3427                 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3428         { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, 
3429                 "S.keys() -> list\n\n"
3430                 "Return sequence of all attribute names." },
3431         { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, 
3432                 "S.remove(name)\n\n"
3433                 "Remove all entries for attributes with the specified name."},
3434         { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
3435           "msg.get(name,default=None,idx=None) -> string\n"
3436           "idx is the index into the values array\n"
3437           "if idx is None, then a list is returned\n"
3438           "if idx is not None, then the element with that index is returned\n"
3439           "if you pass the special name 'dn' then the DN object is returned\n"},
3440         { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
3441         { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
3442         { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
3443                 "S.add(element)\n\n"
3444                 "Add an element to this message." },
3445         { NULL },
3446 };
3447
3448 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
3449 {
3450         PyObject *list, *iter;
3451
3452         list = py_ldb_msg_keys(self);
3453         iter = PyObject_GetIter(list);
3454         Py_DECREF(list);
3455         return iter;
3456 }
3457
3458 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
3459 {
3460         char *attr_name;
3461
3462         attr_name = PyStr_AsUTF8(name);
3463         if (attr_name == NULL) {
3464                 PyErr_SetNone(PyExc_TypeError);
3465                 return -1;
3466         }
3467
3468         if (value == NULL) {
3469                 /* delitem */
3470                 ldb_msg_remove_attr(self->msg, attr_name);
3471         } else {
3472                 int ret;
3473                 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
3474                                                                            value, 0, attr_name);
3475                 if (el == NULL) {
3476                         return -1;
3477                 }
3478                 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
3479                 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
3480                 if (ret != LDB_SUCCESS) {
3481                         PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
3482                         return -1;
3483                 }
3484         }
3485         return 0;
3486 }
3487
3488 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
3489 {
3490         return pyldb_Message_AsMessage(self)->num_elements;
3491 }
3492
3493 static PyMappingMethods py_ldb_msg_mapping = {
3494         .mp_length = (lenfunc)py_ldb_msg_length,
3495         .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
3496         .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
3497 };
3498
3499 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3500 {
3501         const char * const kwnames[] = { "dn", NULL };
3502         struct ldb_message *ret;
3503         TALLOC_CTX *mem_ctx;
3504         PyObject *pydn = NULL;
3505         PyLdbMessageObject *py_ret;
3506
3507         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
3508                                          discard_const_p(char *, kwnames),
3509                                          &pydn))
3510                 return NULL;
3511
3512         mem_ctx = talloc_new(NULL);
3513         if (mem_ctx == NULL) {
3514                 PyErr_NoMemory();
3515                 return NULL;
3516         }
3517
3518         ret = ldb_msg_new(mem_ctx);
3519         if (ret == NULL) {
3520                 talloc_free(mem_ctx);
3521                 PyErr_NoMemory();
3522                 return NULL;
3523         }
3524
3525         if (pydn != NULL) {
3526                 struct ldb_dn *dn;
3527                 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
3528                         talloc_free(mem_ctx);
3529                         return NULL;
3530                 }
3531                 ret->dn = talloc_reference(ret, dn);
3532         }
3533
3534         py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
3535         if (py_ret == NULL) {
3536                 PyErr_NoMemory();
3537                 talloc_free(mem_ctx);
3538                 return NULL;
3539         }
3540
3541         py_ret->mem_ctx = mem_ctx;
3542         py_ret->msg = ret;
3543         return (PyObject *)py_ret;
3544 }
3545
3546 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
3547 {
3548         PyLdbMessageObject *ret;
3549
3550         ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3551         if (ret == NULL) {
3552                 PyErr_NoMemory();
3553                 return NULL;
3554         }
3555         ret->mem_ctx = talloc_new(NULL);
3556         ret->msg = talloc_reference(ret->mem_ctx, msg);
3557         return (PyObject *)ret;
3558 }
3559
3560 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3561 {
3562         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3563         return pyldb_Dn_FromDn(msg->dn);
3564 }
3565
3566 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3567 {
3568         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3569         if (!pyldb_Dn_Check(value)) {
3570                 PyErr_SetString(PyExc_TypeError, "expected dn");
3571                 return -1;
3572         }
3573
3574         msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3575         return 0;
3576 }
3577
3578 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
3579 {
3580         return wrap_text("MessageTextWrapper", self);
3581 }
3582
3583 static PyGetSetDef py_ldb_msg_getset[] = {
3584         { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
3585         { discard_const_p(char, "text"), (getter)py_ldb_msg_get_text, NULL, NULL },
3586         { NULL }
3587 };
3588
3589 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3590 {
3591         PyObject *dict = PyDict_New(), *ret, *repr;
3592         if (PyDict_Update(dict, (PyObject *)self) != 0)
3593                 return NULL;
3594         repr = PyObject_Repr(dict);
3595         if (repr == NULL) {
3596                 Py_DECREF(dict);
3597                 return NULL;
3598         }
3599         ret = PyStr_FromFormat("Message(%s)", PyStr_AsUTF8(repr));
3600         Py_DECREF(repr);
3601         Py_DECREF(dict);
3602         return ret;
3603 }
3604
3605 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3606 {
3607         talloc_free(self->mem_ctx);
3608         PyObject_Del(self);
3609 }
3610
3611 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3612                               PyLdbMessageObject *py_msg2, int op)
3613 {
3614         struct ldb_message *msg1, *msg2;
3615         unsigned int i;
3616         int ret;
3617
3618         if (!PyLdbMessage_Check(py_msg2)) {
3619                 Py_INCREF(Py_NotImplemented);
3620                 return Py_NotImplemented;
3621         }
3622
3623         msg1 = pyldb_Message_AsMessage(py_msg1),
3624         msg2 = pyldb_Message_AsMessage(py_msg2);
3625
3626         if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3627                 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3628                 if (ret != 0) {
3629                         return richcmp(ret, op);
3630                 }
3631         }
3632
3633         ret = msg1->num_elements - msg2->num_elements;
3634         if (ret != 0) {
3635                 return richcmp(ret, op);
3636         }
3637
3638         for (i = 0; i < msg1->num_elements; i++) {
3639                 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3640                                                    &msg2->elements[i]);
3641                 if (ret != 0) {
3642                         return richcmp(ret, op);
3643                 }
3644
3645                 ret = ldb_msg_element_compare(&msg1->elements[i],
3646                                               &msg2->elements[i]);
3647                 if (ret != 0) {
3648                         return richcmp(ret, op);
3649                 }
3650         }
3651
3652         return richcmp(0, op);
3653 }
3654
3655 static PyTypeObject PyLdbMessage = {
3656         .tp_name = "ldb.Message",
3657         .tp_methods = py_ldb_msg_methods,
3658         .tp_getset = py_ldb_msg_getset,
3659         .tp_as_mapping = &py_ldb_msg_mapping,
3660         .tp_basicsize = sizeof(PyLdbMessageObject),
3661         .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3662         .tp_new = py_ldb_msg_new,
3663         .tp_repr = (reprfunc)py_ldb_msg_repr,
3664         .tp_flags = Py_TPFLAGS_DEFAULT,
3665         .tp_iter = (getiterfunc)py_ldb_msg_iter,
3666         .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3667         .tp_doc = "A LDB Message",
3668 };
3669
3670 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3671 {
3672         PyLdbTreeObject *ret;
3673
3674         ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3675         if (ret == NULL) {
3676                 PyErr_NoMemory();
3677                 return NULL;
3678         }
3679
3680         ret->mem_ctx = talloc_new(NULL);
3681         ret->tree = talloc_reference(ret->mem_ctx, tree);
3682         return (PyObject *)ret;
3683 }
3684
3685 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3686 {
3687         talloc_free(self->mem_ctx);
3688         PyObject_Del(self);
3689 }
3690
3691 static PyTypeObject PyLdbTree = {
3692         .tp_name = "ldb.Tree",
3693         .tp_basicsize = sizeof(PyLdbTreeObject),
3694         .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3695         .tp_flags = Py_TPFLAGS_DEFAULT,
3696         .tp_doc = "A search tree",
3697 };
3698
3699 /* Ldb_module */
3700 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3701 {
3702         PyObject *py_ldb = (PyObject *)mod->private_data;
3703         PyObject *py_result, *py_base, *py_attrs, *py_tree;
3704
3705         py_base = pyldb_Dn_FromDn(req->op.search.base);
3706
3707         if (py_base == NULL)
3708                 return LDB_ERR_OPERATIONS_ERROR;
3709
3710         py_tree = PyLdbTree_FromTree(req->op.search.tree);
3711
3712         if (py_tree == NULL)
3713                 return LDB_ERR_OPERATIONS_ERROR;
3714
3715         if (req->op.search.attrs == NULL) {
3716                 py_attrs = Py_None;
3717         } else {
3718                 int i, len;
3719                 for (len = 0; req->op.search.attrs[len]; len++);
3720                 py_attrs = PyList_New(len);
3721                 for (i = 0; i < len; i++)
3722                         PyList_SetItem(py_attrs, i, PyStr_FromString(req->op.search.attrs[i]));
3723         }
3724
3725         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3726                                         discard_const_p(char, "OiOO"),
3727                                         py_base, req->op.search.scope, py_tree, py_attrs);
3728
3729         Py_DECREF(py_attrs);
3730         Py_DECREF(py_tree);
3731         Py_DECREF(py_base);
3732
3733         if (py_result == NULL) {
3734                 return LDB_ERR_PYTHON_EXCEPTION;
3735         }
3736
3737         req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3738         if (req->op.search.res == NULL) {
3739                 return LDB_ERR_PYTHON_EXCEPTION;
3740         }
3741
3742         Py_DECREF(py_result);
3743
3744         return LDB_SUCCESS;
3745 }
3746
3747 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3748 {
3749         PyObject *py_ldb = (PyObject *)mod->private_data;
3750         PyObject *py_result, *py_msg;
3751
3752         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3753
3754         if (py_msg == NULL) {
3755                 return LDB_ERR_OPERATIONS_ERROR;
3756         }
3757
3758         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3759                                         discard_const_p(char, "O"),
3760                                         py_msg);
3761
3762         Py_DECREF(py_msg);
3763
3764         if (py_result == NULL) {
3765                 return LDB_ERR_PYTHON_EXCEPTION;
3766         }
3767
3768         Py_DECREF(py_result);
3769
3770         return LDB_SUCCESS;
3771 }
3772
3773 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3774 {
3775         PyObject *py_ldb = (PyObject *)mod->private_data;
3776         PyObject *py_result, *py_msg;
3777
3778         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3779
3780         if (py_msg == NULL) {
3781                 return LDB_ERR_OPERATIONS_ERROR;
3782         }
3783
3784         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3785                                         discard_const_p(char, "O"),
3786                                         py_msg);
3787
3788         Py_DECREF(py_msg);
3789
3790         if (py_result == NULL) {
3791                 return LDB_ERR_PYTHON_EXCEPTION;
3792         }
3793
3794         Py_DECREF(py_result);
3795
3796         return LDB_SUCCESS;
3797 }
3798
3799 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3800 {
3801         PyObject *py_ldb = (PyObject *)mod->private_data;
3802         PyObject *py_result, *py_dn;
3803
3804         py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3805
3806         if (py_dn == NULL)
3807                 return LDB_ERR_OPERATIONS_ERROR;
3808
3809         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3810                                         discard_const_p(char, "O"),
3811                                         py_dn);
3812
3813         if (py_result == NULL) {
3814                 return LDB_ERR_PYTHON_EXCEPTION;
3815         }
3816
3817         Py_DECREF(py_result);
3818
3819         return LDB_SUCCESS;
3820 }
3821
3822 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3823 {
3824         PyObject *py_ldb = (PyObject *)mod->private_data;
3825         PyObject *py_result, *py_olddn, *py_newdn;
3826
3827         py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3828
3829         if (py_olddn == NULL)
3830                 return LDB_ERR_OPERATIONS_ERROR;
3831
3832         py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3833
3834         if (py_newdn == NULL)
3835                 return LDB_ERR_OPERATIONS_ERROR;
3836
3837         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3838                                         discard_const_p(char, "OO"),
3839                                         py_olddn, py_newdn);
3840
3841         Py_DECREF(py_olddn);
3842         Py_DECREF(py_newdn);
3843
3844         if (py_result == NULL) {
3845                 return LDB_ERR_PYTHON_EXCEPTION;
3846         }
3847
3848         Py_DECREF(py_result);
3849
3850         return LDB_SUCCESS;
3851 }
3852
3853 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3854 {
3855         PyObject *py_ldb = (PyObject *)mod->private_data;
3856         PyObject *py_result;
3857
3858         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3859                                         discard_const_p(char, ""));
3860
3861         Py_XDECREF(py_result);
3862
3863         return LDB_ERR_OPERATIONS_ERROR;
3864 }
3865
3866 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3867 {
3868         PyObject *py_ldb = (PyObject *)mod->private_data;
3869         PyObject *py_result;
3870
3871         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3872                                         discard_const_p(char, ""));
3873
3874         Py_XDECREF(py_result);
3875
3876         return LDB_ERR_OPERATIONS_ERROR;
3877 }
3878
3879 static int py_module_start_transaction(struct ldb_module *mod)
3880 {
3881         PyObject *py_ldb = (PyObject *)mod->private_data;
3882         PyObject *py_result;
3883
3884         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3885                                         discard_const_p(char, ""));
3886
3887         if (py_result == NULL) {
3888                 return LDB_ERR_PYTHON_EXCEPTION;
3889         }
3890
3891         Py_DECREF(py_result);
3892
3893         return LDB_SUCCESS;
3894 }
3895
3896 static int py_module_end_transaction(struct ldb_module *mod)
3897 {
3898         PyObject *py_ldb = (PyObject *)mod->private_data;
3899         PyObject *py_result;
3900
3901         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3902                                         discard_const_p(char, ""));
3903
3904         if (py_result == NULL) {
3905                 return LDB_ERR_PYTHON_EXCEPTION;
3906         }
3907
3908         Py_DECREF(py_result);
3909
3910         return LDB_SUCCESS;
3911 }
3912
3913 static int py_module_del_transaction(struct ldb_module *mod)
3914 {
3915         PyObject *py_ldb = (PyObject *)mod->private_data;
3916         PyObject *py_result;
3917
3918         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3919                                         discard_const_p(char, ""));
3920
3921         if (py_result == NULL) {
3922                 return LDB_ERR_PYTHON_EXCEPTION;
3923         }
3924
3925         Py_DECREF(py_result);
3926
3927         return LDB_SUCCESS;
3928 }
3929
3930 static int py_module_destructor(struct ldb_module *mod)
3931 {
3932         Py_DECREF((PyObject *)mod->private_data);
3933         return 0;
3934 }
3935
3936 static int py_module_init(struct ldb_module *mod)
3937 {
3938         PyObject *py_class = (PyObject *)mod->ops->private_data;
3939         PyObject *py_result, *py_next, *py_ldb;
3940
3941         py_ldb = PyLdb_FromLdbContext(mod->ldb);
3942
3943         if (py_ldb == NULL)
3944                 return LDB_ERR_OPERATIONS_ERROR;
3945
3946         py_next = PyLdbModule_FromModule(mod->next);
3947
3948         if (py_next == NULL)
3949                 return LDB_ERR_OPERATIONS_ERROR;
3950
3951         py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3952                                           py_ldb, py_next);
3953
3954         if (py_result == NULL) {
3955                 return LDB_ERR_PYTHON_EXCEPTION;
3956         }
3957
3958         mod->private_data = py_result;
3959
3960         talloc_set_destructor(mod, py_module_destructor);
3961
3962         return ldb_next_init(mod);
3963 }
3964
3965 static PyObject *py_register_module(PyObject *module, PyObject *args)
3966 {
3967         int ret;
3968         struct ldb_module_ops *ops;
3969         PyObject *input;
3970
3971         if (!PyArg_ParseTuple(args, "O", &input))
3972                 return NULL;
3973
3974         ops = talloc_zero(NULL, struct ldb_module_ops);
3975         if (ops == NULL) {
3976                 PyErr_NoMemory();
3977                 return NULL;
3978         }
3979
3980         ops->name = talloc_strdup(ops, PyStr_AsUTF8(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3981
3982         Py_INCREF(input);
3983         ops->private_data = input;
3984         ops->init_context = py_module_init;
3985         ops->search = py_module_search;
3986         ops->add = py_module_add;
3987         ops->modify = py_module_modify;
3988         ops->del = py_module_del;
3989         ops->rename = py_module_rename;
3990         ops->request = py_module_request;
3991         ops->extended = py_module_extended;
3992         ops->start_transaction = py_module_start_transaction;
3993         ops->end_transaction = py_module_end_transaction;
3994         ops->del_transaction = py_module_del_transaction;
3995
3996         ret = ldb_register_module(ops);
3997         if (ret != LDB_SUCCESS) {
3998                 TALLOC_FREE(ops);
3999         }
4000
4001         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
4002
4003         Py_RETURN_NONE;
4004 }
4005
4006 static PyObject *py_timestring(PyObject *module, PyObject *args)
4007 {
4008         /* most times "time_t" is a signed integer type with 32 or 64 bit:
4009          * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4010         long int t_val;
4011         char *tresult;
4012         PyObject *ret;
4013         if (!PyArg_ParseTuple(args, "l", &t_val))
4014                 return NULL;
4015         tresult = ldb_timestring(NULL, (time_t) t_val);
4016         ret = PyStr_FromString(tresult);
4017         talloc_free(tresult);
4018         return ret;
4019 }
4020
4021 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
4022 {
4023         char *str;
4024         if (!PyArg_ParseTuple(args, "s", &str))
4025                 return NULL;
4026
4027         return PyInt_FromLong(ldb_string_to_time(str));
4028 }
4029
4030 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4031 {
4032         char *name;
4033         if (!PyArg_ParseTuple(args, "s", &name))
4034                 return NULL;
4035         return PyBool_FromLong(ldb_valid_attr_name(name));
4036 }
4037
4038 /*
4039   encode a string using RFC2254 rules
4040  */
4041 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4042 {
4043         char *str, *encoded;
4044         Py_ssize_t size = 0;
4045         struct ldb_val val;
4046         PyObject *ret;
4047
4048         if (!PyArg_ParseTuple(args, "s#", &str, &size))
4049                 return NULL;
4050         val.data = (uint8_t *)str;
4051         val.length = size;
4052
4053         encoded = ldb_binary_encode(NULL, val);
4054         if (encoded == NULL) {
4055                 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4056                 return NULL;
4057         }
4058         ret = PyStr_FromString(encoded);
4059         talloc_free(encoded);
4060         return ret;
4061 }
4062
4063 /*
4064   decode a string using RFC2254 rules
4065  */
4066 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4067 {
4068         char *str;
4069         struct ldb_val val;
4070         PyObject *ret;
4071
4072         if (!PyArg_ParseTuple(args, "s", &str))
4073                 return NULL;
4074
4075         val = ldb_binary_decode(NULL, str);
4076         if (val.data == NULL) {
4077                 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4078                 return NULL;
4079         }
4080         ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4081         talloc_free(val.data);
4082         return ret;
4083 }
4084
4085 static PyMethodDef py_ldb_global_methods[] = {
4086         { "register_module", py_register_module, METH_VARARGS, 
4087                 "S.register_module(module) -> None\n\n"
4088                 "Register a LDB module."},
4089         { "timestring", py_timestring, METH_VARARGS, 
4090                 "S.timestring(int) -> string\n\n"
4091                 "Generate a LDAP time string from a UNIX timestamp" },
4092         { "string_to_time", py_string_to_time, METH_VARARGS,
4093                 "S.string_to_time(string) -> int\n\n"
4094                 "Parse a LDAP time string into a UNIX timestamp." },
4095         { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4096                 "S.valid_attr_name(name) -> bool\n\nn"
4097                 "Check whether the supplied name is a valid attribute name." },
4098         { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
4099                 "S.open() -> Ldb\n\n"
4100                 "Open a new LDB context." },
4101         { "binary_encode", py_binary_encode, METH_VARARGS,
4102                 "S.binary_encode(string) -> string\n\n"
4103                 "Perform a RFC2254 binary encoding on a string" },
4104         { "binary_decode", py_binary_decode, METH_VARARGS,
4105                 "S.binary_decode(string) -> string\n\n"
4106                 "Perform a RFC2254 binary decode on a string" },
4107         { NULL }
4108 };
4109
4110 #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."
4111
4112 #if PY_MAJOR_VERSION >= 3
4113 static struct PyModuleDef moduledef = {
4114         PyModuleDef_HEAD_INIT,
4115         .m_name = "ldb",
4116         .m_doc = MODULE_DOC,
4117         .m_size = -1,
4118         .m_methods = py_ldb_global_methods,
4119 };
4120 #endif
4121
4122 static PyObject* module_init(void)
4123 {
4124         PyObject *m;
4125
4126         if (PyType_Ready(&PyLdbDn) < 0)
4127                 return NULL;
4128
4129         if (PyType_Ready(&PyLdbMessage) < 0)
4130                 return NULL;
4131
4132         if (PyType_Ready(&PyLdbMessageElement) < 0)
4133                 return NULL;
4134
4135         if (PyType_Ready(&PyLdb) < 0)
4136                 return NULL;
4137
4138         if (PyType_Ready(&PyLdbModule) < 0)
4139                 return NULL;
4140
4141         if (PyType_Ready(&PyLdbTree) < 0)
4142                 return NULL;
4143
4144         if (PyType_Ready(&PyLdbResult) < 0)
4145                 return NULL;
4146
4147         if (PyType_Ready(&PyLdbSearchIterator) < 0)
4148                 return NULL;
4149
4150         if (PyType_Ready(&PyLdbControl) < 0)
4151                 return NULL;
4152
4153 #if PY_MAJOR_VERSION >= 3
4154         m = PyModule_Create(&moduledef);
4155 #else
4156         m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC);
4157 #endif
4158         if (m == NULL)
4159                 return NULL;
4160
4161 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4162
4163         ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4164         ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4165         ADD_LDB_INT(SEQ_NEXT);
4166         ADD_LDB_INT(SCOPE_DEFAULT);
4167         ADD_LDB_INT(SCOPE_BASE);
4168         ADD_LDB_INT(SCOPE_ONELEVEL);
4169         ADD_LDB_INT(SCOPE_SUBTREE);
4170
4171         ADD_LDB_INT(CHANGETYPE_NONE);
4172         ADD_LDB_INT(CHANGETYPE_ADD);
4173         ADD_LDB_INT(CHANGETYPE_DELETE);
4174         ADD_LDB_INT(CHANGETYPE_MODIFY);
4175
4176         ADD_LDB_INT(FLAG_MOD_ADD);
4177         ADD_LDB_INT(FLAG_MOD_REPLACE);
4178         ADD_LDB_INT(FLAG_MOD_DELETE);
4179
4180         ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4181         ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4182         ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4183         ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4184
4185         ADD_LDB_INT(SUCCESS);
4186         ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4187         ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4188         ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4189         ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4190         ADD_LDB_INT(ERR_COMPARE_FALSE);
4191         ADD_LDB_INT(ERR_COMPARE_TRUE);
4192         ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4193         ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4194         ADD_LDB_INT(ERR_REFERRAL);
4195         ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4196         ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4197         ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4198         ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4199         ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4200         ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4201         ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4202         ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4203         ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4204         ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4205         ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4206         ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4207         ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4208         ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4209         ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4210         ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4211         ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4212         ADD_LDB_INT(ERR_BUSY);
4213         ADD_LDB_INT(ERR_UNAVAILABLE);
4214         ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4215         ADD_LDB_INT(ERR_LOOP_DETECT);
4216         ADD_LDB_INT(ERR_NAMING_VIOLATION);
4217         ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4218         ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4219         ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4220         ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4221         ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4222         ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4223         ADD_LDB_INT(ERR_OTHER);
4224
4225         ADD_LDB_INT(FLG_RDONLY);
4226         ADD_LDB_INT(FLG_NOSYNC);
4227         ADD_LDB_INT(FLG_RECONNECT);
4228         ADD_LDB_INT(FLG_NOMMAP);
4229         ADD_LDB_INT(FLG_SHOW_BINARY);
4230         ADD_LDB_INT(FLG_ENABLE_TRACING);
4231         ADD_LDB_INT(FLG_DONT_CREATE_DB);
4232
4233
4234         /* Historical misspelling */
4235         PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
4236
4237         PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
4238
4239         PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
4240         PyModule_AddObject(m, "LdbError", PyExc_LdbError);
4241
4242         Py_INCREF(&PyLdb);
4243         Py_INCREF(&PyLdbDn);
4244         Py_INCREF(&PyLdbModule);
4245         Py_INCREF(&PyLdbMessage);
4246         Py_INCREF(&PyLdbMessageElement);
4247         Py_INCREF(&PyLdbTree);
4248         Py_INCREF(&PyLdbResult);
4249         Py_INCREF(&PyLdbControl);
4250
4251         PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
4252         PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
4253         PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
4254         PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
4255         PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
4256         PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
4257         PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
4258
4259         PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
4260
4261 #define ADD_LDB_STRING(val)  PyModule_AddStringConstant(m, #val, LDB_## val)
4262
4263         ADD_LDB_STRING(SYNTAX_DN);
4264         ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
4265         ADD_LDB_STRING(SYNTAX_INTEGER);
4266         ADD_LDB_STRING(SYNTAX_BOOLEAN);
4267         ADD_LDB_STRING(SYNTAX_OCTET_STRING);
4268         ADD_LDB_STRING(SYNTAX_UTC_TIME);
4269         ADD_LDB_STRING(OID_COMPARATOR_AND);
4270         ADD_LDB_STRING(OID_COMPARATOR_OR);
4271
4272         return m;
4273 }
4274
4275 #if PY_MAJOR_VERSION >= 3
4276 PyMODINIT_FUNC PyInit_ldb(void);
4277 PyMODINIT_FUNC PyInit_ldb(void)
4278 {
4279         return module_init();
4280 }
4281 #else
4282 void initldb(void);
4283 void initldb(void)
4284 {
4285         module_init();
4286 }
4287 #endif