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