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