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