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