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