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