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