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