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