b2cac8a3497ac6082f9a3cf739a32c2909026f16
[samba.git] / lib / ldb / pyldb.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Python interface to ldb.
5
6    Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7    Copyright (C) 2006 Simo Sorce <idra@samba.org>
8    Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9    Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10    Copyright (C) 2009-2011 Andrew Tridgell
11    Copyright (C) 2009-2011 Andrew Bartlett
12
13     ** NOTE! The following LGPL license applies to the ldb
14     ** library. This does NOT imply that all of Samba is released
15     ** under the LGPL
16
17    This library is free software; you can redistribute it and/or
18    modify it under the terms of the GNU Lesser General Public
19    License as published by the Free Software Foundation; either
20    version 3 of the License, or (at your option) any later version.
21
22    This library is distributed in the hope that it will be useful,
23    but WITHOUT ANY WARRANTY; without even the implied warranty of
24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25    Lesser General Public License for more details.
26
27    You should have received a copy of the GNU Lesser General Public
28    License along with this library; if not, see <http://www.gnu.org/licenses/>.
29 */
30
31 #include <Python.h>
32 #include "ldb_private.h"
33 #include "ldb_handlers.h"
34 #include "pyldb.h"
35 #include "dlinklist.h"
36
37 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, "|zIO",
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                 return Py_BuildValue(discard_const_p(char, "(iO)"),
1677                                      ldif->changetype,
1678                                      PyLdbMessage_FromMessage(ldif->msg));
1679         }
1680 }
1681
1682
1683 static PyObject *py_ldb_write_ldif(PyLdbObject *self, PyObject *args)
1684 {
1685         int changetype;
1686         PyObject *py_msg;
1687         struct ldb_ldif ldif;
1688         PyObject *ret;
1689         char *string;
1690         TALLOC_CTX *mem_ctx;
1691
1692         if (!PyArg_ParseTuple(args, "Oi", &py_msg, &changetype))
1693                 return NULL;
1694
1695         if (!PyLdbMessage_Check(py_msg)) {
1696                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for msg");
1697                 return NULL;
1698         }
1699
1700         ldif.msg = pyldb_Message_AsMessage(py_msg);
1701         ldif.changetype = changetype;
1702
1703         mem_ctx = talloc_new(NULL);
1704
1705         string = ldb_ldif_write_string(pyldb_Ldb_AsLdbContext(self), mem_ctx, &ldif);
1706         if (!string) {
1707                 PyErr_SetString(PyExc_KeyError, "Failed to generate LDIF");
1708                 return NULL;
1709         }
1710
1711         ret = PyStr_FromString(string);
1712
1713         talloc_free(mem_ctx);
1714
1715         return ret;
1716 }
1717
1718 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
1719 {
1720         PyObject *list, *ret;
1721         struct ldb_ldif *ldif;
1722         const char *s;
1723         struct ldb_dn *last_dn = NULL;
1724
1725         TALLOC_CTX *mem_ctx;
1726
1727         if (!PyArg_ParseTuple(args, "s", &s))
1728                 return NULL;
1729
1730         mem_ctx = talloc_new(NULL);
1731         if (!mem_ctx) {
1732                 Py_RETURN_NONE;
1733         }
1734
1735         list = PyList_New(0);
1736         while (s && *s != '\0') {
1737                 ldif = ldb_ldif_read_string(self->ldb_ctx, &s);
1738                 talloc_steal(mem_ctx, ldif);
1739                 if (ldif) {
1740                         PyList_Append(list, ldb_ldif_to_pyobject(ldif));
1741                         last_dn = ldif->msg->dn;
1742                 } else {
1743                         const char *last_dn_str = NULL;
1744                         const char *err_string = NULL;
1745                         if (last_dn == NULL) {
1746                                 PyErr_SetString(PyExc_ValueError,
1747                                                 "unable to parse LDIF "
1748                                                 "string at first chunk");
1749                                 talloc_free(mem_ctx);
1750                                 return NULL;
1751                         }
1752
1753                         last_dn_str
1754                                 = ldb_dn_get_linearized(last_dn);
1755
1756                         err_string
1757                                 = talloc_asprintf(mem_ctx,
1758                                                   "unable to parse ldif "
1759                                                   "string AFTER %s",
1760                                                   last_dn_str);
1761
1762                         PyErr_SetString(PyExc_ValueError,
1763                                         err_string);
1764                         talloc_free(mem_ctx);
1765                         return NULL;
1766                 }
1767         }
1768         talloc_free(mem_ctx); /* The pyobject already has a reference to the things it needs */
1769         ret = PyObject_GetIter(list);
1770         Py_DECREF(list);
1771         return ret;
1772 }
1773
1774 static PyObject *py_ldb_msg_diff(PyLdbObject *self, PyObject *args)
1775 {
1776         int ldb_ret;
1777         PyObject *py_msg_old;
1778         PyObject *py_msg_new;
1779         struct ldb_message *diff;
1780         struct ldb_context *ldb;
1781         PyObject *py_ret;
1782
1783         if (!PyArg_ParseTuple(args, "OO", &py_msg_old, &py_msg_new))
1784                 return NULL;
1785
1786         if (!PyLdbMessage_Check(py_msg_old)) {
1787                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for old message");
1788                 return NULL;
1789         }
1790
1791         if (!PyLdbMessage_Check(py_msg_new)) {
1792                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message for new message");
1793                 return NULL;
1794         }
1795
1796         ldb = pyldb_Ldb_AsLdbContext(self);
1797         ldb_ret = ldb_msg_difference(ldb, ldb,
1798                                      pyldb_Message_AsMessage(py_msg_old),
1799                                      pyldb_Message_AsMessage(py_msg_new),
1800                                      &diff);
1801         if (ldb_ret != LDB_SUCCESS) {
1802                 PyErr_SetString(PyExc_RuntimeError, "Failed to generate the Ldb Message diff");
1803                 return NULL;
1804         }
1805
1806         py_ret = PyLdbMessage_FromMessage(diff);
1807
1808         talloc_unlink(ldb, diff);
1809
1810         return py_ret;
1811 }
1812
1813 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
1814 {
1815         const struct ldb_schema_attribute *a;
1816         struct ldb_val old_val;
1817         struct ldb_val new_val;
1818         TALLOC_CTX *mem_ctx;
1819         PyObject *ret;
1820         char *element_name;
1821         PyObject *val;
1822         Py_ssize_t size;
1823         int result;
1824
1825         if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
1826                 return NULL;
1827
1828         result = PyBytes_AsStringAndSize(val, (char **)&old_val.data, &size);
1829         old_val.length = size;
1830
1831         if (result != 0) {
1832                 PyErr_SetString(PyExc_RuntimeError, "Failed to convert passed value to String");
1833                 return NULL;
1834         }
1835
1836         a = ldb_schema_attribute_by_name(pyldb_Ldb_AsLdbContext(self), element_name);
1837
1838         if (a == NULL) {
1839                 Py_RETURN_NONE;
1840         }
1841
1842         mem_ctx = talloc_new(NULL);
1843         if (mem_ctx == NULL) {
1844                 PyErr_NoMemory();
1845                 return NULL;
1846         }
1847
1848         if (a->syntax->ldif_write_fn(pyldb_Ldb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
1849                 talloc_free(mem_ctx);
1850                 Py_RETURN_NONE;
1851         }
1852
1853         ret = PyBytes_FromStringAndSize((const char *)new_val.data, new_val.length);
1854
1855         talloc_free(mem_ctx);
1856
1857         return ret;
1858 }
1859
1860 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
1861 {
1862         PyObject *py_base = Py_None;
1863         int scope = LDB_SCOPE_DEFAULT;
1864         char *expr = NULL;
1865         PyObject *py_attrs = Py_None;
1866         PyObject *py_controls = Py_None;
1867         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
1868         int ret;
1869         struct ldb_result *res;
1870         struct ldb_request *req;
1871         const char **attrs;
1872         struct ldb_context *ldb_ctx;
1873         struct ldb_control **parsed_controls;
1874         struct ldb_dn *base;
1875         PyObject *py_ret;
1876         TALLOC_CTX *mem_ctx;
1877
1878         /* type "int" rather than "enum" for "scope" is intentional */
1879         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
1880                                          discard_const_p(char *, kwnames),
1881                                          &py_base, &scope, &expr, &py_attrs, &py_controls))
1882                 return NULL;
1883
1884
1885         mem_ctx = talloc_new(NULL);
1886         if (mem_ctx == NULL) {
1887                 PyErr_NoMemory();
1888                 return NULL;
1889         }
1890         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
1891
1892         if (py_attrs == Py_None) {
1893                 attrs = NULL;
1894         } else {
1895                 attrs = PyList_AsStrList(mem_ctx, py_attrs, "attrs");
1896                 if (attrs == NULL) {
1897                         talloc_free(mem_ctx);
1898                         return NULL;
1899                 }
1900         }
1901
1902         if (py_base == Py_None) {
1903                 base = ldb_get_default_basedn(ldb_ctx);
1904         } else {
1905                 if (!pyldb_Object_AsDn(mem_ctx, py_base, ldb_ctx, &base)) {
1906                         talloc_free(mem_ctx);
1907                         return NULL;
1908                 }
1909         }
1910
1911         if (py_controls == Py_None) {
1912                 parsed_controls = NULL;
1913         } else {
1914                 const char **controls = PyList_AsStrList(mem_ctx, py_controls, "controls");
1915                 if (controls == NULL) {
1916                         talloc_free(mem_ctx);
1917                         return NULL;
1918                 }
1919                 parsed_controls = ldb_parse_control_strings(ldb_ctx, mem_ctx, controls);
1920                 talloc_free(controls);
1921         }
1922
1923         res = talloc_zero(mem_ctx, struct ldb_result);
1924         if (res == NULL) {
1925                 PyErr_NoMemory();
1926                 talloc_free(mem_ctx);
1927                 return NULL;
1928         }
1929
1930         ret = ldb_build_search_req(&req, ldb_ctx, mem_ctx,
1931                                    base,
1932                                    scope,
1933                                    expr,
1934                                    attrs,
1935                                    parsed_controls,
1936                                    res,
1937                                    ldb_search_default_callback,
1938                                    NULL);
1939
1940         if (ret != LDB_SUCCESS) {
1941                 talloc_free(mem_ctx);
1942                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1943                 return NULL;
1944         }
1945
1946         talloc_steal(req, attrs);
1947
1948         ret = ldb_request(ldb_ctx, req);
1949
1950         if (ret == LDB_SUCCESS) {
1951                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
1952         }
1953
1954         if (ret != LDB_SUCCESS) {
1955                 talloc_free(mem_ctx);
1956                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
1957                 return NULL;
1958         }
1959
1960         py_ret = PyLdbResult_FromResult(res);
1961
1962         talloc_free(mem_ctx);
1963
1964         return py_ret;
1965 }
1966
1967 static int py_ldb_search_iterator_reply_destructor(struct py_ldb_search_iterator_reply *reply)
1968 {
1969         if (reply->py_iter != NULL) {
1970                 DLIST_REMOVE(reply->py_iter->state.next, reply);
1971                 if (reply->py_iter->state.result == reply) {
1972                         reply->py_iter->state.result = NULL;
1973                 }
1974                 reply->py_iter = NULL;
1975         }
1976
1977         if (reply->obj != NULL) {
1978                 Py_DECREF(reply->obj);
1979                 reply->obj = NULL;
1980         }
1981
1982         return 0;
1983 }
1984
1985 static int py_ldb_search_iterator_callback(struct ldb_request *req,
1986                                            struct ldb_reply *ares)
1987 {
1988         PyLdbSearchIteratorObject *py_iter = (PyLdbSearchIteratorObject *)req->context;
1989         struct ldb_result result = { .msgs = NULL };
1990         struct py_ldb_search_iterator_reply *reply = NULL;
1991
1992         if (ares == NULL) {
1993                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
1994         }
1995
1996         if (ares->error != LDB_SUCCESS) {
1997                 int ret = ares->error;
1998                 TALLOC_FREE(ares);
1999                 return ldb_request_done(req, ret);
2000         }
2001
2002         reply = talloc_zero(py_iter->mem_ctx,
2003                             struct py_ldb_search_iterator_reply);
2004         if (reply == NULL) {
2005                 TALLOC_FREE(ares);
2006                 return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2007         }
2008         reply->py_iter = py_iter;
2009         talloc_set_destructor(reply, py_ldb_search_iterator_reply_destructor);
2010
2011         switch (ares->type) {
2012         case LDB_REPLY_ENTRY:
2013                 reply->obj = PyLdbMessage_FromMessage(ares->message);
2014                 if (reply->obj == NULL) {
2015                         TALLOC_FREE(ares);
2016                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2017                 }
2018                 DLIST_ADD_END(py_iter->state.next, reply);
2019                 TALLOC_FREE(ares);
2020                 return LDB_SUCCESS;
2021
2022         case LDB_REPLY_REFERRAL:
2023                 reply->obj = PyStr_FromString(ares->referral);
2024                 if (reply->obj == NULL) {
2025                         TALLOC_FREE(ares);
2026                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2027                 }
2028                 DLIST_ADD_END(py_iter->state.next, reply);
2029                 TALLOC_FREE(ares);
2030                 return LDB_SUCCESS;
2031
2032         case LDB_REPLY_DONE:
2033                 result = (struct ldb_result) { .controls = ares->controls };
2034                 reply->obj = PyLdbResult_FromResult(&result);
2035                 if (reply->obj == NULL) {
2036                         TALLOC_FREE(ares);
2037                         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2038                 }
2039                 py_iter->state.result = reply;
2040                 TALLOC_FREE(ares);
2041                 return ldb_request_done(req, LDB_SUCCESS);
2042         }
2043
2044         TALLOC_FREE(ares);
2045         return ldb_request_done(req, LDB_ERR_OPERATIONS_ERROR);
2046 }
2047
2048 static PyObject *py_ldb_search_iterator(PyLdbObject *self, PyObject *args, PyObject *kwargs)
2049 {
2050         PyObject *py_base = Py_None;
2051         int scope = LDB_SCOPE_DEFAULT;
2052         int timeout = 0;
2053         char *expr = NULL;
2054         PyObject *py_attrs = Py_None;
2055         PyObject *py_controls = Py_None;
2056         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", "timeout", NULL };
2057         int ret;
2058         const char **attrs;
2059         struct ldb_context *ldb_ctx;
2060         struct ldb_control **parsed_controls;
2061         struct ldb_dn *base;
2062         PyLdbSearchIteratorObject *py_iter;
2063
2064         /* type "int" rather than "enum" for "scope" is intentional */
2065         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOOi",
2066                                          discard_const_p(char *, kwnames),
2067                                          &py_base, &scope, &expr, &py_attrs, &py_controls, &timeout))
2068                 return NULL;
2069
2070         py_iter = (PyLdbSearchIteratorObject *)PyLdbSearchIterator.tp_alloc(&PyLdbSearchIterator, 0);
2071         if (py_iter == NULL) {
2072                 PyErr_NoMemory();
2073                 return NULL;
2074         }
2075         py_iter->ldb = self;
2076         Py_INCREF(self);
2077         ZERO_STRUCT(py_iter->state);
2078         py_iter->mem_ctx = talloc_new(NULL);
2079         if (py_iter->mem_ctx == NULL) {
2080                 Py_DECREF(py_iter);
2081                 PyErr_NoMemory();
2082                 return NULL;
2083         }
2084
2085         ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2086
2087         if (py_attrs == Py_None) {
2088                 attrs = NULL;
2089         } else {
2090                 attrs = PyList_AsStrList(py_iter->mem_ctx, py_attrs, "attrs");
2091                 if (attrs == NULL) {
2092                         Py_DECREF(py_iter);
2093                         PyErr_NoMemory();
2094                         return NULL;
2095                 }
2096         }
2097
2098         if (py_base == Py_None) {
2099                 base = ldb_get_default_basedn(ldb_ctx);
2100         } else {
2101                 if (!pyldb_Object_AsDn(py_iter->mem_ctx, py_base, ldb_ctx, &base)) {
2102                         Py_DECREF(py_iter);
2103                         PyErr_NoMemory();
2104                         return NULL;
2105                 }
2106         }
2107
2108         if (py_controls == Py_None) {
2109                 parsed_controls = NULL;
2110         } else {
2111                 const char **controls = NULL;
2112
2113                 controls = PyList_AsStrList(py_iter->mem_ctx,
2114                                             py_controls, "controls");
2115                 if (controls == NULL) {
2116                         Py_DECREF(py_iter);
2117                         PyErr_NoMemory();
2118                         return NULL;
2119                 }
2120
2121                 parsed_controls = ldb_parse_control_strings(ldb_ctx,
2122                                                             py_iter->mem_ctx,
2123                                                             controls);
2124                 if (controls[0] != NULL && parsed_controls == NULL) {
2125                         Py_DECREF(py_iter);
2126                         PyErr_NoMemory();
2127                         return NULL;
2128                 }
2129                 talloc_free(controls);
2130         }
2131
2132         ret = ldb_build_search_req(&py_iter->state.req,
2133                                    ldb_ctx,
2134                                    py_iter->mem_ctx,
2135                                    base,
2136                                    scope,
2137                                    expr,
2138                                    attrs,
2139                                    parsed_controls,
2140                                    py_iter,
2141                                    py_ldb_search_iterator_callback,
2142                                    NULL);
2143         if (ret != LDB_SUCCESS) {
2144                 Py_DECREF(py_iter);
2145                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2146                 return NULL;
2147         }
2148
2149         ldb_set_timeout(ldb_ctx, py_iter->state.req, timeout);
2150
2151         ret = ldb_request(ldb_ctx, py_iter->state.req);
2152         if (ret != LDB_SUCCESS) {
2153                 Py_DECREF(py_iter);
2154                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2155                 return NULL;
2156         }
2157
2158         return (PyObject *)py_iter;
2159 }
2160
2161 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
2162 {
2163         char *name;
2164         void *data;
2165
2166         if (!PyArg_ParseTuple(args, "s", &name))
2167                 return NULL;
2168
2169         data = ldb_get_opaque(pyldb_Ldb_AsLdbContext(self), name);
2170
2171         if (data == NULL)
2172                 Py_RETURN_NONE;
2173
2174         /* FIXME: More interpretation */
2175
2176         Py_RETURN_TRUE;
2177 }
2178
2179 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
2180 {
2181         char *name;
2182         PyObject *data;
2183
2184         if (!PyArg_ParseTuple(args, "sO", &name, &data))
2185                 return NULL;
2186
2187         /* FIXME: More interpretation */
2188
2189         ldb_set_opaque(pyldb_Ldb_AsLdbContext(self), name, data);
2190
2191         Py_RETURN_NONE;
2192 }
2193
2194 static PyObject *py_ldb_modules(PyLdbObject *self)
2195 {
2196         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2197         PyObject *ret = PyList_New(0);
2198         struct ldb_module *mod;
2199
2200         for (mod = ldb->modules; mod; mod = mod->next) {
2201                 PyList_Append(ret, PyLdbModule_FromModule(mod));
2202         }
2203
2204         return ret;
2205 }
2206
2207 static PyObject *py_ldb_sequence_number(PyLdbObject *self, PyObject *args)
2208 {
2209         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2210         int type, ret;
2211         uint64_t value;
2212
2213         if (!PyArg_ParseTuple(args, "i", &type))
2214                 return NULL;
2215
2216         /* FIXME: More interpretation */
2217
2218         ret = ldb_sequence_number(ldb, type, &value);
2219
2220         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2221
2222         return PyLong_FromLongLong(value);
2223 }
2224
2225
2226 static const struct ldb_dn_extended_syntax test_dn_syntax = {
2227         .name             = "TEST",
2228         .read_fn          = ldb_handler_copy,
2229         .write_clear_fn   = ldb_handler_copy,
2230         .write_hex_fn     = ldb_handler_copy,
2231 };
2232
2233 static PyObject *py_ldb_register_test_extensions(PyLdbObject *self)
2234 {
2235         struct ldb_context *ldb = pyldb_Ldb_AsLdbContext(self);
2236         int ret;
2237
2238         ret = ldb_dn_extended_add_syntax(ldb, LDB_ATTR_FLAG_FIXED, &test_dn_syntax);
2239
2240         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, ldb);
2241
2242         Py_RETURN_NONE;
2243 }
2244
2245
2246 static PyMethodDef py_ldb_methods[] = {
2247         { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, 
2248                 "S.set_debug(callback) -> None\n"
2249                 "Set callback for LDB debug messages.\n"
2250                 "The callback should accept a debug level and debug text." },
2251         { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, 
2252                 "S.set_create_perms(mode) -> None\n"
2253                 "Set mode to use when creating new LDB files." },
2254         { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
2255                 "S.set_modules_dir(path) -> None\n"
2256                 "Set path LDB should search for modules" },
2257         { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, 
2258                 "S.transaction_start() -> None\n"
2259                 "Start a new transaction." },
2260         { "transaction_prepare_commit", (PyCFunction)py_ldb_transaction_prepare_commit, METH_NOARGS,
2261                 "S.transaction_prepare_commit() -> None\n"
2262                 "prepare to commit a new transaction (2-stage commit)." },
2263         { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, 
2264                 "S.transaction_commit() -> None\n"
2265                 "commit a new transaction." },
2266         { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, 
2267                 "S.transaction_cancel() -> None\n"
2268                 "cancel a new transaction." },
2269         { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, 
2270                 NULL },
2271         { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
2272                 NULL },
2273         { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
2274                 NULL },
2275         { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
2276                 NULL },
2277         { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
2278                 NULL },
2279         { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, 
2280                 "S.connect(url, flags=0, options=None) -> None\n"
2281                 "Connect to a LDB URL." },
2282         { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS|METH_KEYWORDS,
2283                 "S.modify(message, controls=None, validate=False) -> None\n"
2284                 "Modify an entry." },
2285         { "add", (PyCFunction)py_ldb_add, METH_VARARGS|METH_KEYWORDS,
2286                 "S.add(message, controls=None) -> None\n"
2287                 "Add an entry." },
2288         { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS|METH_KEYWORDS,
2289                 "S.delete(dn, controls=None) -> None\n"
2290                 "Remove an entry." },
2291         { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS|METH_KEYWORDS,
2292                 "S.rename(old_dn, new_dn, controls=None) -> None\n"
2293                 "Rename an entry." },
2294         { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
2295                 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result\n"
2296                 "Search in a database.\n"
2297                 "\n"
2298                 ":param base: Optional base DN to search\n"
2299                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2300                 ":param expression: Optional search expression\n"
2301                 ":param attrs: Attributes to return (defaults to all)\n"
2302                 ":param controls: Optional list of controls\n"
2303                 ":return: ldb.Result object\n"
2304         },
2305         { "search_iterator", (PyCFunction)py_ldb_search_iterator, METH_VARARGS|METH_KEYWORDS,
2306                 "S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator\n"
2307                 "Search in a database.\n"
2308                 "\n"
2309                 ":param base: Optional base DN to search\n"
2310                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
2311                 ":param expression: Optional search expression\n"
2312                 ":param attrs: Attributes to return (defaults to all)\n"
2313                 ":param controls: Optional list of controls\n"
2314                 ":param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout\n"
2315                 ":return: ldb.SearchIterator object that provides results when they arrive\n"
2316         },
2317         { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
2318                 NULL },
2319         { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
2320                 NULL },
2321         { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
2322                 NULL },
2323         { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
2324                 "S.parse_ldif(ldif) -> iter(messages)\n"
2325                 "Parse a string formatted using LDIF." },
2326         { "write_ldif", (PyCFunction)py_ldb_write_ldif, METH_VARARGS,
2327                 "S.write_ldif(message, changetype) -> ldif\n"
2328                 "Print the message as a string formatted using LDIF." },
2329         { "msg_diff", (PyCFunction)py_ldb_msg_diff, METH_VARARGS,
2330                 "S.msg_diff(Message) -> Message\n"
2331                 "Return an LDB Message of the difference between two Message objects." },
2332         { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
2333                 "S.get_opaque(name) -> value\n"
2334                 "Get an opaque value set on this LDB connection. \n"
2335                 ":note: The returned value may not be useful in Python."
2336         },
2337         { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
2338                 "S.set_opaque(name, value) -> None\n"
2339                 "Set an opaque value on this LDB connection. \n"
2340                 ":note: Passing incorrect values may cause crashes." },
2341         { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
2342                 "S.modules() -> list\n"
2343                 "Return the list of modules on this LDB connection " },
2344         { "sequence_number", (PyCFunction)py_ldb_sequence_number, METH_VARARGS,
2345                 "S.sequence_number(type) -> value\n"
2346                 "Return the value of the sequence according to the requested type" },
2347         { "_register_test_extensions", (PyCFunction)py_ldb_register_test_extensions, METH_NOARGS,
2348                 "S._register_test_extensions() -> None\n"
2349                 "Register internal extensions used in testing" },
2350         { NULL },
2351 };
2352
2353 static PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
2354 {
2355         PyLdbModuleObject *ret;
2356
2357         ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
2358         if (ret == NULL) {
2359                 PyErr_NoMemory();
2360                 return NULL;
2361         }
2362         ret->mem_ctx = talloc_new(NULL);
2363         ret->mod = talloc_reference(ret->mem_ctx, mod);
2364         return (PyObject *)ret;
2365 }
2366
2367 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
2368 {
2369         struct ldb_module *mod = pyldb_Ldb_AsLdbContext(self)->modules;
2370         if (mod == NULL) {
2371                 Py_RETURN_NONE;
2372         }
2373         return PyLdbModule_FromModule(mod);
2374 }
2375
2376 static PyGetSetDef py_ldb_getset[] = {
2377         {
2378                 .name = discard_const_p(char, "firstmodule"),
2379                 .get  = (getter)py_ldb_get_firstmodule,
2380         },
2381         { .name = NULL },
2382 };
2383
2384 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
2385 {
2386         struct ldb_context *ldb_ctx = pyldb_Ldb_AsLdbContext(self);
2387         struct ldb_dn *dn;
2388         struct ldb_result *result;
2389         unsigned int count;
2390         int ret;
2391
2392         if (!pyldb_Object_AsDn(ldb_ctx, obj, ldb_ctx, &dn)) {
2393                 return -1;
2394         }
2395
2396         ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL,
2397                          NULL);
2398         if (ret != LDB_SUCCESS) {
2399                 PyErr_SetLdbError(PyExc_LdbError, ret, ldb_ctx);
2400                 return -1;
2401         }
2402
2403         count = result->count;
2404
2405         talloc_free(result);
2406
2407         if (count > 1) {
2408                 PyErr_Format(PyExc_RuntimeError,
2409                              "Searching for [%s] dn gave %u results!",
2410                              ldb_dn_get_linearized(dn),
2411                              count);
2412                 return -1;
2413         }
2414
2415         return count;
2416 }
2417
2418 static PySequenceMethods py_ldb_seq = {
2419         .sq_contains = (objobjproc)py_ldb_contains,
2420 };
2421
2422 static PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
2423 {
2424         PyLdbObject *ret;
2425
2426         ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
2427         if (ret == NULL) {
2428                 PyErr_NoMemory();
2429                 return NULL;
2430         }
2431         ret->mem_ctx = talloc_new(NULL);
2432         ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
2433         return (PyObject *)ret;
2434 }
2435
2436 static void py_ldb_dealloc(PyLdbObject *self)
2437 {
2438         talloc_free(self->mem_ctx);
2439         Py_TYPE(self)->tp_free(self);
2440 }
2441
2442 static PyTypeObject PyLdb = {
2443         .tp_name = "ldb.Ldb",
2444         .tp_methods = py_ldb_methods,
2445         .tp_repr = (reprfunc)py_ldb_repr,
2446         .tp_new = py_ldb_new,
2447         .tp_init = (initproc)py_ldb_init,
2448         .tp_dealloc = (destructor)py_ldb_dealloc,
2449         .tp_getset = py_ldb_getset,
2450         .tp_getattro = PyObject_GenericGetAttr,
2451         .tp_basicsize = sizeof(PyLdbObject),
2452         .tp_doc = "Connection to a LDB database.",
2453         .tp_as_sequence = &py_ldb_seq,
2454         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2455 };
2456
2457 static void py_ldb_result_dealloc(PyLdbResultObject *self)
2458 {
2459         talloc_free(self->mem_ctx);
2460         Py_DECREF(self->msgs);
2461         Py_DECREF(self->referals);
2462         Py_DECREF(self->controls);
2463         Py_TYPE(self)->tp_free(self);
2464 }
2465
2466 static PyObject *py_ldb_result_get_msgs(PyLdbResultObject *self, void *closure)
2467 {
2468         Py_INCREF(self->msgs);
2469         return self->msgs;
2470 }
2471
2472 static PyObject *py_ldb_result_get_controls(PyLdbResultObject *self, void *closure)
2473 {
2474         Py_INCREF(self->controls);
2475         return self->controls;
2476 }
2477
2478 static PyObject *py_ldb_result_get_referals(PyLdbResultObject *self, void *closure)
2479 {
2480         Py_INCREF(self->referals);
2481         return self->referals;
2482 }
2483
2484 static PyObject *py_ldb_result_get_count(PyLdbResultObject *self, void *closure)
2485 {
2486         Py_ssize_t size;
2487         if (self->msgs == NULL) {
2488                 PyErr_SetString(PyExc_AttributeError, "Count attribute is meaningless in this context");
2489                 return NULL;
2490         }
2491         size = PyList_Size(self->msgs);
2492         return PyInt_FromLong(size);
2493 }
2494
2495 static PyGetSetDef py_ldb_result_getset[] = {
2496         {
2497                 .name = discard_const_p(char, "controls"),
2498                 .get  = (getter)py_ldb_result_get_controls,
2499         },
2500         {
2501                 .name = discard_const_p(char, "msgs"),
2502                 .get  = (getter)py_ldb_result_get_msgs,
2503         },
2504         {
2505                 .name = discard_const_p(char, "referals"),
2506                 .get  = (getter)py_ldb_result_get_referals,
2507         },
2508         {
2509                 .name = discard_const_p(char, "count"),
2510                 .get  = (getter)py_ldb_result_get_count,
2511         },
2512         { .name = NULL },
2513 };
2514
2515 static PyObject *py_ldb_result_iter(PyLdbResultObject *self)
2516 {
2517         return PyObject_GetIter(self->msgs);
2518 }
2519
2520 static Py_ssize_t py_ldb_result_len(PyLdbResultObject *self)
2521 {
2522         return PySequence_Size(self->msgs);
2523 }
2524
2525 static PyObject *py_ldb_result_find(PyLdbResultObject *self, Py_ssize_t idx)
2526 {
2527         return PySequence_GetItem(self->msgs, idx);
2528 }
2529
2530 static PySequenceMethods py_ldb_result_seq = {
2531         .sq_length = (lenfunc)py_ldb_result_len,
2532         .sq_item = (ssizeargfunc)py_ldb_result_find,
2533 };
2534
2535 static PyObject *py_ldb_result_repr(PyLdbObject *self)
2536 {
2537         return PyStr_FromString("<ldb result>");
2538 }
2539
2540
2541 static PyTypeObject PyLdbResult = {
2542         .tp_name = "ldb.Result",
2543         .tp_repr = (reprfunc)py_ldb_result_repr,
2544         .tp_dealloc = (destructor)py_ldb_result_dealloc,
2545         .tp_iter = (getiterfunc)py_ldb_result_iter,
2546         .tp_getset = py_ldb_result_getset,
2547         .tp_getattro = PyObject_GenericGetAttr,
2548         .tp_basicsize = sizeof(PyLdbResultObject),
2549         .tp_as_sequence = &py_ldb_result_seq,
2550         .tp_doc = "LDB result.",
2551         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2552 };
2553
2554 static void py_ldb_search_iterator_dealloc(PyLdbSearchIteratorObject *self)
2555 {
2556         Py_XDECREF(self->state.exception);
2557         TALLOC_FREE(self->mem_ctx);
2558         ZERO_STRUCT(self->state);
2559         Py_DECREF(self->ldb);
2560         Py_TYPE(self)->tp_free(self);
2561 }
2562
2563 static PyObject *py_ldb_search_iterator_next(PyLdbSearchIteratorObject *self)
2564 {
2565         PyObject *py_ret = NULL;
2566
2567         if (self->state.req == NULL) {
2568                 PyErr_SetString(PyExc_RuntimeError,
2569                                 "ldb.SearchIterator request already finished");
2570                 return NULL;
2571         }
2572
2573         /*
2574          * TODO: do we want a non-blocking mode?
2575          * In future we may add an optional 'nonblocking'
2576          * argument to search_iterator().
2577          *
2578          * For now we keep it simple and wait for at
2579          * least one reply.
2580          */
2581
2582         while (self->state.next == NULL) {
2583                 int ret;
2584
2585                 if (self->state.result != NULL) {
2586                         /*
2587                          * We (already) got a final result from the server.
2588                          *
2589                          * We stop the iteration and let
2590                          * py_ldb_search_iterator_result() will deliver
2591                          * the result details.
2592                          */
2593                         TALLOC_FREE(self->state.req);
2594                         PyErr_SetNone(PyExc_StopIteration);
2595                         return NULL;
2596                 }
2597
2598                 ret = ldb_wait(self->state.req->handle, LDB_WAIT_NONE);
2599                 if (ret != LDB_SUCCESS) {
2600                         struct ldb_context *ldb_ctx;
2601                         TALLOC_FREE(self->state.req);
2602                         ldb_ctx = pyldb_Ldb_AsLdbContext(self->ldb);
2603                         /*
2604                          * We stop the iteration and let
2605                          * py_ldb_search_iterator_result() will deliver
2606                          * the exception.
2607                          */
2608                         self->state.exception = Py_BuildValue(discard_const_p(char, "(i,s)"),
2609                                                 ret, ldb_errstring(ldb_ctx));
2610                         PyErr_SetNone(PyExc_StopIteration);
2611                         return NULL;
2612                 }
2613         }
2614
2615         py_ret = self->state.next->obj;
2616         self->state.next->obj = NULL;
2617         /* no TALLOC_FREE() as self->state.next is a list */
2618         talloc_free(self->state.next);
2619         return py_ret;
2620 }
2621
2622 static PyObject *py_ldb_search_iterator_result(PyLdbSearchIteratorObject *self)
2623 {
2624         PyObject *py_ret = NULL;
2625
2626         if (self->state.req != NULL) {
2627                 PyErr_SetString(PyExc_RuntimeError,
2628                                 "ldb.SearchIterator request running");
2629                 return NULL;
2630         }
2631
2632         if (self->state.next != NULL) {
2633                 PyErr_SetString(PyExc_RuntimeError,
2634                                 "ldb.SearchIterator not fully consumed.");
2635                 return NULL;
2636         }
2637
2638         if (self->state.exception != NULL) {
2639                 PyErr_SetObject(PyExc_LdbError, self->state.exception);
2640                 self->state.exception = NULL;
2641                 return NULL;
2642         }
2643
2644         if (self->state.result == NULL) {
2645                 PyErr_SetString(PyExc_RuntimeError,
2646                                 "ldb.SearchIterator result already consumed");
2647                 return NULL;
2648         }
2649
2650         py_ret = self->state.result->obj;
2651         self->state.result->obj = NULL;
2652         TALLOC_FREE(self->state.result);
2653         return py_ret;
2654 }
2655
2656 static PyObject *py_ldb_search_iterator_abandon(PyLdbSearchIteratorObject *self)
2657 {
2658         if (self->state.req == NULL) {
2659                 PyErr_SetString(PyExc_RuntimeError,
2660                                 "ldb.SearchIterator request already finished");
2661                 return NULL;
2662         }
2663
2664         Py_XDECREF(self->state.exception);
2665         TALLOC_FREE(self->mem_ctx);
2666         ZERO_STRUCT(self->state);
2667         Py_RETURN_NONE;
2668 }
2669
2670 static PyMethodDef py_ldb_search_iterator_methods[] = {
2671         { "result", (PyCFunction)py_ldb_search_iterator_result, METH_NOARGS,
2672                 "S.result() -> ldb.Result (without msgs and referrals)\n" },
2673         { "abandon", (PyCFunction)py_ldb_search_iterator_abandon, METH_NOARGS,
2674                 "S.abandon()\n" },
2675         { NULL }
2676 };
2677
2678 static PyObject *py_ldb_search_iterator_repr(PyLdbSearchIteratorObject *self)
2679 {
2680         return PyStr_FromString("<ldb search iterator>");
2681 }
2682
2683 static PyTypeObject PyLdbSearchIterator = {
2684         .tp_name = "ldb.SearchIterator",
2685         .tp_repr = (reprfunc)py_ldb_search_iterator_repr,
2686         .tp_dealloc = (destructor)py_ldb_search_iterator_dealloc,
2687         .tp_iter = PyObject_SelfIter,
2688         .tp_iternext = (iternextfunc)py_ldb_search_iterator_next,
2689         .tp_methods = py_ldb_search_iterator_methods,
2690         .tp_basicsize = sizeof(PyLdbSearchIteratorObject),
2691         .tp_doc = "LDB search_iterator.",
2692         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2693 };
2694
2695 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
2696 {
2697         return PyStr_FromFormat("<ldb module '%s'>",
2698                 pyldb_Module_AsModule(self)->ops->name);
2699 }
2700
2701 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
2702 {
2703         return PyStr_FromString(pyldb_Module_AsModule(self)->ops->name);
2704 }
2705
2706 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
2707 {
2708         pyldb_Module_AsModule(self)->ops->start_transaction(pyldb_Module_AsModule(self));
2709         Py_RETURN_NONE;
2710 }
2711
2712 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
2713 {
2714         pyldb_Module_AsModule(self)->ops->end_transaction(pyldb_Module_AsModule(self));
2715         Py_RETURN_NONE;
2716 }
2717
2718 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
2719 {
2720         pyldb_Module_AsModule(self)->ops->del_transaction(pyldb_Module_AsModule(self));
2721         Py_RETURN_NONE;
2722 }
2723
2724 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
2725 {
2726         PyObject *py_base, *py_tree, *py_attrs, *py_ret;
2727         int ret, scope;
2728         struct ldb_request *req;
2729         const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
2730         struct ldb_module *mod;
2731         const char * const*attrs;
2732
2733         /* type "int" rather than "enum" for "scope" is intentional */
2734         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!iOO",
2735                                          discard_const_p(char *, kwnames),
2736                                          &PyLdbDn, &py_base, &scope, &py_tree, &py_attrs))
2737                 return NULL;
2738
2739         mod = self->mod;
2740
2741         if (py_attrs == Py_None) {
2742                 attrs = NULL;
2743         } else {
2744                 attrs = PyList_AsStrList(NULL, py_attrs, "attrs");
2745                 if (attrs == NULL)
2746                         return NULL;
2747         }
2748
2749         ret = ldb_build_search_req(&req, mod->ldb, NULL, pyldb_Dn_AsDn(py_base), 
2750                              scope, NULL /* expr */, attrs,
2751                              NULL /* controls */, NULL, NULL, NULL);
2752
2753         talloc_steal(req, attrs);
2754
2755         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2756
2757         req->op.search.res = NULL;
2758
2759         ret = mod->ops->search(mod, req);
2760
2761         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2762
2763         py_ret = PyLdbResult_FromResult(req->op.search.res);
2764
2765         talloc_free(req);
2766
2767         return py_ret;
2768 }
2769
2770
2771 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
2772 {
2773         struct ldb_request *req;
2774         PyObject *py_message;
2775         int ret;
2776         struct ldb_module *mod;
2777
2778         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2779                 return NULL;
2780
2781         req = talloc_zero(NULL, struct ldb_request);
2782         req->operation = LDB_ADD;
2783         req->op.add.message = pyldb_Message_AsMessage(py_message);
2784
2785         mod = pyldb_Module_AsModule(self);
2786         ret = mod->ops->add(mod, req);
2787
2788         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2789
2790         Py_RETURN_NONE;
2791 }
2792
2793 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) 
2794 {
2795         int ret;
2796         struct ldb_request *req;
2797         PyObject *py_message;
2798         struct ldb_module *mod;
2799
2800         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessage, &py_message))
2801                 return NULL;
2802
2803         req = talloc_zero(NULL, struct ldb_request);
2804         req->operation = LDB_MODIFY;
2805         req->op.mod.message = pyldb_Message_AsMessage(py_message);
2806
2807         mod = pyldb_Module_AsModule(self);
2808         ret = mod->ops->modify(mod, req);
2809
2810         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, mod->ldb);
2811
2812         Py_RETURN_NONE;
2813 }
2814
2815 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) 
2816 {
2817         int ret;
2818         struct ldb_request *req;
2819         PyObject *py_dn;
2820
2821         if (!PyArg_ParseTuple(args, "O!", &PyLdbDn, &py_dn))
2822                 return NULL;
2823
2824         req = talloc_zero(NULL, struct ldb_request);
2825         req->operation = LDB_DELETE;
2826         req->op.del.dn = pyldb_Dn_AsDn(py_dn);
2827
2828         ret = pyldb_Module_AsModule(self)->ops->del(pyldb_Module_AsModule(self), req);
2829
2830         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2831
2832         Py_RETURN_NONE;
2833 }
2834
2835 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
2836 {
2837         int ret;
2838         struct ldb_request *req;
2839         PyObject *py_dn1, *py_dn2;
2840
2841         if (!PyArg_ParseTuple(args, "O!O!", &PyLdbDn, &py_dn1, &PyLdbDn, &py_dn2))
2842                 return NULL;
2843
2844         req = talloc_zero(NULL, struct ldb_request);
2845
2846         req->operation = LDB_RENAME;
2847         req->op.rename.olddn = pyldb_Dn_AsDn(py_dn1);
2848         req->op.rename.newdn = pyldb_Dn_AsDn(py_dn2);
2849
2850         ret = pyldb_Module_AsModule(self)->ops->rename(pyldb_Module_AsModule(self), req);
2851
2852         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2853
2854         Py_RETURN_NONE;
2855 }
2856
2857 static PyMethodDef py_ldb_module_methods[] = {
2858         { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
2859         { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
2860         { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
2861         { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
2862         { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
2863         { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
2864         { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
2865         { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
2866         { NULL },
2867 };
2868
2869 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
2870 {
2871         talloc_free(self->mem_ctx);
2872         PyObject_Del(self);
2873 }
2874
2875 static PyTypeObject PyLdbModule = {
2876         .tp_name = "ldb.LdbModule",
2877         .tp_methods = py_ldb_module_methods,
2878         .tp_repr = (reprfunc)py_ldb_module_repr,
2879         .tp_str = (reprfunc)py_ldb_module_str,
2880         .tp_basicsize = sizeof(PyLdbModuleObject),
2881         .tp_dealloc = (destructor)py_ldb_module_dealloc,
2882         .tp_flags = Py_TPFLAGS_DEFAULT,
2883         .tp_doc = "LDB module (extension)",
2884 };
2885
2886
2887 /**
2888  * Create a ldb_message_element from a Python object.
2889  *
2890  * This will accept any sequence objects that contains strings, or 
2891  * a string object.
2892  *
2893  * A reference to set_obj will be borrowed. 
2894  *
2895  * @param mem_ctx Memory context
2896  * @param set_obj Python object to convert
2897  * @param flags ldb_message_element flags to set
2898  * @param attr_name Name of the attribute
2899  * @return New ldb_message_element, allocated as child of mem_ctx
2900  */
2901 static struct ldb_message_element *PyObject_AsMessageElement(
2902                                                       TALLOC_CTX *mem_ctx,
2903                                                       PyObject *set_obj,
2904                                                       unsigned int flags,
2905                                                       const char *attr_name)
2906 {
2907         struct ldb_message_element *me;
2908         const char *msg = NULL;
2909         Py_ssize_t size;
2910         int result;
2911
2912         if (pyldb_MessageElement_Check(set_obj)) {
2913                 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2914                 /* We have to talloc_reference() the memory context, not the pointer
2915                  * which may not actually be it's own context */
2916                 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2917                         return pyldb_MessageElement_AsMessageElement(set_obj);
2918                 }
2919                 return NULL;
2920         }
2921
2922         me = talloc(mem_ctx, struct ldb_message_element);
2923         if (me == NULL) {
2924                 PyErr_NoMemory();
2925                 return NULL;
2926         }
2927
2928         me->name = talloc_strdup(me, attr_name);
2929         me->flags = flags;
2930         if (PyBytes_Check(set_obj) || PyUnicode_Check(set_obj)) {
2931                 me->num_values = 1;
2932                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2933                 if (PyBytes_Check(set_obj)) {
2934                         char *_msg = NULL;
2935                         result = PyBytes_AsStringAndSize(set_obj, &_msg, &size);
2936                         if (result != 0) {
2937                                 talloc_free(me);
2938                                 return NULL;
2939                         }
2940                         msg = _msg;
2941                 } else {
2942                         msg = PyStr_AsUTF8AndSize(set_obj, &size);
2943                         if (msg == NULL) {
2944                                 talloc_free(me);
2945                                 return NULL;
2946                         }
2947                 }
2948                 me->values[0].data = talloc_memdup(me,
2949                                                    (const uint8_t *)msg,
2950                                                    size+1);
2951                 me->values[0].length = size;
2952         } else if (PySequence_Check(set_obj)) {
2953                 Py_ssize_t i;
2954                 me->num_values = PySequence_Size(set_obj);
2955                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2956                 for (i = 0; i < me->num_values; i++) {
2957                         PyObject *obj = PySequence_GetItem(set_obj, i);
2958                         if (PyBytes_Check(obj)) {
2959                                 char *_msg = NULL;
2960                                 result = PyBytes_AsStringAndSize(obj, &_msg, &size);
2961                                 if (result != 0) {
2962                                         talloc_free(me);
2963                                         return NULL;
2964                                 }
2965                                 msg = _msg;
2966                         } else if (PyUnicode_Check(obj)) {
2967                                 msg = PyStr_AsUTF8AndSize(obj, &size);
2968                                 if (msg == NULL) {
2969                                         talloc_free(me);
2970                                         return NULL;
2971                                 }
2972                         } else {
2973                                 PyErr_Format(PyExc_TypeError,
2974                                              "Expected string as element %zd in list", i);
2975                                 talloc_free(me);
2976                                 return NULL;
2977                         }
2978                         me->values[i].data = talloc_memdup(me,
2979                                                            (const uint8_t *)msg,
2980                                                            size+1);
2981                         me->values[i].length = size;
2982                 }
2983         } else {
2984                 PyErr_Format(PyExc_TypeError,
2985                              "String or List type expected for '%s' attribute", attr_name);
2986                 talloc_free(me);
2987                 me = NULL;
2988         }
2989
2990         return me;
2991 }
2992
2993
2994 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2995                                         struct ldb_message_element *me)
2996 {
2997         Py_ssize_t i;
2998         PyObject *result;
2999
3000         /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
3001         result = PyList_New(me->num_values);
3002
3003         for (i = 0; i < me->num_values; i++) {
3004                 PyList_SetItem(result, i,
3005                         PyObject_FromLdbValue(&me->values[i]));
3006         }
3007
3008         return result;
3009 }
3010
3011 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
3012 {
3013         unsigned int i;
3014         if (!PyArg_ParseTuple(args, "I", &i))
3015                 return NULL;
3016         if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
3017                 Py_RETURN_NONE;
3018
3019         return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
3020 }
3021
3022 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
3023 {
3024         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3025         return PyInt_FromLong(el->flags);
3026 }
3027
3028 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
3029 {
3030         unsigned int flags;
3031         struct ldb_message_element *el;
3032         if (!PyArg_ParseTuple(args, "I", &flags))
3033                 return NULL;
3034
3035         el = pyldb_MessageElement_AsMessageElement(self);
3036         el->flags = flags;
3037         Py_RETURN_NONE;
3038 }
3039
3040 static PyMethodDef py_ldb_msg_element_methods[] = {
3041         { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
3042         { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
3043         { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
3044         { NULL },
3045 };
3046
3047 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
3048 {
3049         return pyldb_MessageElement_AsMessageElement(self)->num_values;
3050 }
3051
3052 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
3053 {
3054         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3055         if (idx < 0 || idx >= el->num_values) {
3056                 PyErr_SetString(PyExc_IndexError, "Out of range");
3057                 return NULL;
3058         }
3059         return PyLdbBytes_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
3060 }
3061
3062 static PySequenceMethods py_ldb_msg_element_seq = {
3063         .sq_length = (lenfunc)py_ldb_msg_element_len,
3064         .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
3065 };
3066
3067 static PyObject *py_ldb_msg_element_richcmp(PyObject *self, PyObject *other, int op)
3068 {
3069         int ret;
3070         if (!pyldb_MessageElement_Check(other)) {
3071                 Py_INCREF(Py_NotImplemented);
3072                 return Py_NotImplemented;
3073         }
3074         ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
3075                                                                           pyldb_MessageElement_AsMessageElement(other));
3076         return richcmp(ret, op);
3077 }
3078
3079 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
3080 {
3081         PyObject *el = ldb_msg_element_to_set(NULL,
3082                                               pyldb_MessageElement_AsMessageElement(self));
3083         PyObject *ret = PyObject_GetIter(el);
3084         Py_DECREF(el);
3085         return ret;
3086 }
3087
3088 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
3089 {
3090         PyLdbMessageElementObject *ret;
3091         ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
3092         if (ret == NULL) {
3093                 PyErr_NoMemory();
3094                 return NULL;
3095         }
3096         ret->mem_ctx = talloc_new(NULL);
3097         if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
3098                 PyErr_NoMemory();
3099                 return NULL;
3100         }
3101         ret->el = el;
3102         return (PyObject *)ret;
3103 }
3104
3105 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3106 {
3107         PyObject *py_elements = NULL;
3108         struct ldb_message_element *el;
3109         unsigned int flags = 0;
3110         char *name = NULL;
3111         const char * const kwnames[] = { "elements", "flags", "name", NULL };
3112         PyLdbMessageElementObject *ret;
3113         TALLOC_CTX *mem_ctx;
3114         const char *msg = NULL;
3115         Py_ssize_t size;
3116         int result;
3117
3118         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
3119                                          discard_const_p(char *, kwnames),
3120                                          &py_elements, &flags, &name))
3121                 return NULL;
3122
3123         mem_ctx = talloc_new(NULL);
3124         if (mem_ctx == NULL) {
3125                 PyErr_NoMemory();
3126                 return NULL;
3127         }
3128
3129         el = talloc_zero(mem_ctx, struct ldb_message_element);
3130         if (el == NULL) {
3131                 PyErr_NoMemory();
3132                 talloc_free(mem_ctx);
3133                 return NULL;
3134         }
3135
3136         if (py_elements != NULL) {
3137                 Py_ssize_t i;
3138                 if (PyBytes_Check(py_elements) || PyUnicode_Check(py_elements)) {
3139                         char *_msg = NULL;
3140                         el->num_values = 1;
3141                         el->values = talloc_array(el, struct ldb_val, 1);
3142                         if (el->values == NULL) {
3143                                 talloc_free(mem_ctx);
3144                                 PyErr_NoMemory();
3145                                 return NULL;
3146                         }
3147                         if (PyBytes_Check(py_elements)) {
3148                                 result = PyBytes_AsStringAndSize(py_elements, &_msg, &size);
3149                                 msg = _msg;
3150                         } else {
3151                                 msg = PyStr_AsUTF8AndSize(py_elements, &size);
3152                                 result = (msg == NULL) ? -1 : 0;
3153                         }
3154                         if (result != 0) {
3155                                 talloc_free(mem_ctx);
3156                                 return NULL;
3157                         }
3158                         el->values[0].data = talloc_memdup(el->values, 
3159                                 (const uint8_t *)msg, size + 1);
3160                         el->values[0].length = size;
3161                 } else if (PySequence_Check(py_elements)) {
3162                         el->num_values = PySequence_Size(py_elements);
3163                         el->values = talloc_array(el, struct ldb_val, el->num_values);
3164                         if (el->values == NULL) {
3165                                 talloc_free(mem_ctx);
3166                                 PyErr_NoMemory();
3167                                 return NULL;
3168                         }
3169                         for (i = 0; i < el->num_values; i++) {
3170                                 PyObject *item = PySequence_GetItem(py_elements, i);
3171                                 if (item == NULL) {
3172                                         talloc_free(mem_ctx);
3173                                         return NULL;
3174                                 }
3175                                 if (PyBytes_Check(item)) {
3176                                         char *_msg = NULL;
3177                                         result = PyBytes_AsStringAndSize(item, &_msg, &size);
3178                                         msg = _msg;
3179                                 } else if (PyUnicode_Check(item)) {
3180                                         msg = PyStr_AsUTF8AndSize(item, &size);
3181                                         result = (msg == NULL) ? -1 : 0;
3182                                 } else {
3183                                         PyErr_Format(PyExc_TypeError, 
3184                                                      "Expected string as element %zd in list", i);
3185                                         result = -1;
3186                                 }
3187                                 if (result != 0) {
3188                                         talloc_free(mem_ctx);
3189                                         return NULL;
3190                                 }
3191                                 el->values[i].data = talloc_memdup(el,
3192                                         (const uint8_t *)msg, size+1);
3193                                 el->values[i].length = size;
3194                         }
3195                 } else {
3196                         PyErr_SetString(PyExc_TypeError, 
3197                                         "Expected string or list");
3198                         talloc_free(mem_ctx);
3199                         return NULL;
3200                 }
3201         }
3202
3203         el->flags = flags;
3204         el->name = talloc_strdup(el, name);
3205
3206         ret = PyObject_New(PyLdbMessageElementObject, type);
3207         if (ret == NULL) {
3208                 talloc_free(mem_ctx);
3209                 return NULL;
3210         }
3211
3212         ret->mem_ctx = mem_ctx;
3213         ret->el = el;
3214         return (PyObject *)ret;
3215 }
3216
3217 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
3218 {
3219         char *element_str = NULL;
3220         Py_ssize_t i;
3221         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3222         PyObject *ret, *repr;
3223
3224         for (i = 0; i < el->num_values; i++) {
3225                 PyObject *o = py_ldb_msg_element_find(self, i);
3226                 repr = PyObject_Repr(o);
3227                 if (element_str == NULL)
3228                         element_str = talloc_strdup(NULL, PyStr_AsUTF8(repr));
3229                 else
3230                         element_str = talloc_asprintf_append(element_str, ",%s", PyStr_AsUTF8(repr));
3231                 Py_DECREF(repr);
3232         }
3233
3234         if (element_str != NULL) {
3235                 ret = PyStr_FromFormat("MessageElement([%s])", element_str);
3236                 talloc_free(element_str);
3237         } else {
3238                 ret = PyStr_FromString("MessageElement([])");
3239         }
3240
3241         return ret;
3242 }
3243
3244 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
3245 {
3246         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
3247
3248         if (el->num_values == 1)
3249                 return PyStr_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
3250         else
3251                 Py_RETURN_NONE;
3252 }
3253
3254 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
3255 {
3256         talloc_free(self->mem_ctx);
3257         PyObject_Del(self);
3258 }
3259
3260 static PyObject *py_ldb_msg_element_get_text(PyObject *self, void *closure)
3261 {
3262         return wrap_text("MessageElementTextWrapper", self);
3263 }
3264
3265 static PyGetSetDef py_ldb_msg_element_getset[] = {
3266         {
3267                 .name = discard_const_p(char, "text"),
3268                 .get  = (getter)py_ldb_msg_element_get_text,
3269         },
3270         { .name = NULL }
3271 };
3272
3273 static PyTypeObject PyLdbMessageElement = {
3274         .tp_name = "ldb.MessageElement",
3275         .tp_basicsize = sizeof(PyLdbMessageElementObject),
3276         .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
3277         .tp_repr = (reprfunc)py_ldb_msg_element_repr,
3278         .tp_str = (reprfunc)py_ldb_msg_element_str,
3279         .tp_methods = py_ldb_msg_element_methods,
3280         .tp_getset = py_ldb_msg_element_getset,
3281         .tp_richcompare = (richcmpfunc)py_ldb_msg_element_richcmp,
3282         .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
3283         .tp_as_sequence = &py_ldb_msg_element_seq,
3284         .tp_new = py_ldb_msg_element_new,
3285         .tp_flags = Py_TPFLAGS_DEFAULT,
3286         .tp_doc = "An element of a Message",
3287 };
3288
3289
3290 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
3291 {
3292         PyObject *py_ldb;
3293         PyObject *py_dict;
3294         PyObject *py_ret;
3295         struct ldb_message *msg;
3296         struct ldb_context *ldb_ctx;
3297         unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
3298
3299         if (!PyArg_ParseTuple(args, "O!O!|I",
3300                               &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
3301                               &mod_flags)) {
3302                 return NULL;
3303         }
3304
3305         if (!PyLdb_Check(py_ldb)) {
3306                 PyErr_SetString(PyExc_TypeError, "Expected Ldb");
3307                 return NULL;
3308         }
3309
3310         /* mask only flags we are going to use */
3311         mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
3312         if (!mod_flags) {
3313                 PyErr_SetString(PyExc_ValueError,
3314                                 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
3315                                 " expected as mod_flag value");
3316                 return NULL;
3317         }
3318
3319         ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
3320
3321         msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
3322         if (!msg) {
3323                 return NULL;
3324         }
3325
3326         py_ret = PyLdbMessage_FromMessage(msg);
3327
3328         talloc_unlink(ldb_ctx, msg);
3329
3330         return py_ret;
3331 }
3332
3333 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
3334 {
3335         char *name;
3336         if (!PyArg_ParseTuple(args, "s", &name))
3337                 return NULL;
3338
3339         ldb_msg_remove_attr(self->msg, name);
3340
3341         Py_RETURN_NONE;
3342 }
3343
3344 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
3345 {
3346         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3347         Py_ssize_t i, j = 0;
3348         PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
3349         if (msg->dn != NULL) {
3350                 PyList_SetItem(obj, j, PyStr_FromString("dn"));
3351                 j++;
3352         }
3353         for (i = 0; i < msg->num_elements; i++) {
3354                 PyList_SetItem(obj, j, PyStr_FromString(msg->elements[i].name));
3355                 j++;
3356         }
3357         return obj;
3358 }
3359
3360 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
3361 {
3362         struct ldb_message_element *el;
3363         const char *name;
3364         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3365         name = PyStr_AsUTF8(py_name);
3366         if (name == NULL) {
3367                 PyErr_SetNone(PyExc_TypeError);
3368                 return NULL;
3369         }
3370         if (!ldb_attr_cmp(name, "dn"))
3371                 return pyldb_Dn_FromDn(msg->dn);
3372         el = ldb_msg_find_element(msg, name);
3373         if (el == NULL) {
3374                 return NULL;
3375         }
3376         return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3377 }
3378
3379 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
3380 {
3381         PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
3382         if (ret == NULL) {
3383                 PyErr_SetString(PyExc_KeyError, "No such element");
3384                 return NULL;
3385         }
3386         return ret;
3387 }
3388
3389 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args, PyObject *kwargs)
3390 {
3391         PyObject *def = NULL;
3392         const char *kwnames[] = { "name", "default", "idx", NULL };
3393         const char *name = NULL;
3394         int idx = -1;
3395         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3396         struct ldb_message_element *el;
3397
3398         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oi:msg",
3399                                          discard_const_p(char *, kwnames), &name, &def, &idx)) {
3400                 return NULL;
3401         }
3402
3403         if (strcasecmp(name, "dn") == 0) {
3404                 return pyldb_Dn_FromDn(msg->dn);
3405         }
3406
3407         el = ldb_msg_find_element(msg, name);
3408
3409         if (el == NULL || (idx != -1 && el->num_values <= idx)) {
3410                 if (def != NULL) {
3411                         Py_INCREF(def);
3412                         return def;
3413                 }
3414                 Py_RETURN_NONE;
3415         }
3416
3417         if (idx == -1) {
3418                 return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
3419         }
3420
3421         return PyObject_FromLdbValue(&el->values[idx]);
3422 }
3423
3424 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
3425 {
3426         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3427         Py_ssize_t i, j = 0;
3428         PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
3429         if (msg->dn != NULL) {
3430                 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
3431                 j++;
3432         }
3433         for (i = 0; i < msg->num_elements; i++, j++) {
3434                 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
3435                 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
3436                 PyList_SetItem(l, j, value);
3437         }
3438         return l;
3439 }
3440
3441 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
3442 {
3443         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3444         Py_ssize_t i = 0;
3445         PyObject *l = PyList_New(msg->num_elements);
3446         for (i = 0; i < msg->num_elements; i++) {
3447                 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
3448         }
3449         return l;
3450 }
3451
3452 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
3453 {
3454         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3455         PyLdbMessageElementObject *py_element;
3456         int i, ret;
3457         struct ldb_message_element *el;
3458         struct ldb_message_element *el_new;
3459
3460         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
3461                 return NULL;
3462
3463         el = py_element->el;
3464         if (el == NULL) {
3465                 PyErr_SetString(PyExc_ValueError, "Invalid MessageElement object");
3466                 return NULL;
3467         }
3468
3469         ret = ldb_msg_add_empty(msg, el->name, el->flags, &el_new);
3470         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3471
3472         /* now deep copy all attribute values */
3473         el_new->values = talloc_array(msg->elements, struct ldb_val, el->num_values);
3474         if (el_new->values == NULL) {
3475                 PyErr_NoMemory();
3476                 return NULL;
3477         }
3478         el_new->num_values = el->num_values;
3479
3480         for (i = 0; i < el->num_values; i++) {
3481                 el_new->values[i] = ldb_val_dup(el_new->values, &el->values[i]);
3482                 if (el_new->values[i].data == NULL
3483                                 && el->values[i].length != 0) {
3484                         PyErr_NoMemory();
3485                         return NULL;
3486                 }
3487         }
3488
3489         Py_RETURN_NONE;
3490 }
3491
3492 static PyMethodDef py_ldb_msg_methods[] = {
3493         { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
3494                 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
3495                 "Class method to create ldb.Message object from Dictionary.\n"
3496                 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
3497         { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, 
3498                 "S.keys() -> list\n\n"
3499                 "Return sequence of all attribute names." },
3500         { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, 
3501                 "S.remove(name)\n\n"
3502                 "Remove all entries for attributes with the specified name."},
3503         { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS | METH_KEYWORDS,
3504           "msg.get(name,default=None,idx=None) -> string\n"
3505           "idx is the index into the values array\n"
3506           "if idx is None, then a list is returned\n"
3507           "if idx is not None, then the element with that index is returned\n"
3508           "if you pass the special name 'dn' then the DN object is returned\n"},
3509         { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
3510         { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
3511         { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
3512                 "S.add(element)\n\n"
3513                 "Add an element to this message." },
3514         { NULL },
3515 };
3516
3517 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
3518 {
3519         PyObject *list, *iter;
3520
3521         list = py_ldb_msg_keys(self);
3522         iter = PyObject_GetIter(list);
3523         Py_DECREF(list);
3524         return iter;
3525 }
3526
3527 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
3528 {
3529         const char *attr_name;
3530
3531         attr_name = PyStr_AsUTF8(name);
3532         if (attr_name == NULL) {
3533                 PyErr_SetNone(PyExc_TypeError);
3534                 return -1;
3535         }
3536
3537         if (value == NULL) {
3538                 /* delitem */
3539                 ldb_msg_remove_attr(self->msg, attr_name);
3540         } else {
3541                 int ret;
3542                 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
3543                                                                            value, 0, attr_name);
3544                 if (el == NULL) {
3545                         return -1;
3546                 }
3547                 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
3548                 ret = ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
3549                 if (ret != LDB_SUCCESS) {
3550                         PyErr_SetLdbError(PyExc_LdbError, ret, NULL);
3551                         return -1;
3552                 }
3553         }
3554         return 0;
3555 }
3556
3557 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
3558 {
3559         return pyldb_Message_AsMessage(self)->num_elements;
3560 }
3561
3562 static PyMappingMethods py_ldb_msg_mapping = {
3563         .mp_length = (lenfunc)py_ldb_msg_length,
3564         .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
3565         .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
3566 };
3567
3568 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3569 {
3570         const char * const kwnames[] = { "dn", NULL };
3571         struct ldb_message *ret;
3572         TALLOC_CTX *mem_ctx;
3573         PyObject *pydn = NULL;
3574         PyLdbMessageObject *py_ret;
3575
3576         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
3577                                          discard_const_p(char *, kwnames),
3578                                          &pydn))
3579                 return NULL;
3580
3581         mem_ctx = talloc_new(NULL);
3582         if (mem_ctx == NULL) {
3583                 PyErr_NoMemory();
3584                 return NULL;
3585         }
3586
3587         ret = ldb_msg_new(mem_ctx);
3588         if (ret == NULL) {
3589                 talloc_free(mem_ctx);
3590                 PyErr_NoMemory();
3591                 return NULL;
3592         }
3593
3594         if (pydn != NULL) {
3595                 struct ldb_dn *dn;
3596                 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
3597                         talloc_free(mem_ctx);
3598                         return NULL;
3599                 }
3600                 ret->dn = talloc_reference(ret, dn);
3601         }
3602
3603         py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
3604         if (py_ret == NULL) {
3605                 PyErr_NoMemory();
3606                 talloc_free(mem_ctx);
3607                 return NULL;
3608         }
3609
3610         py_ret->mem_ctx = mem_ctx;
3611         py_ret->msg = ret;
3612         return (PyObject *)py_ret;
3613 }
3614
3615 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
3616 {
3617         PyLdbMessageObject *ret;
3618
3619         ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
3620         if (ret == NULL) {
3621                 PyErr_NoMemory();
3622                 return NULL;
3623         }
3624         ret->mem_ctx = talloc_new(NULL);
3625         ret->msg = talloc_reference(ret->mem_ctx, msg);
3626         return (PyObject *)ret;
3627 }
3628
3629 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
3630 {
3631         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3632         return pyldb_Dn_FromDn(msg->dn);
3633 }
3634
3635 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
3636 {
3637         struct ldb_message *msg = pyldb_Message_AsMessage(self);
3638         if (!pyldb_Dn_Check(value)) {
3639                 PyErr_SetString(PyExc_TypeError, "expected dn");
3640                 return -1;
3641         }
3642
3643         msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
3644         return 0;
3645 }
3646
3647 static PyObject *py_ldb_msg_get_text(PyObject *self, void *closure)
3648 {
3649         return wrap_text("MessageTextWrapper", self);
3650 }
3651
3652 static PyGetSetDef py_ldb_msg_getset[] = {
3653         {
3654                 .name = discard_const_p(char, "dn"),
3655                 .get  = (getter)py_ldb_msg_get_dn,
3656                 .set  = (setter)py_ldb_msg_set_dn,
3657         },
3658         {
3659                 .name = discard_const_p(char, "text"),
3660                 .get  = (getter)py_ldb_msg_get_text,
3661         },
3662         { .name = NULL },
3663 };
3664
3665 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
3666 {
3667         PyObject *dict = PyDict_New(), *ret, *repr;
3668         if (PyDict_Update(dict, (PyObject *)self) != 0)
3669                 return NULL;
3670         repr = PyObject_Repr(dict);
3671         if (repr == NULL) {
3672                 Py_DECREF(dict);
3673                 return NULL;
3674         }
3675         ret = PyStr_FromFormat("Message(%s)", PyStr_AsUTF8(repr));
3676         Py_DECREF(repr);
3677         Py_DECREF(dict);
3678         return ret;
3679 }
3680
3681 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
3682 {
3683         talloc_free(self->mem_ctx);
3684         PyObject_Del(self);
3685 }
3686
3687 static PyObject *py_ldb_msg_richcmp(PyLdbMessageObject *py_msg1,
3688                               PyLdbMessageObject *py_msg2, int op)
3689 {
3690         struct ldb_message *msg1, *msg2;
3691         unsigned int i;
3692         int ret;
3693
3694         if (!PyLdbMessage_Check(py_msg2)) {
3695                 Py_INCREF(Py_NotImplemented);
3696                 return Py_NotImplemented;
3697         }
3698
3699         msg1 = pyldb_Message_AsMessage(py_msg1),
3700         msg2 = pyldb_Message_AsMessage(py_msg2);
3701
3702         if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
3703                 ret = ldb_dn_compare(msg1->dn, msg2->dn);
3704                 if (ret != 0) {
3705                         return richcmp(ret, op);
3706                 }
3707         }
3708
3709         ret = msg1->num_elements - msg2->num_elements;
3710         if (ret != 0) {
3711                 return richcmp(ret, op);
3712         }
3713
3714         for (i = 0; i < msg1->num_elements; i++) {
3715                 ret = ldb_msg_element_compare_name(&msg1->elements[i],
3716                                                    &msg2->elements[i]);
3717                 if (ret != 0) {
3718                         return richcmp(ret, op);
3719                 }
3720
3721                 ret = ldb_msg_element_compare(&msg1->elements[i],
3722                                               &msg2->elements[i]);
3723                 if (ret != 0) {
3724                         return richcmp(ret, op);
3725                 }
3726         }
3727
3728         return richcmp(0, op);
3729 }
3730
3731 static PyTypeObject PyLdbMessage = {
3732         .tp_name = "ldb.Message",
3733         .tp_methods = py_ldb_msg_methods,
3734         .tp_getset = py_ldb_msg_getset,
3735         .tp_as_mapping = &py_ldb_msg_mapping,
3736         .tp_basicsize = sizeof(PyLdbMessageObject),
3737         .tp_dealloc = (destructor)py_ldb_msg_dealloc,
3738         .tp_new = py_ldb_msg_new,
3739         .tp_repr = (reprfunc)py_ldb_msg_repr,
3740         .tp_flags = Py_TPFLAGS_DEFAULT,
3741         .tp_iter = (getiterfunc)py_ldb_msg_iter,
3742         .tp_richcompare = (richcmpfunc)py_ldb_msg_richcmp,
3743         .tp_doc = "A LDB Message",
3744 };
3745
3746 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
3747 {
3748         PyLdbTreeObject *ret;
3749
3750         ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
3751         if (ret == NULL) {
3752                 PyErr_NoMemory();
3753                 return NULL;
3754         }
3755
3756         ret->mem_ctx = talloc_new(NULL);
3757         ret->tree = talloc_reference(ret->mem_ctx, tree);
3758         return (PyObject *)ret;
3759 }
3760
3761 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
3762 {
3763         talloc_free(self->mem_ctx);
3764         PyObject_Del(self);
3765 }
3766
3767 static PyTypeObject PyLdbTree = {
3768         .tp_name = "ldb.Tree",
3769         .tp_basicsize = sizeof(PyLdbTreeObject),
3770         .tp_dealloc = (destructor)py_ldb_tree_dealloc,
3771         .tp_flags = Py_TPFLAGS_DEFAULT,
3772         .tp_doc = "A search tree",
3773 };
3774
3775 /* Ldb_module */
3776 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
3777 {
3778         PyObject *py_ldb = (PyObject *)mod->private_data;
3779         PyObject *py_result, *py_base, *py_attrs, *py_tree;
3780
3781         py_base = pyldb_Dn_FromDn(req->op.search.base);
3782
3783         if (py_base == NULL)
3784                 return LDB_ERR_OPERATIONS_ERROR;
3785
3786         py_tree = PyLdbTree_FromTree(req->op.search.tree);
3787
3788         if (py_tree == NULL)
3789                 return LDB_ERR_OPERATIONS_ERROR;
3790
3791         if (req->op.search.attrs == NULL) {
3792                 py_attrs = Py_None;
3793         } else {
3794                 int i, len;
3795                 for (len = 0; req->op.search.attrs[len]; len++);
3796                 py_attrs = PyList_New(len);
3797                 for (i = 0; i < len; i++)
3798                         PyList_SetItem(py_attrs, i, PyStr_FromString(req->op.search.attrs[i]));
3799         }
3800
3801         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
3802                                         discard_const_p(char, "OiOO"),
3803                                         py_base, req->op.search.scope, py_tree, py_attrs);
3804
3805         Py_DECREF(py_attrs);
3806         Py_DECREF(py_tree);
3807         Py_DECREF(py_base);
3808
3809         if (py_result == NULL) {
3810                 return LDB_ERR_PYTHON_EXCEPTION;
3811         }
3812
3813         req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
3814         if (req->op.search.res == NULL) {
3815                 return LDB_ERR_PYTHON_EXCEPTION;
3816         }
3817
3818         Py_DECREF(py_result);
3819
3820         return LDB_SUCCESS;
3821 }
3822
3823 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
3824 {
3825         PyObject *py_ldb = (PyObject *)mod->private_data;
3826         PyObject *py_result, *py_msg;
3827
3828         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
3829
3830         if (py_msg == NULL) {
3831                 return LDB_ERR_OPERATIONS_ERROR;
3832         }
3833
3834         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
3835                                         discard_const_p(char, "O"),
3836                                         py_msg);
3837
3838         Py_DECREF(py_msg);
3839
3840         if (py_result == NULL) {
3841                 return LDB_ERR_PYTHON_EXCEPTION;
3842         }
3843
3844         Py_DECREF(py_result);
3845
3846         return LDB_SUCCESS;
3847 }
3848
3849 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
3850 {
3851         PyObject *py_ldb = (PyObject *)mod->private_data;
3852         PyObject *py_result, *py_msg;
3853
3854         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
3855
3856         if (py_msg == NULL) {
3857                 return LDB_ERR_OPERATIONS_ERROR;
3858         }
3859
3860         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
3861                                         discard_const_p(char, "O"),
3862                                         py_msg);
3863
3864         Py_DECREF(py_msg);
3865
3866         if (py_result == NULL) {
3867                 return LDB_ERR_PYTHON_EXCEPTION;
3868         }
3869
3870         Py_DECREF(py_result);
3871
3872         return LDB_SUCCESS;
3873 }
3874
3875 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
3876 {
3877         PyObject *py_ldb = (PyObject *)mod->private_data;
3878         PyObject *py_result, *py_dn;
3879
3880         py_dn = pyldb_Dn_FromDn(req->op.del.dn);
3881
3882         if (py_dn == NULL)
3883                 return LDB_ERR_OPERATIONS_ERROR;
3884
3885         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
3886                                         discard_const_p(char, "O"),
3887                                         py_dn);
3888
3889         if (py_result == NULL) {
3890                 return LDB_ERR_PYTHON_EXCEPTION;
3891         }
3892
3893         Py_DECREF(py_result);
3894
3895         return LDB_SUCCESS;
3896 }
3897
3898 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
3899 {
3900         PyObject *py_ldb = (PyObject *)mod->private_data;
3901         PyObject *py_result, *py_olddn, *py_newdn;
3902
3903         py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
3904
3905         if (py_olddn == NULL)
3906                 return LDB_ERR_OPERATIONS_ERROR;
3907
3908         py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
3909
3910         if (py_newdn == NULL)
3911                 return LDB_ERR_OPERATIONS_ERROR;
3912
3913         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
3914                                         discard_const_p(char, "OO"),
3915                                         py_olddn, py_newdn);
3916
3917         Py_DECREF(py_olddn);
3918         Py_DECREF(py_newdn);
3919
3920         if (py_result == NULL) {
3921                 return LDB_ERR_PYTHON_EXCEPTION;
3922         }
3923
3924         Py_DECREF(py_result);
3925
3926         return LDB_SUCCESS;
3927 }
3928
3929 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3930 {
3931         PyObject *py_ldb = (PyObject *)mod->private_data;
3932         PyObject *py_result;
3933
3934         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3935                                         discard_const_p(char, ""));
3936
3937         Py_XDECREF(py_result);
3938
3939         return LDB_ERR_OPERATIONS_ERROR;
3940 }
3941
3942 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3943 {
3944         PyObject *py_ldb = (PyObject *)mod->private_data;
3945         PyObject *py_result;
3946
3947         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3948                                         discard_const_p(char, ""));
3949
3950         Py_XDECREF(py_result);
3951
3952         return LDB_ERR_OPERATIONS_ERROR;
3953 }
3954
3955 static int py_module_start_transaction(struct ldb_module *mod)
3956 {
3957         PyObject *py_ldb = (PyObject *)mod->private_data;
3958         PyObject *py_result;
3959
3960         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3961                                         discard_const_p(char, ""));
3962
3963         if (py_result == NULL) {
3964                 return LDB_ERR_PYTHON_EXCEPTION;
3965         }
3966
3967         Py_DECREF(py_result);
3968
3969         return LDB_SUCCESS;
3970 }
3971
3972 static int py_module_end_transaction(struct ldb_module *mod)
3973 {
3974         PyObject *py_ldb = (PyObject *)mod->private_data;
3975         PyObject *py_result;
3976
3977         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3978                                         discard_const_p(char, ""));
3979
3980         if (py_result == NULL) {
3981                 return LDB_ERR_PYTHON_EXCEPTION;
3982         }
3983
3984         Py_DECREF(py_result);
3985
3986         return LDB_SUCCESS;
3987 }
3988
3989 static int py_module_del_transaction(struct ldb_module *mod)
3990 {
3991         PyObject *py_ldb = (PyObject *)mod->private_data;
3992         PyObject *py_result;
3993
3994         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3995                                         discard_const_p(char, ""));
3996
3997         if (py_result == NULL) {
3998                 return LDB_ERR_PYTHON_EXCEPTION;
3999         }
4000
4001         Py_DECREF(py_result);
4002
4003         return LDB_SUCCESS;
4004 }
4005
4006 static int py_module_destructor(struct ldb_module *mod)
4007 {
4008         Py_DECREF((PyObject *)mod->private_data);
4009         return 0;
4010 }
4011
4012 static int py_module_init(struct ldb_module *mod)
4013 {
4014         PyObject *py_class = (PyObject *)mod->ops->private_data;
4015         PyObject *py_result, *py_next, *py_ldb;
4016
4017         py_ldb = PyLdb_FromLdbContext(mod->ldb);
4018
4019         if (py_ldb == NULL)
4020                 return LDB_ERR_OPERATIONS_ERROR;
4021
4022         py_next = PyLdbModule_FromModule(mod->next);
4023
4024         if (py_next == NULL)
4025                 return LDB_ERR_OPERATIONS_ERROR;
4026
4027         py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
4028                                           py_ldb, py_next);
4029
4030         if (py_result == NULL) {
4031                 return LDB_ERR_PYTHON_EXCEPTION;
4032         }
4033
4034         mod->private_data = py_result;
4035
4036         talloc_set_destructor(mod, py_module_destructor);
4037
4038         return ldb_next_init(mod);
4039 }
4040
4041 static PyObject *py_register_module(PyObject *module, PyObject *args)
4042 {
4043         int ret;
4044         struct ldb_module_ops *ops;
4045         PyObject *input;
4046
4047         if (!PyArg_ParseTuple(args, "O", &input))
4048                 return NULL;
4049
4050         ops = talloc_zero(NULL, struct ldb_module_ops);
4051         if (ops == NULL) {
4052                 PyErr_NoMemory();
4053                 return NULL;
4054         }
4055
4056         ops->name = talloc_strdup(ops, PyStr_AsUTF8(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
4057
4058         Py_INCREF(input);
4059         ops->private_data = input;
4060         ops->init_context = py_module_init;
4061         ops->search = py_module_search;
4062         ops->add = py_module_add;
4063         ops->modify = py_module_modify;
4064         ops->del = py_module_del;
4065         ops->rename = py_module_rename;
4066         ops->request = py_module_request;
4067         ops->extended = py_module_extended;
4068         ops->start_transaction = py_module_start_transaction;
4069         ops->end_transaction = py_module_end_transaction;
4070         ops->del_transaction = py_module_del_transaction;
4071
4072         ret = ldb_register_module(ops);
4073         if (ret != LDB_SUCCESS) {
4074                 TALLOC_FREE(ops);
4075         }
4076
4077         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
4078
4079         Py_RETURN_NONE;
4080 }
4081
4082 static PyObject *py_timestring(PyObject *module, PyObject *args)
4083 {
4084         /* most times "time_t" is a signed integer type with 32 or 64 bit:
4085          * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
4086         long int t_val;
4087         char *tresult;
4088         PyObject *ret;
4089         if (!PyArg_ParseTuple(args, "l", &t_val))
4090                 return NULL;
4091         tresult = ldb_timestring(NULL, (time_t) t_val);
4092         ret = PyStr_FromString(tresult);
4093         talloc_free(tresult);
4094         return ret;
4095 }
4096
4097 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
4098 {
4099         char *str;
4100         if (!PyArg_ParseTuple(args, "s", &str))
4101                 return NULL;
4102
4103         return PyInt_FromLong(ldb_string_to_time(str));
4104 }
4105
4106 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
4107 {
4108         char *name;
4109         if (!PyArg_ParseTuple(args, "s", &name))
4110                 return NULL;
4111         return PyBool_FromLong(ldb_valid_attr_name(name));
4112 }
4113
4114 /*
4115   encode a string using RFC2254 rules
4116  */
4117 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
4118 {
4119         char *str, *encoded;
4120         Py_ssize_t size = 0;
4121         struct ldb_val val;
4122         PyObject *ret;
4123
4124         if (!PyArg_ParseTuple(args, "s#", &str, &size))
4125                 return NULL;
4126         val.data = (uint8_t *)str;
4127         val.length = size;
4128
4129         encoded = ldb_binary_encode(NULL, val);
4130         if (encoded == NULL) {
4131                 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
4132                 return NULL;
4133         }
4134         ret = PyStr_FromString(encoded);
4135         talloc_free(encoded);
4136         return ret;
4137 }
4138
4139 /*
4140   decode a string using RFC2254 rules
4141  */
4142 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
4143 {
4144         char *str;
4145         struct ldb_val val;
4146         PyObject *ret;
4147
4148         if (!PyArg_ParseTuple(args, "s", &str))
4149                 return NULL;
4150
4151         val = ldb_binary_decode(NULL, str);
4152         if (val.data == NULL) {
4153                 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
4154                 return NULL;
4155         }
4156         ret = PyBytes_FromStringAndSize((const char*)val.data, val.length);
4157         talloc_free(val.data);
4158         return ret;
4159 }
4160
4161 static PyMethodDef py_ldb_global_methods[] = {
4162         { "register_module", py_register_module, METH_VARARGS, 
4163                 "S.register_module(module) -> None\n\n"
4164                 "Register a LDB module."},
4165         { "timestring", py_timestring, METH_VARARGS, 
4166                 "S.timestring(int) -> string\n\n"
4167                 "Generate a LDAP time string from a UNIX timestamp" },
4168         { "string_to_time", py_string_to_time, METH_VARARGS,
4169                 "S.string_to_time(string) -> int\n\n"
4170                 "Parse a LDAP time string into a UNIX timestamp." },
4171         { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
4172                 "S.valid_attr_name(name) -> bool\n\nn"
4173                 "Check whether the supplied name is a valid attribute name." },
4174         { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
4175                 "S.open() -> Ldb\n\n"
4176                 "Open a new LDB context." },
4177         { "binary_encode", py_binary_encode, METH_VARARGS,
4178                 "S.binary_encode(string) -> string\n\n"
4179                 "Perform a RFC2254 binary encoding on a string" },
4180         { "binary_decode", py_binary_decode, METH_VARARGS,
4181                 "S.binary_decode(string) -> string\n\n"
4182                 "Perform a RFC2254 binary decode on a string" },
4183         { NULL }
4184 };
4185
4186 #define MODULE_DOC "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server."
4187
4188 #if PY_MAJOR_VERSION >= 3
4189 static struct PyModuleDef moduledef = {
4190         PyModuleDef_HEAD_INIT,
4191         .m_name = "ldb",
4192         .m_doc = MODULE_DOC,
4193         .m_size = -1,
4194         .m_methods = py_ldb_global_methods,
4195 };
4196 #endif
4197
4198 static PyObject* module_init(void)
4199 {
4200         PyObject *m;
4201
4202         PyLdbBytesType.tp_base = &PyBytes_Type;
4203         if (PyType_Ready(&PyLdbBytesType) < 0) {
4204                 return NULL;
4205         }
4206
4207         if (PyType_Ready(&PyLdbDn) < 0)
4208                 return NULL;
4209
4210         if (PyType_Ready(&PyLdbMessage) < 0)
4211                 return NULL;
4212
4213         if (PyType_Ready(&PyLdbMessageElement) < 0)
4214                 return NULL;
4215
4216         if (PyType_Ready(&PyLdb) < 0)
4217                 return NULL;
4218
4219         if (PyType_Ready(&PyLdbModule) < 0)
4220                 return NULL;
4221
4222         if (PyType_Ready(&PyLdbTree) < 0)
4223                 return NULL;
4224
4225         if (PyType_Ready(&PyLdbResult) < 0)
4226                 return NULL;
4227
4228         if (PyType_Ready(&PyLdbSearchIterator) < 0)
4229                 return NULL;
4230
4231         if (PyType_Ready(&PyLdbControl) < 0)
4232                 return NULL;
4233
4234 #if PY_MAJOR_VERSION >= 3
4235         m = PyModule_Create(&moduledef);
4236 #else
4237         m = Py_InitModule3("ldb", py_ldb_global_methods, MODULE_DOC);
4238 #endif
4239         if (m == NULL)
4240                 return NULL;
4241
4242 #define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
4243
4244         ADD_LDB_INT(SEQ_HIGHEST_SEQ);
4245         ADD_LDB_INT(SEQ_HIGHEST_TIMESTAMP);
4246         ADD_LDB_INT(SEQ_NEXT);
4247         ADD_LDB_INT(SCOPE_DEFAULT);
4248         ADD_LDB_INT(SCOPE_BASE);
4249         ADD_LDB_INT(SCOPE_ONELEVEL);
4250         ADD_LDB_INT(SCOPE_SUBTREE);
4251
4252         ADD_LDB_INT(CHANGETYPE_NONE);
4253         ADD_LDB_INT(CHANGETYPE_ADD);
4254         ADD_LDB_INT(CHANGETYPE_DELETE);
4255         ADD_LDB_INT(CHANGETYPE_MODIFY);
4256
4257         ADD_LDB_INT(FLAG_MOD_ADD);
4258         ADD_LDB_INT(FLAG_MOD_REPLACE);
4259         ADD_LDB_INT(FLAG_MOD_DELETE);
4260
4261         ADD_LDB_INT(ATTR_FLAG_HIDDEN);
4262         ADD_LDB_INT(ATTR_FLAG_UNIQUE_INDEX);
4263         ADD_LDB_INT(ATTR_FLAG_SINGLE_VALUE);
4264         ADD_LDB_INT(ATTR_FLAG_FORCE_BASE64_LDIF);
4265
4266         ADD_LDB_INT(SUCCESS);
4267         ADD_LDB_INT(ERR_OPERATIONS_ERROR);
4268         ADD_LDB_INT(ERR_PROTOCOL_ERROR);
4269         ADD_LDB_INT(ERR_TIME_LIMIT_EXCEEDED);
4270         ADD_LDB_INT(ERR_SIZE_LIMIT_EXCEEDED);
4271         ADD_LDB_INT(ERR_COMPARE_FALSE);
4272         ADD_LDB_INT(ERR_COMPARE_TRUE);
4273         ADD_LDB_INT(ERR_AUTH_METHOD_NOT_SUPPORTED);
4274         ADD_LDB_INT(ERR_STRONG_AUTH_REQUIRED);
4275         ADD_LDB_INT(ERR_REFERRAL);
4276         ADD_LDB_INT(ERR_ADMIN_LIMIT_EXCEEDED);
4277         ADD_LDB_INT(ERR_UNSUPPORTED_CRITICAL_EXTENSION);
4278         ADD_LDB_INT(ERR_CONFIDENTIALITY_REQUIRED);
4279         ADD_LDB_INT(ERR_SASL_BIND_IN_PROGRESS);
4280         ADD_LDB_INT(ERR_NO_SUCH_ATTRIBUTE);
4281         ADD_LDB_INT(ERR_UNDEFINED_ATTRIBUTE_TYPE);
4282         ADD_LDB_INT(ERR_INAPPROPRIATE_MATCHING);
4283         ADD_LDB_INT(ERR_CONSTRAINT_VIOLATION);
4284         ADD_LDB_INT(ERR_ATTRIBUTE_OR_VALUE_EXISTS);
4285         ADD_LDB_INT(ERR_INVALID_ATTRIBUTE_SYNTAX);
4286         ADD_LDB_INT(ERR_NO_SUCH_OBJECT);
4287         ADD_LDB_INT(ERR_ALIAS_PROBLEM);
4288         ADD_LDB_INT(ERR_INVALID_DN_SYNTAX);
4289         ADD_LDB_INT(ERR_ALIAS_DEREFERENCING_PROBLEM);
4290         ADD_LDB_INT(ERR_INAPPROPRIATE_AUTHENTICATION);
4291         ADD_LDB_INT(ERR_INVALID_CREDENTIALS);
4292         ADD_LDB_INT(ERR_INSUFFICIENT_ACCESS_RIGHTS);
4293         ADD_LDB_INT(ERR_BUSY);
4294         ADD_LDB_INT(ERR_UNAVAILABLE);
4295         ADD_LDB_INT(ERR_UNWILLING_TO_PERFORM);
4296         ADD_LDB_INT(ERR_LOOP_DETECT);
4297         ADD_LDB_INT(ERR_NAMING_VIOLATION);
4298         ADD_LDB_INT(ERR_OBJECT_CLASS_VIOLATION);
4299         ADD_LDB_INT(ERR_NOT_ALLOWED_ON_NON_LEAF);
4300         ADD_LDB_INT(ERR_NOT_ALLOWED_ON_RDN);
4301         ADD_LDB_INT(ERR_ENTRY_ALREADY_EXISTS);
4302         ADD_LDB_INT(ERR_OBJECT_CLASS_MODS_PROHIBITED);
4303         ADD_LDB_INT(ERR_AFFECTS_MULTIPLE_DSAS);
4304         ADD_LDB_INT(ERR_OTHER);
4305
4306         ADD_LDB_INT(FLG_RDONLY);
4307         ADD_LDB_INT(FLG_NOSYNC);
4308         ADD_LDB_INT(FLG_RECONNECT);
4309         ADD_LDB_INT(FLG_NOMMAP);
4310         ADD_LDB_INT(FLG_SHOW_BINARY);
4311         ADD_LDB_INT(FLG_ENABLE_TRACING);
4312         ADD_LDB_INT(FLG_DONT_CREATE_DB);
4313
4314
4315         /* Historical misspelling */
4316         PyModule_AddIntConstant(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", LDB_ERR_ALIAS_DEREFERENCING_PROBLEM);
4317
4318         PyModule_AddStringConstant(m, "__docformat__", "restructuredText");
4319
4320         PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
4321         PyModule_AddObject(m, "LdbError", PyExc_LdbError);
4322
4323         Py_INCREF(&PyLdb);
4324         Py_INCREF(&PyLdbDn);
4325         Py_INCREF(&PyLdbModule);
4326         Py_INCREF(&PyLdbMessage);
4327         Py_INCREF(&PyLdbMessageElement);
4328         Py_INCREF(&PyLdbTree);
4329         Py_INCREF(&PyLdbResult);
4330         Py_INCREF(&PyLdbControl);
4331
4332         PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
4333         PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
4334         PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
4335         PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
4336         PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
4337         PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
4338         PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
4339
4340         PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
4341
4342 #define ADD_LDB_STRING(val)  PyModule_AddStringConstant(m, #val, LDB_## val)
4343
4344         ADD_LDB_STRING(SYNTAX_DN);
4345         ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
4346         ADD_LDB_STRING(SYNTAX_INTEGER);
4347         ADD_LDB_STRING(SYNTAX_BOOLEAN);
4348         ADD_LDB_STRING(SYNTAX_OCTET_STRING);
4349         ADD_LDB_STRING(SYNTAX_UTC_TIME);
4350         ADD_LDB_STRING(OID_COMPARATOR_AND);
4351         ADD_LDB_STRING(OID_COMPARATOR_OR);
4352
4353         return m;
4354 }
4355
4356 #if PY_MAJOR_VERSION >= 3
4357 PyMODINIT_FUNC PyInit_ldb(void);
4358 PyMODINIT_FUNC PyInit_ldb(void)
4359 {
4360         return module_init();
4361 }
4362 #else
4363 void initldb(void);
4364 void initldb(void)
4365 {
4366         module_init();
4367 }
4368 #endif