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