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