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