pyldb: p3k readiness: allow single unicode string in msg element
[nivanova/samba-autobuild/.git] / lib / ldb / pyldb.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Python interface to ldb.
5
6    Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7    Copyright (C) 2006 Simo Sorce <idra@samba.org>
8    Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9    Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10    Copyright (C) 2009-2011 Andrew Tridgell
11    Copyright (C) 2009-2011 Andrew Bartlett
12
13     ** NOTE! The following LGPL license applies to the ldb
14     ** library. This does NOT imply that all of Samba is released
15     ** under the LGPL
16
17    This library is free software; you can redistribute it and/or
18    modify it under the terms of the GNU Lesser General Public
19    License as published by the Free Software Foundation; either
20    version 3 of the License, or (at your option) any later version.
21
22    This library is distributed in the hope that it will be useful,
23    but WITHOUT ANY WARRANTY; without even the implied warranty of
24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25    Lesser General Public License for more details.
26
27    You should have received a copy of the GNU Lesser General Public
28    License along with this library; if not, see <http://www.gnu.org/licenses/>.
29 */
30
31 #include <Python.h>
32 #include "ldb_private.h"
33 #include "ldb_handlers.h"
34 #include "pyldb.h"
35 #include "dlinklist.h"
36
37 struct py_ldb_search_iterator_reply;
38
39 typedef struct {
40         PyObject_HEAD
41         TALLOC_CTX *mem_ctx;
42         PyLdbObject *ldb;
43         struct {
44                 struct ldb_request *req;
45                 struct py_ldb_search_iterator_reply *next;
46                 struct py_ldb_search_iterator_reply *result;
47                 PyObject *exception;
48         } state;
49 } PyLdbSearchIteratorObject;
50
51 struct py_ldb_search_iterator_reply {
52         struct py_ldb_search_iterator_reply *prev, *next;
53         PyLdbSearchIteratorObject *py_iter;
54         PyObject *obj;
55 };
56
57 void initldb(void);
58 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg);
59 static PyObject *PyExc_LdbError;
60
61 static PyTypeObject PyLdbControl;
62 static PyTypeObject PyLdbResult;
63 static PyTypeObject PyLdbSearchIterator;
64 static PyTypeObject PyLdbMessage;
65 #define PyLdbMessage_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
66 static PyTypeObject PyLdbModule;
67 static PyTypeObject PyLdbDn;
68 #define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
69 static PyTypeObject PyLdb;
70 #define PyLdb_Check(ob) PyObject_TypeCheck(ob, &PyLdb)
71 static PyTypeObject PyLdbMessageElement;
72 #define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
73
74 static PyTypeObject PyLdbTree;
75 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx);
76 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod);
77 static struct ldb_message_element *PyObject_AsMessageElement(
78                                                       TALLOC_CTX *mem_ctx,
79                                                       PyObject *set_obj,
80                                                       unsigned int flags,
81                                                       const char *attr_name);
82
83 #if PY_MAJOR_VERSION >= 3
84 #define PyStr_Check PyUnicode_Check
85 #define PyStr_FromString PyUnicode_FromString
86 #define PyStr_FromStringAndSize PyUnicode_FromStringAndSize
87 #define PyStr_FromFormat PyUnicode_FromFormat
88 #define PyStr_FromFormatV PyUnicode_FromFormatV
89 #define PyStr_AsUTF8 PyUnicode_AsUTF8
90 #define PyStr_AsUTF8AndSize PyUnicode_AsUTF8AndSize
91 #define PyInt_FromLong PyLong_FromLong
92 #else
93 #define PyStr_Check PyString_Check
94 #define PyStr_FromString PyString_FromString
95 #define PyStr_FromStringAndSize PyString_FromStringAndSize
96 #define PyStr_FromFormat PyString_FromFormat
97 #define PyStr_FromFormatV PyString_FromFormatV
98 #define PyStr_AsUTF8 PyString_AsString
99
100 const char *PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr);
101 const char *
102 PyStr_AsUTF8AndSize(PyObject *pystr, Py_ssize_t *sizeptr)
103 {
104         const char * ret = PyString_AsString(pystr);
105         if (ret == NULL)
106                 return NULL;
107         *sizeptr = PyString_Size(pystr);
108         return ret;
109 }
110 #endif
111
112 static PyObject *richcmp(int cmp_val, int op)
113 {
114         int ret;
115         switch (op) {
116                 case Py_LT: ret = cmp_val < 0;  break;
117                 case Py_LE: ret = cmp_val <= 0; break;
118                 case Py_EQ: ret = cmp_val == 0; break;
119                 case Py_NE: ret = cmp_val != 0; break;
120                 case Py_GT: ret = cmp_val > 0;  break;
121                 case Py_GE: ret = cmp_val >= 0; break;
122                 default:
123                         Py_INCREF(Py_NotImplemented);
124                         return Py_NotImplemented;
125         }
126         return PyBool_FromLong(ret);
127 }
128
129
130 static PyObject *py_ldb_control_str(PyLdbControlObject *self)
131 {
132         if (self->data != NULL) {
133                 char* control = ldb_control_to_string(self->mem_ctx, self->data);
134                 if (control == NULL) {
135                         PyErr_NoMemory();
136                         return NULL;
137                 }
138                 return PyStr_FromString(control);
139         } else {
140                 return PyStr_FromString("ldb control");
141         }
142 }
143
144 static void py_ldb_control_dealloc(PyLdbControlObject *self)
145 {
146         if (self->mem_ctx != NULL) {
147                 talloc_free(self->mem_ctx);
148         }
149         self->data = NULL;
150         Py_TYPE(self)->tp_free(self);
151 }
152
153 /* Create a text (rather than bytes) interface for a LDB result object */
154 static PyObject *wrap_text(const char *type, PyObject *wrapped)
155 {
156         PyObject *mod, *cls, *constructor, *inst;
157         mod = PyImport_ImportModule("_ldb_text");
158         if (mod == NULL)
159                 return NULL;
160         cls = PyObject_GetAttrString(mod, type);
161         Py_DECREF(mod);
162         if (cls == NULL) {
163                 Py_DECREF(mod);
164                 return NULL;
165         }
166         constructor = PyObject_GetAttrString(cls, "_wrap");
167         Py_DECREF(cls);
168         if (constructor == NULL) {
169                 return NULL;
170         }
171         inst = PyObject_CallFunction(constructor, discard_const_p(char, "O"), wrapped);
172         Py_DECREF(constructor);
173         return inst;
174 }
175
176 static PyObject *py_ldb_control_get_oid(PyLdbControlObject *self)
177 {
178         return PyStr_FromString(self->data->oid);
179 }
180
181 static PyObject *py_ldb_control_get_critical(PyLdbControlObject *self)
182 {
183         return PyBool_FromLong(self->data->critical);
184 }
185
186 static PyObject *py_ldb_control_set_critical(PyLdbControlObject *self, PyObject *value, void *closure)
187 {
188         if (PyObject_IsTrue(value)) {
189                 self->data->critical = true;
190         } else {
191                 self->data->critical = false;
192         }
193         return 0;
194 }
195
196 static PyObject *py_ldb_control_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
197 {
198         char *data = NULL;
199         const char * const kwnames[] = { "ldb", "data", NULL };
200         struct ldb_control *parsed_controls;
201         PyLdbControlObject *ret;
202         PyObject *py_ldb;
203         TALLOC_CTX *mem_ctx;
204         struct ldb_context *ldb_ctx;
205
206         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!s",
207                                          discard_const_p(char *, kwnames),
208                                          &PyLdb, &py_ldb, &data))
209                 return NULL;
210
211         mem_ctx = talloc_new(NULL);
212         if (mem_ctx == NULL) {
213                 PyErr_NoMemory();
214                 return NULL;
215         }
216
217         ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
218         parsed_controls = ldb_parse_control_from_string(ldb_ctx, mem_ctx, data);
219
220         if (!parsed_controls) {
221                 talloc_free(mem_ctx);
222                 PyErr_SetString(PyExc_ValueError, "unable to parse control string");
223                 return NULL;
224         }
225
226         ret = PyObject_New(PyLdbControlObject, type);
227         if (ret == NULL) {
228                 PyErr_NoMemory();
229                 talloc_free(mem_ctx);
230                 return NULL;
231         }
232
233         ret->mem_ctx = mem_ctx;
234
235         ret->data = talloc_move(mem_ctx, &parsed_controls);
236         if (ret->data == NULL) {
237                 Py_DECREF(ret);
238                 PyErr_NoMemory();
239                 talloc_free(mem_ctx);
240                 return NULL;
241         }
242
243         return (PyObject *)ret;
244 }
245
246 static PyGetSetDef py_ldb_control_getset[] = {
247         { discard_const_p(char, "oid"), (getter)py_ldb_control_get_oid, NULL, NULL },
248         { discard_const_p(char, "critical"), (getter)py_ldb_control_get_critical, (setter)py_ldb_control_set_critical, NULL },
249         { NULL }
250 };
251
252 static PyTypeObject PyLdbControl = {
253         .tp_name = "ldb.control",
254         .tp_dealloc = (destructor)py_ldb_control_dealloc,
255         .tp_getattro = PyObject_GenericGetAttr,
256         .tp_basicsize = sizeof(PyLdbControlObject),
257         .tp_getset = py_ldb_control_getset,
258         .tp_doc = "LDB control.",
259         .tp_str = (reprfunc)py_ldb_control_str,
260         .tp_new = py_ldb_control_new,
261         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
262 };
263
264 static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
265 {
266         if (ret == LDB_ERR_PYTHON_EXCEPTION)
267                 return; /* Python exception should already be set, just keep that */
268
269         PyErr_SetObject(error, 
270                         Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
271                                       ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
272 }
273
274 static PyObject *PyObject_FromLdbValue(const struct ldb_val *val)
275 {
276         return PyBytes_FromStringAndSize((const char *)val->data, val->length);
277 }
278
279 static PyObject *PyStr_FromLdbValue(const struct ldb_val *val)
280 {
281         return PyStr_FromStringAndSize((const char *)val->data, val->length);
282 }
283
284 /**
285  * Create a Python object from a ldb_result.
286  *
287  * @param result LDB result to convert
288  * @return Python object with converted result (a list object)
289  */
290 static PyObject *PyLdbControl_FromControl(struct ldb_control *control)
291 {
292         TALLOC_CTX *ctl_ctx = talloc_new(NULL);
293         PyLdbControlObject *ctrl;
294         if (ctl_ctx == NULL) {
295                 PyErr_NoMemory();
296                 return NULL;
297         }
298
299         ctrl = (PyLdbControlObject *)PyLdbControl.tp_alloc(&PyLdbControl, 0);
300         if (ctrl == NULL) {
301                 talloc_free(ctl_ctx);
302                 PyErr_NoMemory();
303                 return NULL;
304         }
305         ctrl->mem_ctx = ctl_ctx;
306         ctrl->data = talloc_steal(ctrl->mem_ctx, control);
307         if (ctrl->data == NULL) {
308                 Py_DECREF(ctrl);
309                 PyErr_NoMemory();
310                 return NULL;
311         }
312         return (PyObject*) ctrl;
313 }
314
315 /**
316  * Create a Python object from a ldb_result.
317  *
318  * @param result LDB result to convert
319  * @return Python object with converted result (a list object)
320  */
321 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
322 {
323         PyLdbResultObject *ret;
324         PyObject *list, *controls, *referals;
325         Py_ssize_t i;
326
327         if (result == NULL) {
328                 Py_RETURN_NONE;
329         }
330
331         ret = (PyLdbResultObject *)PyLdbResult.tp_alloc(&PyLdbResult, 0);
332         if (ret == NULL) {
333                 PyErr_NoMemory();
334                 return NULL;
335         }
336
337         list = PyList_New(result->count);
338         if (list == NULL) {
339                 PyErr_NoMemory();
340                 Py_DECREF(ret);
341                 return NULL;
342         }
343
344         for (i = 0; i < result->count; i++) {
345                 PyList_SetItem(list, i, PyLdbMessage_FromMessage(result->msgs[i]));
346         }
347
348         ret->mem_ctx = talloc_new(NULL);
349         if (ret->mem_ctx == NULL) {
350                 Py_DECREF(list);
351                 Py_DECREF(ret);
352                 PyErr_NoMemory();
353                 return NULL;
354         }
355
356         ret->msgs = list;
357
358         if (result->controls) {
359                 i = 0;
360                 while (result->controls[i]) {
361                         i++;
362                 }
363                 controls = PyList_New(i);
364                 if (controls == NULL) {
365                         Py_DECREF(ret);
366                         PyErr_NoMemory();
367                         return NULL;
368                 }
369                 for (i=0; result->controls[i]; i++) {
370                         PyObject *ctrl = (PyObject*) PyLdbControl_FromControl(result->controls[i]);
371                         if (ctrl == NULL) {
372                                 Py_DECREF(ret);
373                                 Py_DECREF(controls);
374                                 PyErr_NoMemory();
375                                 return NULL;
376                         }
377                         PyList_SetItem(controls, i, ctrl);
378                 }
379         } else {
380                 /*
381                  * No controls so we keep an empty list
382                  */
383                 controls = PyList_New(0);
384                 if (controls == NULL) {
385                         Py_DECREF(ret);
386                         PyErr_NoMemory();
387                         return NULL;
388                 }
389         }
390
391         ret->controls = controls;
392
393         i = 0;
394
395         while (result->refs && result->refs[i]) {
396                 i++;
397         }
398
399         referals = PyList_New(i);
400         if (referals == NULL) {
401                 Py_DECREF(ret);
402                 PyErr_NoMemory();
403                 return NULL;
404         }
405
406         for (i = 0;result->refs && result->refs[i]; i++) {
407                 PyList_SetItem(referals, i, PyStr_FromString(result->refs[i]));
408         }
409         ret->referals = referals;
410         return (PyObject *)ret;
411 }
412
413 /**
414  * Create a LDB Result from a Python object.
415  * If conversion fails, NULL will be returned and a Python exception set.
416  *
417  * Note: the result object only includes the messages at the moment; extended
418  * result, controls and referrals are ignored.
419  *
420  * @param mem_ctx Memory context in which to allocate the LDB Result
421  * @param obj Python object to convert
422  * @return a ldb_result, or NULL if the conversion failed
423  */
424 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, 
425                                                PyObject *obj)
426 {
427         struct ldb_result *res;
428         Py_ssize_t i;
429
430         if (obj == Py_None)
431                 return NULL;
432
433         res = talloc_zero(mem_ctx, struct ldb_result);
434         res->count = PyList_Size(obj);
435         res->msgs = talloc_array(res, struct ldb_message *, res->count);
436         for (i = 0; i < res->count; i++) {
437                 PyObject *item = PyList_GetItem(obj, i);
438                 res->msgs[i] = pyldb_Message_AsMessage(item);
439         }
440         return res;
441 }
442
443 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
444 {
445         return PyBool_FromLong(ldb_dn_validate(self->dn));
446 }
447
448 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
449 {
450         return PyBool_FromLong(ldb_dn_is_valid(self->dn));
451 }
452
453 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
454 {
455         return PyBool_FromLong(ldb_dn_is_special(self->dn));
456 }
457
458 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
459 {
460         return PyBool_FromLong(ldb_dn_is_null(self->dn));
461 }
462  
463 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
464 {
465         return PyStr_FromString(ldb_dn_get_casefold(self->dn));
466 }
467
468 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
469 {
470         return PyStr_FromString(ldb_dn_get_linearized(self->dn));
471 }
472
473 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
474 {
475         return PyStr_FromString(ldb_dn_canonical_string(self->dn, self->dn));
476 }
477
478 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
479 {
480         return PyStr_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
481 }
482
483 static PyObject *py_ldb_dn_extended_str(PyLdbDnObject *self, PyObject *args, PyObject *kwargs)
484 {
485         const char * const kwnames[] = { "mode", NULL };
486         int mode = 1;
487         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
488                                          discard_const_p(char *, kwnames),
489                                          &mode))
490                 return NULL;
491         return PyStr_FromString(ldb_dn_get_extended_linearized(self->dn, self->dn, mode));
492 }
493
494 static PyObject *py_ldb_dn_get_extended_component(PyLdbDnObject *self, PyObject *args)
495 {
496         char *name;
497         const struct ldb_val *val;
498
499         if (!PyArg_ParseTuple(args, "s", &name))
500                 return NULL;
501         val = ldb_dn_get_extended_component(self->dn, name);
502         if (val == NULL) {
503                 Py_RETURN_NONE;
504         }
505
506         return PyBytes_FromStringAndSize((const char *)val->data, val->length);
507 }
508
509 static PyObject *py_ldb_dn_set_extended_component(PyLdbDnObject *self, PyObject *args)
510 {
511         char *name;
512         int err;
513         uint8_t *value;
514         Py_ssize_t size = 0;
515
516         if (!PyArg_ParseTuple(args, "sz#", &name, (const char**)&value, &size))
517                 return NULL;
518
519         if (value == NULL) {
520                 err = ldb_dn_set_extended_component(self->dn, name, NULL);
521         } else {
522                 struct ldb_val val;
523                 val.data = (uint8_t *)value;
524                 val.length = size;
525                 err = ldb_dn_set_extended_component(self->dn, name, &val);
526         }
527
528         if (err != LDB_SUCCESS) {
529                 PyErr_SetString(PyExc_TypeError, "Failed to set extended component");
530                 return NULL;
531         }
532
533         Py_RETURN_NONE;
534 }
535
536 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
537 {
538         PyObject *str = PyStr_FromString(ldb_dn_get_linearized(self->dn));
539         PyObject *repr, *result;
540         if (str == NULL)
541                 return NULL;
542         repr = PyObject_Repr(str);
543         if (repr == NULL) {
544                 Py_DECREF(str);
545                 return NULL;
546         }
547         result = PyStr_FromFormat("Dn(%s)", PyStr_AsUTF8(repr));
548         Py_DECREF(str);
549         Py_DECREF(repr);
550         return result;
551 }
552
553 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
554 {
555         char *name;
556
557         if (!PyArg_ParseTuple(args, "s", &name))
558                 return NULL;
559
560         return PyBool_FromLong(ldb_dn_check_special(self->dn, name));
561 }
562
563 static PyObject *py_ldb_dn_richcmp(PyObject *dn1, PyObject *dn2, int op)
564 {
565         int ret;
566         if (!pyldb_Dn_Check(dn2)) {
567                 Py_INCREF(Py_NotImplemented);
568                 return Py_NotImplemented;
569         }
570         ret = ldb_dn_compare(pyldb_Dn_AsDn(dn1), pyldb_Dn_AsDn(dn2));
571         return richcmp(ret, op);
572 }
573
574 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
575 {
576         struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self);
577         struct ldb_dn *parent;
578         PyLdbDnObject *py_ret;
579         TALLOC_CTX *mem_ctx = talloc_new(NULL);
580
581         parent = ldb_dn_get_parent(mem_ctx, dn);
582         if (parent == NULL) {
583                 talloc_free(mem_ctx);
584                 Py_RETURN_NONE;
585         }
586
587         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
588         if (py_ret == NULL) {
589                 PyErr_NoMemory();
590                 talloc_free(mem_ctx);
591                 return NULL;
592         }
593         py_ret->mem_ctx = mem_ctx;
594         py_ret->dn = parent;
595         return (PyObject *)py_ret;
596 }
597
598 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
599 {
600         PyObject *py_other;
601         struct ldb_dn *dn, *other;
602         if (!PyArg_ParseTuple(args, "O", &py_other))
603                 return NULL;
604
605         dn = pyldb_Dn_AsDn((PyObject *)self);
606
607         if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
608                 return NULL;
609
610         return PyBool_FromLong(ldb_dn_add_child(dn, other));
611 }
612
613 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
614 {
615         PyObject *py_other;
616         struct ldb_dn *other, *dn;
617         if (!PyArg_ParseTuple(args, "O", &py_other))
618                 return NULL;
619
620         dn = pyldb_Dn_AsDn((PyObject *)self);
621
622         if (!pyldb_Object_AsDn(NULL, py_other, ldb_dn_get_ldb_context(dn), &other))
623                 return NULL;
624
625         return PyBool_FromLong(ldb_dn_add_base(dn, other));
626 }
627
628 static PyObject *py_ldb_dn_remove_base_components(PyLdbDnObject *self, PyObject *args)
629 {
630         struct ldb_dn *dn;
631         int i;
632         if (!PyArg_ParseTuple(args, "i", &i))
633                 return NULL;
634
635         dn = pyldb_Dn_AsDn((PyObject *)self);
636
637         return PyBool_FromLong(ldb_dn_remove_base_components(dn, i));
638 }
639
640 static PyObject *py_ldb_dn_is_child_of(PyLdbDnObject *self, PyObject *args)
641 {
642         PyObject *py_base;
643         struct ldb_dn *dn, *base;
644         if (!PyArg_ParseTuple(args, "O", &py_base))
645                 return NULL;
646
647         dn = pyldb_Dn_AsDn((PyObject *)self);
648
649         if (!pyldb_Object_AsDn(NULL, py_base, ldb_dn_get_ldb_context(dn), &base))
650                 return NULL;
651
652         return PyBool_FromLong(ldb_dn_compare_base(base, dn) == 0);
653 }
654
655 static PyObject *py_ldb_dn_get_component_name(PyLdbDnObject *self, PyObject *args)
656 {
657         struct ldb_dn *dn;
658         const char *name;
659         unsigned int num = 0;
660
661         if (!PyArg_ParseTuple(args, "I", &num))
662                 return NULL;
663
664         dn = pyldb_Dn_AsDn((PyObject *)self);
665
666         name = ldb_dn_get_component_name(dn, num);
667         if (name == NULL) {
668                 Py_RETURN_NONE;
669         }
670
671         return PyStr_FromString(name);
672 }
673
674 static PyObject *py_ldb_dn_get_component_value(PyLdbDnObject *self, PyObject *args)
675 {
676         struct ldb_dn *dn;
677         const struct ldb_val *val;
678         unsigned int num = 0;
679
680         if (!PyArg_ParseTuple(args, "I", &num))
681                 return NULL;
682
683         dn = pyldb_Dn_AsDn((PyObject *)self);
684
685         val = ldb_dn_get_component_val(dn, num);
686         if (val == NULL) {
687                 Py_RETURN_NONE;
688         }
689
690         return PyStr_FromLdbValue(val);
691 }
692
693 static PyObject *py_ldb_dn_set_component(PyLdbDnObject *self, PyObject *args)
694 {
695         unsigned int num = 0;
696         char *name = NULL, *value = NULL;
697         struct ldb_val val = { NULL, };
698         int err;
699         Py_ssize_t size = 0;
700
701         if (!PyArg_ParseTuple(args, "Iss#", &num, &name, &value, &size))
702                 return NULL;
703
704         val.data = (unsigned char*) value;
705         val.length = size;
706
707         err = ldb_dn_set_component(self->dn, num, name, val);
708         if (err != LDB_SUCCESS) {
709                 PyErr_SetString(PyExc_TypeError, "Failed to set component");
710                 return NULL;
711         }
712
713         Py_RETURN_NONE;
714 }
715
716 static PyObject *py_ldb_dn_get_rdn_name(PyLdbDnObject *self)
717 {
718         struct ldb_dn *dn;
719         const char *name;
720
721         dn = pyldb_Dn_AsDn((PyObject *)self);
722
723         name = ldb_dn_get_rdn_name(dn);
724         if (name == NULL) {
725                 Py_RETURN_NONE;
726         }
727
728         return PyStr_FromString(name);
729 }
730
731 static PyObject *py_ldb_dn_get_rdn_value(PyLdbDnObject *self)
732 {
733         struct ldb_dn *dn;
734         const struct ldb_val *val;
735
736         dn = pyldb_Dn_AsDn((PyObject *)self);
737
738         val = ldb_dn_get_rdn_val(dn);
739         if (val == NULL) {
740                 Py_RETURN_NONE;
741         }
742
743         return PyStr_FromLdbValue(val);
744 }
745
746 static PyMethodDef py_ldb_dn_methods[] = {
747         { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, 
748                 "S.validate() -> bool\n"
749                 "Validate DN is correct." },
750         { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
751                 "S.is_valid() -> bool\n" },
752         { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
753                 "S.is_special() -> bool\n"
754                 "Check whether this is a special LDB DN." },
755         { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
756                 "Check whether this is a null DN." },
757         { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
758                 NULL },
759         { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
760                 NULL },
761         { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
762                 "S.canonical_str() -> string\n"
763                 "Canonical version of this DN (like a posix path)." },
764         { "is_child_of", (PyCFunction)py_ldb_dn_is_child_of, METH_VARARGS,
765                 "S.is_child_of(basedn) -> int\nReturns True if this DN is a child of basedn\n"},
766         { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
767                 "S.canonical_ex_str() -> string\n"
768                 "Canonical version of this DN (like a posix path, with terminating newline)." },
769         { "extended_str", (PyCFunction)py_ldb_dn_extended_str, METH_VARARGS | METH_KEYWORDS,
770                 "S.extended_str(mode=1) -> string\n"
771                 "Extended version of this DN" },
772         { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
773                 "S.parent() -> dn\n"
774                 "Get the parent for this DN." },
775         { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS, 
776                 "S.add_child(dn) -> None\n"
777                 "Add a child DN to this DN." },
778         { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
779                 "S.add_base(dn) -> None\n"
780                 "Add a base DN to this DN." },
781         { "remove_base_components", (PyCFunction)py_ldb_dn_remove_base_components, METH_VARARGS,
782                 "S.remove_base_components(int) -> bool\n"
783                 "Remove a number of DN components from the base of this DN." },
784         { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
785                 "S.check_special(name) -> bool\n\n"
786                 "Check if name is a special DN name"},
787         { "get_extended_component", (PyCFunction)py_ldb_dn_get_extended_component, METH_VARARGS,
788                 "S.get_extended_component(name) -> string\n\n"
789                 "returns a DN extended component as a binary string"},
790         { "set_extended_component", (PyCFunction)py_ldb_dn_set_extended_component, METH_VARARGS,
791                 "S.set_extended_component(name, value) -> None\n\n"
792                 "set a DN extended component as a binary string"},
793         { "get_component_name", (PyCFunction)py_ldb_dn_get_component_name, METH_VARARGS,
794                 "S.get_component_name(num) -> string\n"
795                 "get the attribute name of the specified component" },
796         { "get_component_value", (PyCFunction)py_ldb_dn_get_component_value, METH_VARARGS,
797                 "S.get_component_value(num) -> string\n"
798                 "get the attribute value of the specified component as a binary string" },
799         { "set_component", (PyCFunction)py_ldb_dn_set_component, METH_VARARGS,
800                 "S.get_component_value(num, name, value) -> None\n"
801                 "set the attribute name and value of the specified component" },
802         { "get_rdn_name", (PyCFunction)py_ldb_dn_get_rdn_name, METH_NOARGS,
803                 "S.get_rdn_name() -> string\n"
804                 "get the RDN attribute name" },
805         { "get_rdn_value", (PyCFunction)py_ldb_dn_get_rdn_value, METH_NOARGS,
806                 "S.get_rdn_value() -> string\n"
807                 "get the RDN attribute value as a binary string" },
808         { NULL }
809 };
810
811 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
812 {
813         return ldb_dn_get_comp_num(pyldb_Dn_AsDn((PyObject *)self));
814 }
815
816 /*
817   copy a DN as a python object
818  */
819 static PyObject *py_ldb_dn_copy(struct ldb_dn *dn)
820 {
821         PyLdbDnObject *py_ret;
822
823         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
824         if (py_ret == NULL) {
825                 PyErr_NoMemory();
826                 return NULL;
827         }
828         py_ret->mem_ctx = talloc_new(NULL);
829         py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
830         return (PyObject *)py_ret;
831 }
832
833 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
834 {
835         struct ldb_dn *dn = pyldb_Dn_AsDn((PyObject *)self), 
836                                   *other;
837         PyLdbDnObject *py_ret;
838
839         if (!pyldb_Object_AsDn(NULL, py_other, NULL, &other))
840                 return NULL;
841
842         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
843         if (py_ret == NULL) {
844                 PyErr_NoMemory();
845                 return NULL;
846         }
847         py_ret->mem_ctx = talloc_new(NULL);
848         py_ret->dn = ldb_dn_copy(py_ret->mem_ctx, dn);
849         ldb_dn_add_base(py_ret->dn, other);
850         return (PyObject *)py_ret;
851 }
852
853 static PySequenceMethods py_ldb_dn_seq = {
854         .sq_length = (lenfunc)py_ldb_dn_len,
855         .sq_concat = (binaryfunc)py_ldb_dn_concat,
856 };
857
858 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
859 {
860         struct ldb_dn *ret;
861         char *str;
862         PyObject *py_ldb;
863         struct ldb_context *ldb_ctx;
864         TALLOC_CTX *mem_ctx;
865         PyLdbDnObject *py_ret;
866         const char * const kwnames[] = { "ldb", "dn", NULL };
867
868         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
869                                          discard_const_p(char *, kwnames),
870                                          &py_ldb, &str))
871                 return NULL;
872
873         if (!PyLdb_Check(py_ldb)) {
874                 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
875                 return NULL;
876         }
877
878         ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
879
880         mem_ctx = talloc_new(NULL);
881         if (mem_ctx == NULL) {
882                 PyErr_NoMemory();
883                 return NULL;
884         }
885
886         ret = ldb_dn_new(mem_ctx, ldb_ctx, str);
887         if (!ldb_dn_validate(ret)) {
888                 talloc_free(mem_ctx);
889                 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
890                 return NULL;
891         }
892
893         py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
894         if (ret == NULL) {
895                 talloc_free(mem_ctx);
896                 PyErr_NoMemory();
897                 return NULL;
898         }
899         py_ret->mem_ctx = mem_ctx;
900         py_ret->dn = ret;
901         return (PyObject *)py_ret;
902 }
903
904 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
905 {
906         talloc_free(self->mem_ctx);
907         PyObject_Del(self);
908 }
909
910 static PyTypeObject PyLdbDn = {
911         .tp_name = "ldb.Dn",
912         .tp_methods = py_ldb_dn_methods,
913         .tp_str = (reprfunc)py_ldb_dn_get_linearized,
914         .tp_repr = (reprfunc)py_ldb_dn_repr,
915         .tp_richcompare = (richcmpfunc)py_ldb_dn_richcmp,
916         .tp_as_sequence = &py_ldb_dn_seq,
917         .tp_doc = "A LDB distinguished name.",
918         .tp_new = py_ldb_dn_new,
919         .tp_dealloc = (destructor)py_ldb_dn_dealloc,
920         .tp_basicsize = sizeof(PyLdbDnObject),
921         .tp_flags = Py_TPFLAGS_DEFAULT,
922 };
923
924 /* Debug */
925 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
926 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
927 {
928         PyObject *fn = (PyObject *)context;
929         PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyStr_FromFormatV(fmt, ap));
930 }
931
932 static PyObject *py_ldb_debug_func;
933
934 static PyObject *py_ldb_set_debug(PyObject *self, PyObject *args)
935 {
936         PyObject *cb;
937         struct ldb_context *ldb_ctx;
938
939         if (!PyArg_ParseTuple(args, "O", &cb))
940                 return NULL;
941
942         if (py_ldb_debug_func != NULL) {
943                 Py_DECREF(py_ldb_debug_func);
944         }
945
946         Py_INCREF(cb);
947         /* FIXME: DECREF cb when exiting program */
948         py_ldb_debug_func = cb;
949         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
950         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError,
951                 ldb_set_debug(ldb_ctx, py_ldb_debug, cb),
952                 ldb_ctx);
953
954         Py_RETURN_NONE;
955 }
956
957 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
958 {
959         unsigned int perms;
960         if (!PyArg_ParseTuple(args, "I", &perms))
961                 return NULL;
962
963         ldb_set_create_perms(pyldb_Ldb_AsLdbContext(self), perms);
964
965         Py_RETURN_NONE;
966 }
967
968 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
969 {
970         char *modules_dir;
971         if (!PyArg_ParseTuple(args, "s", &modules_dir))
972                 return NULL;
973
974         ldb_set_modules_dir(pyldb_Ldb_AsLdbContext(self), modules_dir);
975
976         Py_RETURN_NONE;
977 }
978
979 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
980 {
981         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
982         int ldb_err;
983         ldb_err = ldb_transaction_start(ldb_ctx);
984         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
985         Py_RETURN_NONE;
986 }
987
988 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
989 {
990         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
991         int ldb_err;
992         ldb_err = ldb_transaction_commit(ldb_ctx);
993         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
994         Py_RETURN_NONE;
995 }
996
997 static PyObject *py_ldb_transaction_prepare_commit(PyLdbObject *self)
998 {
999         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1000         int ldb_err;
1001         ldb_err = ldb_transaction_prepare_commit(ldb_ctx);
1002         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1003         Py_RETURN_NONE;
1004 }
1005
1006 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
1007 {
1008         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1009         int ldb_err;
1010         ldb_err = ldb_transaction_cancel(ldb_ctx);
1011         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1012         Py_RETURN_NONE;
1013 }
1014
1015 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
1016 {
1017         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1018         int ldb_err;
1019         ldb_err = ldb_setup_wellknown_attributes(ldb_ctx);
1020         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ldb_err, ldb_ctx);
1021         Py_RETURN_NONE;
1022 }
1023
1024 static PyObject *py_ldb_repr(PyLdbObject *self)
1025 {
1026         return PyStr_FromString("<ldb connection>");
1027 }
1028
1029 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
1030 {
1031         struct ldb_dn *dn = ldb_get_root_basedn(pyldb_Ldb_AsLdbContext(self));
1032         if (dn == NULL)
1033                 Py_RETURN_NONE;
1034         return py_ldb_dn_copy(dn);
1035 }
1036
1037
1038 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
1039 {
1040         struct ldb_dn *dn = ldb_get_schema_basedn(pyldb_Ldb_AsLdbContext(self));
1041         if (dn == NULL)
1042                 Py_RETURN_NONE;
1043         return py_ldb_dn_copy(dn);
1044 }
1045
1046 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
1047 {
1048         struct ldb_dn *dn = ldb_get_config_basedn(pyldb_Ldb_AsLdbContext(self));
1049         if (dn == NULL)
1050                 Py_RETURN_NONE;
1051         return py_ldb_dn_copy(dn);
1052 }
1053
1054 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
1055 {
1056         struct ldb_dn *dn = ldb_get_default_basedn(pyldb_Ldb_AsLdbContext(self));
1057         if (dn == NULL)
1058                 Py_RETURN_NONE;
1059         return py_ldb_dn_copy(dn);
1060 }
1061
1062 static const char **PyList_AsStrList(TALLOC_CTX *mem_ctx, PyObject *list,
1063                     const char *paramname)
1064 {
1065         const char **ret;
1066         Py_ssize_t i;
1067         if (!PyList_Check(list)) {
1068                 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
1069                 return NULL;
1070         }
1071         ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
1072         if (ret == NULL) {
1073                 PyErr_NoMemory();
1074                 return NULL;
1075         }
1076
1077         for (i = 0; i < PyList_Size(list); i++) {
1078                 const char *str = NULL;
1079                 Py_ssize_t size;
1080                 PyObject *item = PyList_GetItem(list, i);
1081                 if (!PyStr_Check(item)) {
1082                         PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
1083                         talloc_free(ret);
1084                         return NULL;
1085                 }
1086                 str = PyStr_AsUTF8AndSize(item, &size);
1087                 if (str == NULL) {
1088                         talloc_free(ret);
1089                         return NULL;
1090                 }
1091                 ret[i] = talloc_strndup(ret, str, size);
1092         }
1093         ret[i] = NULL;
1094         return ret;
1095 }
1096
1097 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1098 {
1099         const char * const kwnames[] = { "url", "flags", "options", NULL };
1100         char *url = NULL;
1101         PyObject *py_options = Py_None;
1102         const char **options;
1103         unsigned int flags = 0;
1104         int ret;
1105         struct ldb_context *ldb;
1106
1107         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO:Ldb.__init__",
1108                                          discard_const_p(char *, kwnames),
1109                                          &url, &flags, &py_options))
1110                 return -1;
1111
1112         ldb = pyldb_Ldb_AsLdbContext(self);
1113
1114         if (py_options == Py_None) {
1115                 options = NULL;
1116         } else {
1117                 options = PyList_AsStrList(ldb, py_options, "options");
1118                 if (options == NULL)
1119                         return -1;
1120         }
1121
1122         if (url != NULL) {
1123                 ret = ldb_connect(ldb, url, flags, options);
1124                 if (ret != LDB_SUCCESS) {
1125                         PyErr_SetLdbError(PyExc_LdbError, ret, ldb);
1126                         return -1;
1127                 }
1128         }
1129
1130         talloc_free(options);
1131         return 0;
1132 }
1133
1134 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1135 {
1136         PyLdbObject *ret;
1137         struct ldb_context *ldb;
1138         ret = (PyLdbObject *)type->tp_alloc(type, 0);
1139         if (ret == NULL) {
1140                 PyErr_NoMemory();
1141                 return NULL;
1142         }
1143         ret->mem_ctx = talloc_new(NULL);
1144         ldb = ldb_init(ret->mem_ctx, NULL);
1145
1146         if (ldb == NULL) {
1147                 PyErr_NoMemory();
1148                 return NULL;
1149         }
1150
1151         ret->ldb_ctx = ldb;
1152         return (PyObject *)ret;
1153 }
1154
1155 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1156 {
1157         char *url;
1158         unsigned int flags = 0;
1159         PyObject *py_options = Py_None;
1160         int ret;
1161         const char **options;
1162         const char * const kwnames[] = { "url", "flags", "options", NULL };
1163         struct ldb_context *ldb_ctx;
1164
1165         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|zIO",
1166                                          discard_const_p(char *, kwnames),
1167                                          &url, &flags, &py_options))
1168                 return NULL;
1169
1170         if (py_options == Py_None) {
1171                 options = NULL;
1172         } else {
1173                 options = PyList_AsStrList(NULL, py_options, "options");
1174                 if (options == NULL)
1175                         return NULL;
1176         }
1177
1178         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1179         ret = ldb_connect(ldb_ctx, url, flags, options);
1180         talloc_free(options);
1181
1182         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1183
1184         Py_RETURN_NONE;
1185 }
1186
1187 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1188 {
1189         PyObject *py_msg;
1190         PyObject *py_controls = Py_None;
1191         struct ldb_context *ldb_ctx;
1192         struct ldb_request *req;
1193         struct ldb_control **parsed_controls;
1194         struct ldb_message *msg;
1195         int ret;
1196         TALLOC_CTX *mem_ctx;
1197         bool validate=true;
1198         const char * const kwnames[] = { "message", "controls", "validate", NULL };
1199
1200         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Ob",
1201                                          discard_const_p(char *, kwnames),
1202                                          &py_msg, &py_controls, &validate))
1203                 return NULL;
1204
1205         mem_ctx = talloc_new(NULL);
1206         if (mem_ctx == NULL) {
1207                 PyErr_NoMemory();
1208                 return NULL;
1209         }
1210         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1211
1212         if (py_controls == Py_None) {
1213                 parsed_controls = NULL;
1214         } else {
1215                 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1216                 if (controls == NULL) {
1217                         talloc_free(mem_ctx);
1218                         return NULL;
1219                 }
1220                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1221                 talloc_free(controls);
1222         }
1223
1224         if (!PyLdbMessage_Check(py_msg)) {
1225                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
1226                 talloc_free(mem_ctx);
1227                 return NULL;
1228         }
1229         msg = pyldb_Message_AsMessage(py_msg);
1230
1231         if (validate) {
1232                 ret = ldb_msg_sanity_check(ldb_ctx, msg);
1233                 if (ret != LDB_SUCCESS) {
1234                         PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1235                         talloc_free(mem_ctx);
1236                         return NULL;
1237                 }
1238         }
1239
1240         ret = ldb_build_mod_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1241                                 NULL, ldb_op_default_callback, NULL);
1242         if (ret != LDB_SUCCESS) {
1243                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1244                 talloc_free(mem_ctx);
1245                 return NULL;
1246         }
1247
1248         /* do request and autostart a transaction */
1249         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1250
1251         ret = ldb_transaction_start(ldb_ctx);
1252         if (ret != LDB_SUCCESS) {
1253                 talloc_free(mem_ctx);
1254                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1255                 return NULL;
1256         }
1257
1258         ret = ldb_request(ldb_ctx, req);
1259         if (ret == LDB_SUCCESS) {
1260                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1261         }
1262
1263         if (ret == LDB_SUCCESS) {
1264                 ret = ldb_transaction_commit(ldb_ctx);
1265         } else {
1266                 ldb_transaction_cancel(ldb_ctx);
1267         }
1268
1269         talloc_free(mem_ctx);
1270         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1271
1272         Py_RETURN_NONE;
1273 }
1274
1275
1276 /**
1277  * Obtain a ldb message from a Python Dictionary object.
1278  *
1279  * @param mem_ctx Memory context
1280  * @param py_obj Python Dictionary object
1281  * @param ldb_ctx LDB context
1282  * @param mod_flags Flags to be set on every message element
1283  * @return ldb_message on success or NULL on failure
1284  */
1285 static struct ldb_message *PyDict_AsMessage(TALLOC_CTX *mem_ctx,
1286                                             PyObject *py_obj,
1287                                             struct ldb_context *ldb_ctx,
1288                                             unsigned int mod_flags)
1289 {
1290         struct ldb_message *msg;
1291         unsigned int msg_pos = 0;
1292         Py_ssize_t dict_pos = 0;
1293         PyObject *key, *value;
1294         struct ldb_message_element *msg_el;
1295         PyObject *dn_value = PyDict_GetItemString(py_obj, "dn");
1296
1297         msg = ldb_msg_new(mem_ctx);
1298         if (msg == NULL) {
1299                 PyErr_NoMemory();
1300                 return NULL;
1301         }
1302         msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_obj));
1303
1304         if (dn_value) {
1305                 if (!pyldb_Object_AsDn(msg, dn_value, ldb_ctx, &msg->dn)) {
1306                         PyErr_SetString(PyExc_TypeError, "unable to import dn object");
1307                         return NULL;
1308                 }
1309                 if (msg->dn == NULL) {
1310                         PyErr_SetString(PyExc_TypeError, "dn set but not found");
1311                         return NULL;
1312                 }
1313         } else {
1314                 PyErr_SetString(PyExc_TypeError, "no dn set");
1315                 return NULL;
1316         }
1317
1318         while (PyDict_Next(py_obj, &dict_pos, &key, &value)) {
1319                 char *key_str = PyStr_AsUTF8(key);
1320                 if (ldb_attr_cmp(key_str, "dn") != 0) {
1321                         msg_el = PyObject_AsMessageElement(msg->elements, value,
1322                                                            mod_flags, key_str);
1323                         if (msg_el == NULL) {
1324                                 PyErr_Format(PyExc_TypeError, "unable to import element '%s'", key_str);
1325                                 return NULL;
1326                         }
1327                         memcpy(&msg->elements[msg_pos], msg_el, sizeof(*msg_el));
1328                         msg_pos++;
1329                 }
1330         }
1331
1332         msg->num_elements = msg_pos;
1333
1334         return msg;
1335 }
1336
1337 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1338 {
1339         PyObject *py_obj;
1340         int ret;
1341         struct ldb_context *ldb_ctx;
1342         struct ldb_request *req;
1343         struct ldb_message *msg = NULL;
1344         PyObject *py_controls = Py_None;
1345         TALLOC_CTX *mem_ctx;
1346         struct ldb_control **parsed_controls;
1347         const char * const kwnames[] = { "message", "controls", NULL };
1348
1349         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1350                                          discard_const_p(char *, kwnames),
1351                                          &py_obj, &py_controls))
1352                 return NULL;
1353
1354         mem_ctx = talloc_new(NULL);
1355         if (mem_ctx == NULL) {
1356                 PyErr_NoMemory();
1357                 return NULL;
1358         }
1359         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1360
1361         if (py_controls == Py_None) {
1362                 parsed_controls = NULL;
1363         } else {
1364                 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1365                 if (controls == NULL) {
1366                         talloc_free(mem_ctx);
1367                         return NULL;
1368                 }
1369                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1370                 talloc_free(controls);
1371         }
1372
1373         if (PyLdbMessage_Check(py_obj)) {
1374                 msg = pyldb_Message_AsMessage(py_obj);
1375         } else if (PyDict_Check(py_obj)) {
1376                 msg = PyDict_AsMessage(mem_ctx, py_obj, ldb_ctx, LDB_FLAG_MOD_ADD);
1377         } else {
1378                 PyErr_SetString(PyExc_TypeError,
1379                                 "Dictionary or LdbMessage object expected!");
1380         }
1381
1382         if (!msg) {
1383                 /* we should have a PyErr already set */
1384                 talloc_free(mem_ctx);
1385                 return NULL;
1386         }
1387
1388         ret = ldb_msg_sanity_check(ldb_ctx, msg);
1389         if (ret != LDB_SUCCESS) {
1390                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1391                 talloc_free(mem_ctx);
1392                 return NULL;
1393         }
1394
1395         ret = ldb_build_add_req(&req, ldb_ctx, mem_ctx, msg, parsed_controls,
1396                                 NULL, ldb_op_default_callback, NULL);
1397         if (ret != LDB_SUCCESS) {
1398                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1399                 talloc_free(mem_ctx);
1400                 return NULL;
1401         }
1402
1403         /* do request and autostart a transaction */
1404         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1405
1406         ret = ldb_transaction_start(ldb_ctx);
1407         if (ret != LDB_SUCCESS) {
1408                 talloc_free(mem_ctx);
1409                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1410                 return NULL;
1411         }
1412
1413         ret = ldb_request(ldb_ctx, req);
1414         if (ret == LDB_SUCCESS) {
1415                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1416         }
1417
1418         if (ret == LDB_SUCCESS) {
1419                 ret = ldb_transaction_commit(ldb_ctx);
1420         } else {
1421                 ldb_transaction_cancel(ldb_ctx);
1422         }
1423
1424         talloc_free(mem_ctx);
1425         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1426
1427         Py_RETURN_NONE;
1428 }
1429
1430 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1431 {
1432         PyObject *py_dn;
1433         struct ldb_dn *dn;
1434         int ret;
1435         struct ldb_context *ldb_ctx;
1436         struct ldb_request *req;
1437         PyObject *py_controls = Py_None;
1438         TALLOC_CTX *mem_ctx;
1439         struct ldb_control **parsed_controls;
1440         const char * const kwnames[] = { "dn", "controls", NULL };
1441
1442         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O",
1443                                          discard_const_p(char *, kwnames),
1444                                          &py_dn, &py_controls))
1445                 return NULL;
1446
1447         mem_ctx = talloc_new(NULL);
1448         if (mem_ctx == NULL) {
1449                 PyErr_NoMemory();
1450                 return NULL;
1451         }
1452         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1453
1454         if (py_controls == Py_None) {
1455                 parsed_controls = NULL;
1456         } else {
1457                 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1458                 if (controls == NULL) {
1459                         talloc_free(mem_ctx);
1460                         return NULL;
1461                 }
1462                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1463                 talloc_free(controls);
1464         }
1465
1466         if (!pyldb_Object_AsDn(mem_ctx, py_dn, ldb_ctx, &dn)) {
1467                 talloc_free(mem_ctx);
1468                 return NULL;
1469         }
1470
1471         ret = ldb_build_del_req(&req, ldb_ctx, mem_ctx, dn, parsed_controls,
1472                                 NULL, ldb_op_default_callback, NULL);
1473         if (ret != LDB_SUCCESS) {
1474                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1475                 talloc_free(mem_ctx);
1476                 return NULL;
1477         }
1478
1479         /* do request and autostart a transaction */
1480         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1481
1482         ret = ldb_transaction_start(ldb_ctx);
1483         if (ret != LDB_SUCCESS) {
1484                 talloc_free(mem_ctx);
1485                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1486                 return NULL;
1487         }
1488
1489         ret = ldb_request(ldb_ctx, req);
1490         if (ret == LDB_SUCCESS) {
1491                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1492         }
1493
1494         if (ret == LDB_SUCCESS) {
1495                 ret = ldb_transaction_commit(ldb_ctx);
1496         } else {
1497                 ldb_transaction_cancel(ldb_ctx);
1498         }
1499
1500         talloc_free(mem_ctx);
1501         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1502
1503         Py_RETURN_NONE;
1504 }
1505
1506 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1507 {
1508         PyObject *py_dn1, *py_dn2;
1509         struct ldb_dn *dn1, *dn2;
1510         int ret;
1511         TALLOC_CTX *mem_ctx;
1512         PyObject *py_controls = Py_None;
1513         struct ldb_control **parsed_controls;
1514         struct ldb_context *ldb_ctx;
1515         struct ldb_request *req;
1516         const char * const kwnames[] = { "dn1", "dn2", "controls", NULL };
1517
1518         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1519
1520         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|O",
1521                                          discard_const_p(char *, kwnames),
1522                                          &py_dn1, &py_dn2, &py_controls))
1523                 return NULL;
1524
1525
1526         mem_ctx = talloc_new(NULL);
1527         if (mem_ctx == NULL) {
1528                 PyErr_NoMemory();
1529                 return NULL;
1530         }
1531
1532         if (py_controls == Py_None) {
1533                 parsed_controls = NULL;
1534         } else {
1535                 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1536                 if (controls == NULL) {
1537                         talloc_free(mem_ctx);
1538                         return NULL;
1539                 }
1540                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1541                 talloc_free(controls);
1542         }
1543
1544
1545         if (!pyldb_Object_AsDn(mem_ctx, py_dn1, ldb_ctx, &dn1)) {
1546                 talloc_free(mem_ctx);
1547                 return NULL;
1548         }
1549
1550         if (!pyldb_Object_AsDn(mem_ctx, py_dn2, ldb_ctx, &dn2)) {
1551                 talloc_free(mem_ctx);
1552                 return NULL;
1553         }
1554
1555         ret = ldb_build_rename_req(&req, ldb_ctx, mem_ctx, dn1, dn2, parsed_controls,
1556                                 NULL, ldb_op_default_callback, NULL);
1557         if (ret != LDB_SUCCESS) {
1558                 PyErr_SetString(PyExc_TypeError, "failed to build request");
1559                 talloc_free(mem_ctx);
1560                 return NULL;
1561         }
1562
1563         /* do request and autostart a transaction */
1564         /* Then let's LDB handle the message error in case of pb as they are meaningful */
1565
1566         ret = ldb_transaction_start(ldb_ctx);
1567         if (ret != LDB_SUCCESS) {
1568                 talloc_free(mem_ctx);
1569                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1570                 return NULL;
1571         }
1572
1573         ret = ldb_request(ldb_ctx, req);
1574         if (ret == LDB_SUCCESS) {
1575                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1576         }
1577
1578         if (ret == LDB_SUCCESS) {
1579                 ret = ldb_transaction_commit(ldb_ctx);
1580         } else {
1581                 ldb_transaction_cancel(ldb_ctx);
1582         }
1583
1584         talloc_free(mem_ctx);
1585         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1586
1587         Py_RETURN_NONE;
1588 }
1589
1590 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
1591 {
1592         char *name;
1593         if (!PyArg_ParseTuple(args, "s", &name))
1594                 return NULL;
1595
1596         ldb_schema_attribute_remove(pyldb_Ldb_AsLdbContext(self), name);
1597
1598         Py_RETURN_NONE;
1599 }
1600
1601 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
1602 {
1603         char *attribute, *syntax;
1604         unsigned int flags;
1605         int ret;
1606         struct ldb_context *ldb_ctx;
1607
1608         if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
1609                 return NULL;
1610
1611         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1612         ret = ldb_schema_attribute_add(ldb_ctx, attribute, flags, syntax);
1613
1614         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb_ctx);
1615
1616         Py_RETURN_NONE;
1617 }
1618
1619 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
1620 {
1621         if (ldif == NULL) {
1622                 Py_RETURN_NONE;
1623         } else {
1624         /* We don't want this attached to the 'ldb' any more */
1625                 return Py_BuildValue(discard_const_p(char, "(iO)"),
1626                                      ldif->changetype,
1627                                      PyLdbMessage_FromMessage(ldif->msg));
1628         }
1629 }
1630
1631
1632 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1633 {
1634         int changetype;
1635         PyObject *py_msg;
1636         struct ldb_ldif ldif;
1637         PyObject *ret;
1638         char *string;
1639         TALLOC_CTX *mem_ctx;
1640
1641         if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1642                 return NULL;
1643
1644         if (!PyLdbMessage_Check(py_msg)) {
1645                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1646                 return NULL;
1647         }
1648
1649         ldif.msg = pyldb_Message_AsMessage(py_msg);
1650         ldif.changetype = changetype;
1651
1652         mem_ctx = talloc_new(NULL);
1653
1654         string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1655         if (!string) {
1656                 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1657                 return NULL;
1658         }
1659
1660         ret = PyStr_FromString(string);
1661
1662         talloc_free(mem_ctx);
1663
1664         return ret;
1665 }
1666
1667 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1668 {
1669         PyObject *list, *ret;
1670         struct ldb_ldif *ldif;
1671         const char *s;
1672
1673         TALLOC_CTX *mem_ctx;
1674
1675         if (!PyArg_ParseTuple(args, "s", &s))
1676                 return NULL;
1677
1678         mem_ctx = talloc_new(NULL);
1679         if (!mem_ctx) {
1680                 Py_RETURN_NONE;
1681         }
1682
1683         list = PyList_New(0);
1684         while (s && *s != '\0') {
1685                 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1686                 talloc_steal(mem_ctx, ldif);
1687                 if (ldif) {
1688                         PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1689                 } else {
1690                         PyErr_SetString(PyExc_ValueError, "unable to parse ldif string");
1691                         talloc_free(mem_ctx);
1692                         return NULL;
1693                 }
1694         }
1695         talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1696         ret = PyObject_GetIter(list);
1697         Py_DECREF(list);
1698         return ret;
1699 }
1700
1701 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1702 {
1703         int ldb_ret;
1704         PyObject *py_msg_old;
1705         PyObject *py_msg_new;
1706         struct ldb_message *diff;
1707         struct ldb_context *ldb;
1708         PyObject *py_ret;
1709
1710         if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1711                 return NULL;
1712
1713         if (!PyLdbMessage_Check(py_msg_old)) {
1714                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1715                 return NULL;
1716         }
1717
1718         if (!PyLdbMessage_Check(py_msg_new)) {
1719                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1720                 return NULL;
1721         }
1722
1723         ldb = pyldb_Ldb_AsLdbContext(self);
1724         ldb_ret = ldb_msg_difference(ldb, ldb,
1725                                      pyldb_Message_AsMessage(py_msg_old),
1726                                      pyldb_Message_AsMessage(py_msg_new),
1727                                      &diff);
1728         if (ldb_ret != LDB_SUCCESS) {
1729                 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1730                 return NULL;
1731         }
1732
1733         py_ret = PyLdbMessage_FromMessage(diff);
1734
1735         talloc_unlink(ldb, diff);
1736
1737         return py_ret;
1738 }
1739
1740 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1741 {
1742         const struct ldb_schema_attribute *a;
1743         struct ldb_val old_val;
1744         struct ldb_val new_val;
1745         TALLOC_CTX *mem_ctx;
1746         PyObject *ret;
1747         char *element_name;
1748         PyObject *val;
1749         Py_ssize_t size;
1750         int result;
1751
1752         if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1753                 return NULL;
1754
1755         result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1756         old_val.length = size;
1757
1758         if (result != 0) {
1759                 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1760                 return NULL;
1761         }
1762
1763         a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1764
1765         if (a == NULL) {
1766                 Py_RETURN_NONE;
1767         }
1768
1769         mem_ctx = talloc_new(NULL);
1770         if (mem_ctx == NULL) {
1771                 PyErr_NoMemory();
1772                 return NULL;
1773         }
1774
1775         if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1776                 talloc_free(mem_ctx);
1777                 Py_RETURN_NONE;
1778         }
1779
1780         ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1781
1782         talloc_free(mem_ctx);
1783
1784         return ret;
1785 }
1786
1787 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1788 {
1789         PyObject *py_base = Py_None;
1790         int scope = LDB_SCOPE_DEFAULT;
1791         char *expr = NULL;
1792         PyObject *py_attrs = Py_None;
1793         PyObject *py_controls = Py_None;
1794         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1795         int ret;
1796         struct ldb_result *res;
1797         struct ldb_request *req;
1798         const char **attrs;
1799         struct ldb_context *ldb_ctx;
1800         struct ldb_control **parsed_controls;
1801         struct ldb_dn *base;
1802         PyObject *py_ret;
1803         TALLOC_CTX *mem_ctx;
1804
1805         /* type "int" rather than "enum" for "scope" is intentional */
1806         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1807                                          discard_const_p(char *, kwnames),
1808                                          &py_base, &scope, &expr, &py_attrs, &py_controls))
1809                 return NULL;
1810
1811
1812         mem_ctx = talloc_new(NULL);
1813         if (mem_ctx == NULL) {
1814                 PyErr_NoMemory();
1815                 return NULL;
1816         }
1817         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1818
1819         if (py_attrs == Py_None) {
1820                 attrs = NULL;
1821         } else {
1822                 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1823                 if (attrs == NULL) {
1824                         talloc_free(mem_ctx);
1825                         return NULL;
1826                 }
1827         }
1828
1829         if (py_base == Py_None) {
1830                 base = ldb_get_default_basedn(ldb_ctx);
1831         } else {
1832                 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1833                         talloc_free(mem_ctx);
1834                         return NULL;
1835                 }
1836         }
1837
1838         if (py_controls == Py_None) {
1839                 parsed_controls = NULL;
1840         } else {
1841                 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1842                 if (controls == NULL) {
1843                         talloc_free(mem_ctx);
1844                         return NULL;
1845                 }
1846                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1847                 talloc_free(controls);
1848         }
1849
1850         res = talloc_zero(mem_ctx, struct ldb_result);
1851         if (res == NULL) {
1852                 PyErr_NoMemory();
1853                 talloc_free(mem_ctx);
1854                 return NULL;
1855         }
1856
1857         ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1858                                    base,
1859                                    scope,
1860                                    expr,
1861                                    attrs,
1862                                    parsed_controls,
1863                                    res,
1864                                    ldb_search_default_callback,
1865                                    NULL);
1866
1867         if (ret != LDB_SUCCESS) {
1868                 talloc_free(mem_ctx);
1869                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1870                 return NULL;
1871         }
1872
1873         talloc_steal(req, attrs);
1874
1875         ret = ldb_request(ldb_ctx, req);
1876
1877         if (ret == LDB_SUCCESS) {
1878                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1879         }
1880
1881         if (ret != LDB_SUCCESS) {
1882                 talloc_free(mem_ctx);
1883                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1884                 return NULL;
1885         }
1886
1887         py_ret = PyLdbResult_FromResult(res);
1888
1889         talloc_free(mem_ctx);
1890
1891         return py_ret;
1892 }
1893
1894 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
1895 {
1896         if (reply->py_iter != NULL) {
1897                 DLIST_REMOVE(reply->py_iter->state.next, reply);
1898                 if (reply->py_iter->state.result == reply) {
1899                         reply->py_iter->state.result = NULL;
1900                 }
1901                 reply->py_iter = NULL;
1902         }
1903
1904         if (reply->obj != NULL) {
1905                 Py_DECREF(reply->obj);
1906                 reply->obj = NULL;
1907         }
1908
1909         return 0;
1910 }
1911
1912 static int py_ldb_search_iterator_callback(struct ldb_request *req,
1913                                            struct ldb_reply *ares)
1914 {
1915         PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
1916         struct ldb_result result = { .msgs = NULL };
1917         struct py_ldb_search_iterator_reply *reply = NULL;
1918
1919         if (ares == NULL) {
1920                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1921         }
1922
1923         if (ares->error != LDB_SUCCESS) {
1924                 int ret = ares->error;
1925                 TALLOC_FREE(ares);
1926                 return ldb_request_done(req, ret);
1927         }
1928
1929         reply = talloc_zero(py_iter->mem_ctx,
1930                             struct py_ldb_search_iterator_reply);
1931         if (reply == NULL) {
1932                 TALLOC_FREE(ares);
1933                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1934         }
1935         reply->py_iter = py_iter;
1936         talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
1937
1938         switch (ares->type) {
1939         case LDB_REPLY_ENTRY:
1940                 reply->obj = PyLdbMessage_FromMessage(ares->message);
1941                 if (reply->obj == NULL) {
1942                         TALLOC_FREE(ares);
1943                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1944                 }
1945                 DLIST_ADD_END(py_iter->state.next, reply);
1946                 TALLOC_FREE(ares);
1947                 return LDB_SUCCESS;
1948
1949         case LDB_REPLY_REFERRAL:
1950                 reply->obj = PyStr_FromString(ares->referral);
1951                 if (reply->obj == NULL) {
1952                         TALLOC_FREE(ares);
1953                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1954                 }
1955                 DLIST_ADD_END(py_iter->state.next, reply);
1956                 TALLOC_FREE(ares);
1957                 return LDB_SUCCESS;
1958
1959         case LDB_REPLY_DONE:
1960                 result = (struct ldb_result) { .controls = ares->controls };
1961                 reply->obj = PyLdbResult_FromResult(&result);
1962                 if (reply->obj == NULL) {
1963                         TALLOC_FREE(ares);
1964                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1965                 }
1966                 py_iter->state.result = reply;
1967                 TALLOC_FREE(ares);
1968                 return ldb_request_done(req, LDB_SUCCESS);
1969         }
1970
1971         TALLOC_FREE(ares);
1972         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1973 }
1974
1975 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1976 {
1977         PyObject *py_base = Py_None;
1978         int scope = LDB_SCOPE_DEFAULT;
1979         int timeout = 0;
1980         char *expr = NULL;
1981         PyObject *py_attrs = Py_None;
1982         PyObject *py_controls = Py_None;
1983         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
1984         int ret;
1985         const char **attrs;
1986         struct ldb_context *ldb_ctx;
1987         struct ldb_control **parsed_controls;
1988         struct ldb_dn *base;
1989         PyLdbSearchIteratorObject *py_iter;
1990
1991         /* type "int" rather than "enum" for "scope" is intentional */
1992         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
1993                                          discard_const_p(char *, kwnames),
1994                                          &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
1995                 return NULL;
1996
1997         py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
1998         if (py_iter == NULL) {
1999                 PyErr_NoMemory();
2000                 return NULL;
2001         }
2002         py_iter->ldb = self;
2003         Py_INCREF(self);
2004         ZERO_STRUCT(py_iter->state);
2005         py_iter->mem_ctx = talloc_new(NULL);
2006         if (py_iter->mem_ctx == NULL) {
2007                 Py_DECREF(py_iter);
2008                 PyErr_NoMemory();
2009                 return NULL;
2010         }
2011
2012         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2013
2014         if (py_attrs == Py_None) {
2015                 attrs = NULL;
2016         } else {
2017                 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2018                 if (attrs == NULL) {
2019                         Py_DECREF(py_iter);
2020                         PyErr_NoMemory();
2021                         return NULL;
2022                 }
2023         }
2024
2025         if (py_base == Py_None) {
2026                 base = ldb_get_default_basedn(ldb_ctx);
2027         } else {
2028                 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2029                         Py_DECREF(py_iter);
2030                         PyErr_NoMemory();
2031                         return NULL;
2032                 }
2033         }
2034
2035         if (py_controls == Py_None) {
2036                 parsed_controls = NULL;
2037         } else {
2038                 const char **controls = NULL;
2039
2040                 controls = PyList_AsStrList(py_iter->mem_ctx,
2041                                             py_controls, "controls");
2042                 if (controls == NULL) {
2043                         Py_DECREF(py_iter);
2044                         PyErr_NoMemory();
2045                         return NULL;
2046                 }
2047
2048                 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2049                                                             py_iter->mem_ctx,
2050                                                             controls);
2051                 if (controls[0] != NULL && parsed_controls == NULL) {
2052                         Py_DECREF(py_iter);
2053                         PyErr_NoMemory();
2054                         return NULL;
2055                 }
2056                 talloc_free(controls);
2057         }
2058
2059         ret = ldb_build_search_req(&py_iter->state.req,
2060                                    ldb_ctx,
2061                                    py_iter->mem_ctx,
2062                                    base,
2063                                    scope,
2064                                    expr,
2065                                    attrs,
2066                                    parsed_controls,
2067                                    py_iter,
2068                                    py_ldb_search_iterator_callback,
2069                                    NULL);
2070         if (ret != LDB_SUCCESS) {
2071                 Py_DECREF(py_iter);
2072                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2073                 return NULL;
2074         }
2075
2076         ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2077
2078         ret = ldb_request(ldb_ctx, py_iter->state.req);
2079         if (ret != LDB_SUCCESS) {
2080                 Py_DECREF(py_iter);
2081                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2082                 return NULL;
2083         }
2084
2085         return (PyObject *)py_iter;
2086 }
2087
2088 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2089 {
2090         char *name;
2091         void *data;
2092
2093         if (!PyArg_ParseTuple(args, "s", &name))
2094                 return NULL;
2095
2096         data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
2097
2098         if (data == NULL)
2099                 Py_RETURN_NONE;
2100
2101         /* FIXME: More interpretation */
2102
2103         Py_RETURN_TRUE;
2104 }
2105
2106 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2107 {
2108         char *name;
2109         PyObject *data;
2110
2111         if (!PyArg_ParseTuple(args, "sO", &name, &data))
2112                 return NULL;
2113
2114         /* FIXME: More interpretation */
2115
2116         ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
2117
2118         Py_RETURN_NONE;
2119 }
2120
2121 static PyObject *py_ldb_modules(PyLdbObject *self)
2122 {
2123         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2124         PyObject *ret = PyList_New(0);
2125         struct ldb_module *mod;
2126
2127         for (mod = ldb->modules; mod; mod = mod->next) {
2128                 PyList_Append(ret, PyLdbModule_FromModule(mod));
2129         }
2130
2131         return ret;
2132 }
2133
2134 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2135 {
2136         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2137         int type, ret;
2138         uint64_t value;
2139
2140         if (!PyArg_ParseTuple(args, "i", &type))
2141                 return NULL;
2142
2143         /* FIXME: More interpretation */
2144
2145         ret = ldb_sequence_number(ldb, type, &value);
2146
2147         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2148
2149         return PyLong_FromLongLong(value);
2150 }
2151
2152
2153 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2154         .name             = "TEST",
2155         .read_fn          = ldb_handler_copy,
2156         .write_clear_fn   = ldb_handler_copy,
2157         .write_hex_fn     = ldb_handler_copy,
2158 };
2159
2160 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self)
2161 {
2162         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2163         int ret;
2164
2165         ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2166
2167         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2168
2169         Py_RETURN_NONE;
2170 }
2171
2172
2173 static PyMethodDef py_ldb_methods[] = {
2174         { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, 
2175                 "S.set_debug(callback) -> None\n"
2176                 "Set callback for LDB debug messages.\n"
2177                 "The callback should accept a debug level and debug text." },
2178         { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, 
2179                 "S.set_create_perms(mode) -> None\n"
2180                 "Set mode to use when creating new LDB files." },
2181         { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2182                 "S.set_modules_dir(path) -> None\n"
2183                 "Set path LDB should search for modules" },
2184         { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, 
2185                 "S.transaction_start() -> None\n"
2186                 "Start a new transaction." },
2187         { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2188                 "S.transaction_prepare_commit() -> None\n"
2189                 "prepare to commit a new transaction (2-stage commit)." },
2190         { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, 
2191                 "S.transaction_commit() -> None\n"
2192                 "commit a new transaction." },
2193         { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, 
2194                 "S.transaction_cancel() -> None\n"
2195                 "cancel a new transaction." },
2196         { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, 
2197                 NULL },
2198         { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2199                 NULL },
2200         { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2201                 NULL },
2202         { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2203                 NULL },
2204         { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2205                 NULL },
2206         { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, 
2207                 "S.connect(url, flags=0, options=None) -> None\n"
2208                 "Connect to a LDB URL." },
2209         { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
2210                 "S.modify(message, controls=None, validate=False) -> None\n"
2211                 "Modify an entry." },
2212         { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
2213                 "S.add(message, controls=None) -> None\n"
2214                 "Add an entry." },
2215         { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
2216                 "S.delete(dn, controls=None) -> None\n"
2217                 "Remove an entry." },
2218         { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
2219                 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2220                 "Rename an entry." },
2221         { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
2222                 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2223                 "Search in a database.\n"
2224                 "\n"
2225                 ":param base: Optional base DN to search\n"
2226                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2227                 ":param expression: Optional search expression\n"
2228                 ":param attrs: Attributes to return (defaults to all)\n"
2229                 ":param controls: Optional list of controls\n"
2230                 ":return: ldb.Result object\n"
2231         },
2232         { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS,
2233                 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2234                 "Search in a database.\n"
2235                 "\n"
2236                 ":param base: Optional base DN to search\n"
2237                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2238                 ":param expression: Optional search expression\n"
2239                 ":param attrs: Attributes to return (defaults to all)\n"
2240                 ":param controls: Optional list of controls\n"
2241                 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2242                 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2243         },
2244         { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2245                 NULL },
2246         { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2247                 NULL },
2248         { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2249                 NULL },
2250         { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2251                 "S.parse_ldif(ldif) -> iter(messages)\n"
2252                 "Parse a string formatted using LDIF." },
2253         { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2254                 "S.write_ldif(message, changetype) -> ldif\n"
2255                 "Print the message as a string formatted using LDIF." },
2256         { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2257                 "S.msg_diff(Message) -> Message\n"
2258                 "Return an LDB Message of the difference between two Message objects." },
2259         { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2260                 "S.get_opaque(name) -> value\n"
2261                 "Get an opaque value set on this LDB connection. \n"
2262                 ":note: The returned value may not be useful in Python."
2263         },
2264         { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2265                 "S.set_opaque(name, value) -> None\n"
2266                 "Set an opaque value on this LDB connection. \n"
2267                 ":note: Passing incorrect values may cause crashes." },
2268         { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2269                 "S.modules() -> list\n"
2270                 "Return the list of modules on this LDB connection " },
2271         { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2272                 "S.sequence_number(type) -> value\n"
2273                 "Return the value of the sequence according to the requested type" },
2274         { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2275                 "S._register_test_extensions() -> None\n"
2276                 "Register internal extensions used in testing" },
2277         { NULL },
2278 };
2279
2280 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2281 {
2282         PyLdbModuleObject *ret;
2283
2284         ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2285         if (ret == NULL) {
2286                 PyErr_NoMemory();
2287                 return NULL;
2288         }
2289         ret->mem_ctx = talloc_new(NULL);
2290         ret->mod = talloc_reference(ret->mem_ctx, mod);
2291         return (PyObject *)ret;
2292 }
2293
2294 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2295 {
2296         struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2297         if (mod == NULL) {
2298                 Py_RETURN_NONE;
2299         }
2300         return PyLdbModule_FromModule(mod);
2301 }
2302
2303 static PyGetSetDef py_ldb_getset[] = {
2304         { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
2305         { NULL }
2306 };
2307
2308 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2309 {
2310         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2311         struct ldb_dn *dn;
2312         struct ldb_result *result;
2313         unsigned int count;
2314         int ret;
2315
2316         if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2317                 return -1;
2318         }
2319
2320         ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2321                          NULL);
2322         if (ret != LDB_SUCCESS) {
2323                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2324                 return -1;
2325         }
2326
2327         count = result->count;
2328
2329         talloc_free(result);
2330
2331         if (count > 1) {
2332                 PyErr_Format(PyExc_RuntimeError,
2333                              "Searching for [%s] dn gave %u results!",
2334                              ldb_dn_get_linearized(dn),
2335                              count);
2336                 return -1;
2337         }
2338
2339         return count;
2340 }
2341
2342 static PySequenceMethods py_ldb_seq = {
2343         .sq_contains = (objobjproc)py_ldb_contains,
2344 };
2345
2346 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2347 {
2348         PyLdbObject *ret;
2349
2350         ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2351         if (ret == NULL) {
2352                 PyErr_NoMemory();
2353                 return NULL;
2354         }
2355         ret->mem_ctx = talloc_new(NULL);
2356         ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2357         return (PyObject *)ret;
2358 }
2359
2360 static void py_ldb_dealloc(PyLdbObject *self)
2361 {
2362         talloc_free(self->mem_ctx);
2363         Py_TYPE(self)->tp_free(self);
2364 }
2365
2366 static PyTypeObject PyLdb = {
2367         .tp_name = "ldb.Ldb",
2368         .tp_methods = py_ldb_methods,
2369         .tp_repr = (reprfunc)py_ldb_repr,
2370         .tp_new = py_ldb_new,
2371         .tp_init = (initproc)py_ldb_init,
2372         .tp_dealloc = (destructor)py_ldb_dealloc,
2373         .tp_getset = py_ldb_getset,
2374         .tp_getattro = PyObject_GenericGetAttr,
2375         .tp_basicsize = sizeof(PyLdbObject),
2376         .tp_doc = "Connection to a LDB database.",
2377         .tp_as_sequence = &py_ldb_seq,
2378         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2379 };
2380
2381 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2382 {
2383         talloc_free(self->mem_ctx);
2384         Py_DECREF(self->msgs);
2385         Py_DECREF(self->referals);
2386         Py_DECREF(self->controls);
2387         Py_TYPE(self)->tp_free(self);
2388 }
2389
2390 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2391 {
2392         Py_INCREF(self->msgs);
2393         return self->msgs;
2394 }
2395
2396 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2397 {
2398         Py_INCREF(self->controls);
2399         return self->controls;
2400 }
2401
2402 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2403 {
2404         Py_INCREF(self->referals);
2405         return self->referals;
2406 }
2407
2408 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2409 {
2410         Py_ssize_t size;
2411         if (self->msgs == NULL) {
2412                 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2413                 return NULL;
2414         }
2415         size = PyList_Size(self->msgs);
2416         return PyInt_FromLong(size);
2417 }
2418
2419 static PyGetSetDef py_ldb_result_getset[] = {
2420         { discard_const_p(char, "controls"), (getter)py_ldb_result_get_controls, NULL, NULL },
2421         { discard_const_p(char, "msgs"), (getter)py_ldb_result_get_msgs, NULL, NULL },
2422         { discard_const_p(char, "referals"), (getter)py_ldb_result_get_referals, NULL, NULL },
2423         { discard_const_p(char, "count"), (getter)py_ldb_result_get_count, NULL, NULL },
2424         { NULL }
2425 };
2426
2427 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2428 {
2429         return PyObject_GetIter(self->msgs);
2430 }
2431
2432 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2433 {
2434         return PySequence_Size(self->msgs);
2435 }
2436
2437 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2438 {
2439         return PySequence_GetItem(self->msgs, idx);
2440 }
2441
2442 static PySequenceMethods py_ldb_result_seq = {
2443         .sq_length = (lenfunc)py_ldb_result_len,
2444         .sq_item = (ssizeargfunc)py_ldb_result_find,
2445 };
2446
2447 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2448 {
2449         return PyStr_FromString("<ldb result>");
2450 }
2451
2452
2453 static PyTypeObject PyLdbResult = {
2454         .tp_name = "ldb.Result",
2455         .tp_repr = (reprfunc)py_ldb_result_repr,
2456         .tp_dealloc = (destructor)py_ldb_result_dealloc,
2457         .tp_iter = (getiterfunc)py_ldb_result_iter,
2458         .tp_getset = py_ldb_result_getset,
2459         .tp_getattro = PyObject_GenericGetAttr,
2460         .tp_basicsize = sizeof(PyLdbResultObject),
2461         .tp_as_sequence = &py_ldb_result_seq,
2462         .tp_doc = "LDB result.",
2463         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2464 };
2465
2466 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2467 {
2468         Py_XDECREF(self->state.exception);
2469         TALLOC_FREE(self->mem_ctx);
2470         ZERO_STRUCT(self->state);
2471         Py_DECREF(self->ldb);
2472         Py_TYPE(self)->tp_free(self);
2473 }
2474
2475 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2476 {
2477         PyObject *py_ret = NULL;
2478
2479         if (self->state.req == NULL) {
2480                 PyErr_SetString(PyExc_RuntimeError,
2481                                 "ldb.SearchIterator request already finished");
2482                 return NULL;
2483         }
2484
2485         /*
2486          * TODO: do we want a non-blocking mode?
2487          * In future we may add an optional 'nonblocking'
2488          * argument to search_iterator().
2489          *
2490          * For now we keep it simple and wait for at
2491          * least one reply.
2492          */
2493
2494         while (self->state.next == NULL) {
2495                 int ret;
2496
2497                 if (self->state.result != NULL) {
2498                         /*
2499                          * We (already) got a final result from the server.
2500                          *
2501                          * We stop the iteration and let
2502                          * py_ldb_search_iterator_result() will deliver
2503                          * the result details.
2504                          */
2505                         TALLOC_FREE(self->state.req);
2506                         PyErr_SetNone(PyExc_StopIteration);
2507                         return NULL;
2508                 }
2509
2510                 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2511                 if (ret != LDB_SUCCESS) {
2512                         struct ldb_context *ldb_ctx;
2513                         TALLOC_FREE(self->state.req);
2514                         ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb);
2515                         /*
2516                          * We stop the iteration and let
2517                          * py_ldb_search_iterator_result() will deliver
2518                          * the exception.
2519                          */
2520                         self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2521                                                 ret, ldb_errstring(ldb_ctx));
2522                         PyErr_SetNone(PyExc_StopIteration);
2523                         return NULL;
2524                 }
2525         }
2526
2527         py_ret = self->state.next->obj;
2528         self->state.next->obj = NULL;
2529         /* no TALLOC_FREE() as self->state.next is a list */
2530         talloc_free(self->state.next);
2531         return py_ret;
2532 }
2533
2534 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self)
2535 {
2536         PyObject *py_ret = NULL;
2537
2538         if (self->state.req != NULL) {
2539                 PyErr_SetString(PyExc_RuntimeError,
2540                                 "ldb.SearchIterator request running");
2541                 return NULL;
2542         }
2543
2544         if (self->state.next != NULL) {
2545                 PyErr_SetString(PyExc_RuntimeError,
2546                                 "ldb.SearchIterator not fully consumed.");
2547                 return NULL;
2548         }
2549
2550         if (self->state.exception != NULL) {
2551                 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2552                 self->state.exception = NULL;
2553                 return NULL;
2554         }
2555
2556         if (self->state.result == NULL) {
2557                 PyErr_SetString(PyExc_RuntimeError,
2558                                 "ldb.SearchIterator result already consumed");
2559                 return NULL;
2560         }
2561
2562         py_ret = self->state.result->obj;
2563         self->state.result->obj = NULL;
2564         TALLOC_FREE(self->state.result);
2565         return py_ret;
2566 }
2567
2568 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self)
2569 {
2570         if (self->state.req == NULL) {
2571                 PyErr_SetString(PyExc_RuntimeError,
2572                                 "ldb.SearchIterator request already finished");
2573                 return NULL;
2574         }
2575
2576         Py_XDECREF(self->state.exception);
2577         TALLOC_FREE(self->mem_ctx);
2578         ZERO_STRUCT(self->state);
2579         Py_RETURN_NONE;
2580 }
2581
2582 static PyMethodDef py_ldb_search_iterator_methods[] = {
2583         { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2584                 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2585         { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2586                 "S.abandon()\n" },
2587         { NULL }
2588 };
2589
2590 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2591 {
2592         return PyStr_FromString("<ldb search iterator>");
2593 }
2594
2595 static PyTypeObject PyLdbSearchIterator = {
2596         .tp_name = "ldb.SearchIterator",
2597         .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2598         .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2599         .tp_iter = PyObject_SelfIter,
2600         .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2601         .tp_methods = py_ldb_search_iterator_methods,
2602         .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2603         .tp_doc = "LDB search_iterator.",
2604         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2605 };
2606
2607 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2608 {
2609         return PyStr_FromFormat("<ldb module '%s'>",
2610                 pyldb_Module_AsModule(self)->ops->name);
2611 }
2612
2613 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2614 {
2615         return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
2616 }
2617
2618 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2619 {
2620         pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2621         Py_RETURN_NONE;
2622 }
2623
2624 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2625 {
2626         pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2627         Py_RETURN_NONE;
2628 }
2629
2630 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2631 {
2632         pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2633         Py_RETURN_NONE;
2634 }
2635
2636 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2637 {
2638         PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2639         int ret, scope;
2640         struct ldb_request *req;
2641         const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2642         struct ldb_module *mod;
2643         const char * const*attrs;
2644
2645         /* type "int" rather than "enum" for "scope" is intentional */
2646         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2647                                          discard_const_p(char *, kwnames),
2648                                          &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2649                 return NULL;
2650
2651         mod = self->mod;
2652
2653         if (py_attrs == Py_None) {
2654                 attrs = NULL;
2655         } else {
2656                 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2657                 if (attrs == NULL)
2658                         return NULL;
2659         }
2660
2661         ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base), 
2662                              scope, NULL /* expr */, attrs,
2663                              NULL /* controls */, NULL, NULL, NULL);
2664
2665         talloc_steal(req, attrs);
2666
2667         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2668
2669         req->op.search.res = NULL;
2670
2671         ret = mod->ops->search(mod, req);
2672
2673         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2674
2675         py_ret = PyLdbResult_FromResult(req->op.search.res);
2676
2677         talloc_free(req);
2678
2679         return py_ret;
2680 }
2681
2682
2683 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2684 {
2685         struct ldb_request *req;
2686         PyObject *py_message;
2687         int ret;
2688         struct ldb_module *mod;
2689
2690         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2691                 return NULL;
2692
2693         req = talloc_zero(NULL, struct ldb_request);
2694         req->operation = LDB_ADD;
2695         req->op.add.message = pyldb_Message_AsMessage(py_message);
2696
2697         mod = pyldb_Module_AsModule(self);
2698         ret = mod->ops->add(mod, req);
2699
2700         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2701
2702         Py_RETURN_NONE;
2703 }
2704
2705 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) 
2706 {
2707         int ret;
2708         struct ldb_request *req;
2709         PyObject *py_message;
2710         struct ldb_module *mod;
2711
2712         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2713                 return NULL;
2714
2715         req = talloc_zero(NULL, struct ldb_request);
2716         req->operation = LDB_MODIFY;
2717         req->op.mod.message = pyldb_Message_AsMessage(py_message);
2718
2719         mod = pyldb_Module_AsModule(self);
2720         ret = mod->ops->modify(mod, req);
2721
2722         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2723
2724         Py_RETURN_NONE;
2725 }
2726
2727 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) 
2728 {
2729         int ret;
2730         struct ldb_request *req;
2731         PyObject *py_dn;
2732
2733         if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2734                 return NULL;
2735
2736         req = talloc_zero(NULL, struct ldb_request);
2737         req->operation = LDB_DELETE;
2738         req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2739
2740         ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2741
2742         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2743
2744         Py_RETURN_NONE;
2745 }
2746
2747 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2748 {
2749         int ret;
2750         struct ldb_request *req;
2751         PyObject *py_dn1, *py_dn2;
2752
2753         if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2754                 return NULL;
2755
2756         req = talloc_zero(NULL, struct ldb_request);
2757
2758         req->operation = LDB_RENAME;
2759         req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2760         req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2761
2762         ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2763
2764         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2765
2766         Py_RETURN_NONE;
2767 }
2768
2769 static PyMethodDef py_ldb_module_methods[] = {
2770         { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2771         { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2772         { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2773         { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2774         { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2775         { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2776         { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2777         { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2778         { NULL },
2779 };
2780
2781 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2782 {
2783         talloc_free(self->mem_ctx);
2784         PyObject_Del(self);
2785 }
2786
2787 static PyTypeObject PyLdbModule = {
2788         .tp_name = "ldb.LdbModule",
2789         .tp_methods = py_ldb_module_methods,
2790         .tp_repr = (reprfunc)py_ldb_module_repr,
2791         .tp_str = (reprfunc)py_ldb_module_str,
2792         .tp_basicsize = sizeof(PyLdbModuleObject),
2793         .tp_dealloc = (destructor)py_ldb_module_dealloc,
2794         .tp_flags = Py_TPFLAGS_DEFAULT,
2795         .tp_doc = "LDB module (extension)",
2796 };
2797
2798
2799 /**
2800  * Create a ldb_message_element from a Python object.
2801  *
2802  * This will accept any sequence objects that contains strings, or 
2803  * a string object.
2804  *
2805  * A reference to set_obj will be borrowed. 
2806  *
2807  * @param mem_ctx Memory context
2808  * @param set_obj Python object to convert
2809  * @param flags ldb_message_element flags to set
2810  * @param attr_name Name of the attribute
2811  * @return New ldb_message_element, allocated as child of mem_ctx
2812  */
2813 static struct ldb_message_element *PyObject_AsMessageElement(
2814                                                       TALLOC_CTX *mem_ctx,
2815                                                       PyObject *set_obj,
2816                                                       unsigned int flags,
2817                                                       const char *attr_name)
2818 {
2819         struct ldb_message_element *me;
2820         const char *msg = NULL;
2821         Py_ssize_t size;
2822         int result;
2823
2824         if (pyldb_MessageElement_Check(set_obj)) {
2825                 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2826                 /* We have to talloc_reference() the memory context, not the pointer
2827                  * which may not actually be it's own context */
2828                 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2829                         return pyldb_MessageElement_AsMessageElement(set_obj);
2830                 }
2831                 return NULL;
2832         }
2833
2834         me = talloc(mem_ctx, struct ldb_message_element);
2835         if (me == NULL) {
2836                 PyErr_NoMemory();
2837                 return NULL;
2838         }
2839
2840         me->name = talloc_strdup(me, attr_name);
2841         me->flags = flags;
2842         if (PyBytes_Check(set_obj) || PyStr_Check(set_obj)) {
2843                 me->num_values = 1;
2844                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2845                 if (PyBytes_Check(set_obj)) {
2846                         char *_msg = NULL;
2847                         result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
2848                         if (result != 0) {
2849                                 talloc_free(me);
2850                                 return NULL;
2851                         }
2852                         msg = _msg;
2853                 } else {
2854                         msg = PyStr_AsUTF8AndSize(set_obj, &size);
2855                         if (msg == NULL) {
2856                                 talloc_free(me);
2857                                 return NULL;
2858                         }
2859                 }
2860                 me->values[0].data = talloc_memdup(me,
2861                                                    (const uint8_t *)msg,
2862                                                    size+1);
2863                 me->values[0].length = size;
2864         } else if (PySequence_Check(set_obj)) {
2865                 Py_ssize_t i;
2866                 me->num_values = PySequence_Size(set_obj);
2867                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2868                 for (i = 0; i < me->num_values; i++) {
2869                         PyObject *obj = PySequence_GetItem(set_obj, i);
2870                         if (PyBytes_Check(obj)) {
2871                                 char *_msg = NULL;
2872                                 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
2873                                 if (result != 0) {
2874                                         talloc_free(me);
2875                                         return NULL;
2876                                 }
2877                                 msg = _msg;
2878                         } else if (PyStr_Check(obj)) {
2879                                 msg = PyStr_AsUTF8AndSize(obj, &size);
2880                                 if (msg == NULL) {
2881                                         talloc_free(me);
2882                                         return NULL;
2883                                 }
2884                         } else {
2885                                 PyErr_Format(PyExc_TypeError,
2886                                              "Expected string as element %zd in list", i);
2887                                 talloc_free(me);
2888                                 return NULL;
2889                         }
2890                         me->values[i].data = talloc_memdup(me,
2891                                                            (const uint8_t *)msg,
2892                                                            size+1);
2893                         me->values[i].length = size;
2894                 }
2895         } else {
2896                 PyErr_Format(PyExc_TypeError,
2897                              "String or List type expected for '%s' attribute", attr_name);
2898                 talloc_free(me);
2899                 me = NULL;
2900         }
2901
2902         return me;
2903 }
2904
2905
2906 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2907                                         struct ldb_message_element *me)
2908 {
2909         Py_ssize_t i;
2910         PyObject *result;
2911
2912         /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2913         result = PyList_New(me->num_values);
2914
2915         for (i = 0; i < me->num_values; i++) {
2916                 PyList_SetItem(result, i,
2917                         PyObject_FromLdbValue(&me->values[i]));
2918         }
2919
2920         return result;
2921 }
2922
2923 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2924 {
2925         unsigned int i;
2926         if (!PyArg_ParseTuple(args, "I", &i))
2927                 return NULL;
2928         if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2929                 Py_RETURN_NONE;
2930
2931         return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2932 }
2933
2934 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2935 {
2936         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2937         return PyInt_FromLong(el->flags);
2938 }
2939
2940 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2941 {
2942         unsigned int flags;
2943         struct ldb_message_element *el;
2944         if (!PyArg_ParseTuple(args, "I", &flags))
2945                 return NULL;
2946
2947         el = pyldb_MessageElement_AsMessageElement(self);
2948         el->flags = flags;
2949         Py_RETURN_NONE;
2950 }
2951
2952 static PyMethodDef py_ldb_msg_element_methods[] = {
2953         { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2954         { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2955         { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2956         { NULL },
2957 };
2958
2959 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2960 {
2961         return pyldb_MessageElement_AsMessageElement(self)->num_values;
2962 }
2963
2964 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2965 {
2966         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2967         if (idx < 0 || idx >= el->num_values) {
2968                 PyErr_SetString(PyExc_IndexError, "Out of range");
2969                 return NULL;
2970         }
2971         return PyBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2972 }
2973
2974 static PySequenceMethods py_ldb_msg_element_seq = {
2975         .sq_length = (lenfunc)py_ldb_msg_element_len,
2976         .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2977 };
2978
2979 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
2980 {
2981         int ret;
2982         if (!pyldb_MessageElement_Check(other)) {
2983                 Py_INCREF(Py_NotImplemented);
2984                 return Py_NotImplemented;
2985         }
2986         ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2987                                                                           pyldb_MessageElement_AsMessageElement(other));
2988         return richcmp(ret, op);
2989 }
2990
2991 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2992 {
2993         PyObject *el = ldb_msg_element_to_set(NULL,
2994                                               pyldb_MessageElement_AsMessageElement(self));
2995         PyObject *ret = PyObject_GetIter(el);
2996         Py_DECREF(el);
2997         return ret;
2998 }
2999
3000 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3001 {
3002         PyLdbMessageElementObject *ret;
3003         ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3004         if (ret == NULL) {
3005                 PyErr_NoMemory();
3006                 return NULL;
3007         }
3008         ret->mem_ctx = talloc_new(NULL);
3009         if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
3010                 PyErr_NoMemory();
3011                 return NULL;
3012         }
3013         ret->el = el;
3014         return (PyObject *)ret;
3015 }
3016
3017 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3018 {
3019         PyObject *py_elements = NULL;
3020         struct ldb_message_element *el;
3021         unsigned int flags = 0;
3022         char *name = NULL;
3023         const char * const kwnames[] = { "elements", "flags", "name", NULL };
3024         PyLdbMessageElementObject *ret;
3025         TALLOC_CTX *mem_ctx;
3026         const char *msg = NULL;
3027         Py_ssize_t size;
3028         int result;
3029
3030         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3031                                          discard_const_p(char *, kwnames),
3032                                          &py_elements, &flags, &name))
3033                 return NULL;
3034
3035         mem_ctx = talloc_new(NULL);
3036         if (mem_ctx == NULL) {
3037                 PyErr_NoMemory();
3038                 return NULL;
3039         }
3040
3041         el = talloc_zero(mem_ctx, struct ldb_message_element);
3042         if (el == NULL) {
3043                 PyErr_NoMemory();
3044                 talloc_free(mem_ctx);
3045                 return NULL;
3046         }
3047
3048         if (py_elements != NULL) {
3049                 Py_ssize_t i;
3050                 if (PyBytes_Check(py_elements) || PyStr_Check(py_elements)) {
3051                         char *_msg = NULL;
3052                         el->num_values = 1;
3053                         el->values = talloc_array(el, struct ldb_val, 1);
3054                         if (el->values == NULL) {
3055                                 talloc_free(mem_ctx);
3056                                 PyErr_NoMemory();
3057                                 return NULL;
3058                         }
3059                         if (PyBytes_Check(py_elements)) {
3060                                 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3061                                 msg = _msg;
3062                         } else {
3063                                 msg = PyStr_AsUTF8AndSize(py_elements, &size);
3064                                 result = (msg == NULL) ? -1 : 0;
3065                         }
3066                         if (result != 0) {
3067                                 talloc_free(mem_ctx);
3068                                 return NULL;
3069                         }
3070                         el->values[0].data = talloc_memdup(el->values, 
3071                                 (const uint8_t *)msg, size + 1);
3072                         el->values[0].length = size;
3073                 } else if (PySequence_Check(py_elements)) {
3074                         el->num_values = PySequence_Size(py_elements);
3075                         el->values = talloc_array(el, struct ldb_val, el->num_values);
3076                         if (el->values == NULL) {
3077                                 talloc_free(mem_ctx);
3078                                 PyErr_NoMemory();
3079                                 return NULL;
3080                         }
3081                         for (i = 0; i < el->num_values; i++) {
3082                                 PyObject *item = PySequence_GetItem(py_elements, i);
3083                                 if (item == NULL) {
3084                                         talloc_free(mem_ctx);
3085                                         return NULL;
3086                                 }
3087                                 if (PyBytes_Check(item)) {
3088                                         char *_msg = NULL;
3089                                         result = PyBytes_AsStringAndSize(item, &_msg, &size);
3090                                         msg = _msg;
3091                                 } else if (PyStr_Check(item)) {
3092                                         msg = PyStr_AsUTF8AndSize(item, &size);
3093                                         result = (msg == NULL) ? -1 : 0;
3094                                 } else {
3095                                         PyErr_Format(PyExc_TypeError, 
3096                                                      "Expected string as element %zd in list", i);
3097                                         result = -1;
3098                                 }
3099                                 if (result != 0) {
3100                                         talloc_free(mem_ctx);
3101                                         return NULL;
3102                                 }
3103                                 el->values[i].data = talloc_memdup(el,
3104                                         (const uint8_t *)msg, size+1);
3105                                 el->values[i].length = size;
3106                         }
3107                 } else {
3108                         PyErr_SetString(PyExc_TypeError, 
3109                                         "Expected string or list");
3110                         talloc_free(mem_ctx);
3111                         return NULL;
3112                 }
3113         }
3114
3115         el->flags = flags;
3116         el->name = talloc_strdup(el, name);
3117
3118         ret = PyObject_New(PyLdbMessageElementObject, type);
3119         if (ret == NULL) {
3120                 talloc_free(mem_ctx);
3121                 return NULL;
3122         }
3123
3124         ret->mem_ctx = mem_ctx;
3125         ret->el = el;
3126         return (PyObject *)ret;
3127 }
3128
3129 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3130 {
3131         char *element_str = NULL;
3132         Py_ssize_t i;
3133         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3134         PyObject *ret, *repr;
3135
3136         for (i = 0; i < el->num_values; i++) {
3137                 PyObject *o = py_ldb_msg_element_find(self, i);
3138                 repr = PyObject_Repr(o);
3139                 if (element_str == NULL)
3140                         element_str = talloc_strdup(NULL, PyStr_AsUTF8(repr));
3141                 else
3142                         element_str = talloc_asprintf_append(element_str, ",%s", PyStr_AsUTF8(repr));
3143                 Py_DECREF(repr);
3144         }
3145
3146         if (element_str != NULL) {
3147                 ret = PyStr_FromFormat("MessageElement([%s])", element_str);
3148                 talloc_free(element_str);
3149         } else {
3150                 ret = PyStr_FromString("MessageElement([])");
3151         }
3152
3153         return ret;
3154 }
3155
3156 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3157 {
3158         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3159
3160         if (el->num_values == 1)
3161                 return PyStr_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3162         else
3163                 Py_RETURN_NONE;
3164 }
3165
3166 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3167 {
3168         talloc_free(self->mem_ctx);
3169         PyObject_Del(self);
3170 }
3171
3172 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3173 {
3174         return wrap_text("MessageElementTextWrapper", self);
3175 }
3176
3177 static PyGetSetDef py_ldb_msg_element_getset[] = {
3178         { discard_const_p(char, "text"), (getter)py_ldb_msg_element_get_text, NULL, NULL },
3179         { NULL }
3180 };
3181
3182 static PyTypeObject PyLdbMessageElement = {
3183         .tp_name = "ldb.MessageElement",
3184         .tp_basicsize = sizeof(PyLdbMessageElementObject),
3185         .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3186         .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3187         .tp_str = (reprfunc)py_ldb_msg_element_str,
3188         .tp_methods = py_ldb_msg_element_methods,
3189         .tp_getset = py_ldb_msg_element_getset,
3190         .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3191         .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3192         .tp_as_sequence = &py_ldb_msg_element_seq,
3193         .tp_new = py_ldb_msg_element_new,
3194         .tp_flags = Py_TPFLAGS_DEFAULT,
3195         .tp_doc = "An element of a Message",
3196 };
3197
3198
3199 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3200 {
3201         PyObject *py_ldb;
3202         PyObject *py_dict;
3203         PyObject *py_ret;
3204         struct ldb_message *msg;
3205         struct ldb_context *ldb_ctx;
3206         unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3207
3208         if (!PyArg_ParseTuple(args, "O!O!|I",
3209                               &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3210                               &mod_flags)) {
3211                 return NULL;
3212         }
3213
3214         if (!PyLdb_Check(py_ldb)) {
3215                 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
3216                 return NULL;
3217         }
3218
3219         /* mask only flags we are going to use */
3220         mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3221         if (!mod_flags) {
3222                 PyErr_SetString(PyExc_ValueError,
3223                                 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3224                                 " expected as mod_flag value");
3225                 return NULL;
3226         }
3227
3228         ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
3229
3230         msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3231         if (!msg) {
3232                 return NULL;
3233         }
3234
3235         py_ret = PyLdbMessage_FromMessage(msg);
3236
3237         talloc_unlink(ldb_ctx, msg);
3238
3239         return py_ret;
3240 }
3241
3242 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3243 {
3244         char *name;
3245         if (!PyArg_ParseTuple(args, "s", &name))
3246                 return NULL;
3247
3248         ldb_msg_remove_attr(self->msg, name);
3249
3250         Py_RETURN_NONE;
3251 }
3252
3253 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
3254 {
3255         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3256         Py_ssize_t i, j = 0;
3257         PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3258         if (msg->dn != NULL) {
3259                 PyList_SetItem(obj, j, PyStr_FromString("dn"));