ldb:pyldb.c - py_ldb_* modification calls - error string shouldn't be set here
[mdw/samba.git] / lib / ldb / pyldb.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Python interface to ldb.
5
6    Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
7    Copyright (C) 2006 Simo Sorce <idra@samba.org>
8    Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
9    Copyright (C) 2009-2010 Matthias Dieter Wallnöfer
10    Copyright (C) 2009-2011 Andrew Tridgell
11    Copyright (C) 2009-2011 Andrew Bartlett
12
13     ** NOTE! The following LGPL license applies to the ldb
14     ** library. This does NOT imply that all of Samba is released
15     ** under the LGPL
16
17    This library is free software; you can redistribute it and/or
18    modify it under the terms of the GNU Lesser General Public
19    License as published by the Free Software Foundation; either
20    version 3 of the License, or (at your option) any later version.
21
22    This library is distributed in the hope that it will be useful,
23    but WITHOUT ANY WARRANTY; without even the implied warranty of
24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25    Lesser General Public License for more details.
26
27    You should have received a copy of the GNU Lesser General Public
28    License along with this library; if not, see <http://www.gnu.org/licenses/>.
29 */
30
31 #include <Python.h>
32 #include "ldb_private.h"
33 #include "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 };
2121
2122
2123 /**
2124  * Create a ldb_message_element from a Python object.
2125  *
2126  * This will accept any sequence objects that contains strings, or 
2127  * a string object.
2128  *
2129  * A reference to set_obj will be borrowed. 
2130  *
2131  * @param mem_ctx Memory context
2132  * @param set_obj Python object to convert
2133  * @param flags ldb_message_element flags to set
2134  * @param attr_name Name of the attribute
2135  * @return New ldb_message_element, allocated as child of mem_ctx
2136  */
2137 static struct ldb_message_element *PyObject_AsMessageElement(
2138                                                       TALLOC_CTX *mem_ctx,
2139                                                       PyObject *set_obj,
2140                                                       unsigned int flags,
2141                                                       const char *attr_name)
2142 {
2143         struct ldb_message_element *me;
2144
2145         if (pyldb_MessageElement_Check(set_obj)) {
2146                 PyLdbMessageElementObject *set_obj_as_me = (PyLdbMessageElementObject *)set_obj;
2147                 /* We have to talloc_reference() the memory context, not the pointer
2148                  * which may not actually be it's own context */
2149                 if (talloc_reference(mem_ctx, set_obj_as_me->mem_ctx)) {
2150                         return pyldb_MessageElement_AsMessageElement(set_obj);
2151                 }
2152                 return NULL;
2153         }
2154
2155         me = talloc(mem_ctx, struct ldb_message_element);
2156         if (me == NULL) {
2157                 PyErr_NoMemory();
2158                 return NULL;
2159         }
2160
2161         me->name = talloc_strdup(me, attr_name);
2162         me->flags = flags;
2163         if (PyString_Check(set_obj)) {
2164                 me->num_values = 1;
2165                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2166                 me->values[0].length = PyString_Size(set_obj);
2167                 me->values[0].data = talloc_memdup(me, 
2168                         (uint8_t *)PyString_AsString(set_obj), me->values[0].length+1);
2169         } else if (PySequence_Check(set_obj)) {
2170                 Py_ssize_t i;
2171                 me->num_values = PySequence_Size(set_obj);
2172                 me->values = talloc_array(me, struct ldb_val, me->num_values);
2173                 for (i = 0; i < me->num_values; i++) {
2174                         PyObject *obj = PySequence_GetItem(set_obj, i);
2175                         if (!PyString_Check(obj)) {
2176                                 PyErr_Format(PyExc_TypeError,
2177                                              "Expected string as element %zd in list", i);
2178                                 talloc_free(me);
2179                                 return NULL;
2180                         }
2181
2182                         me->values[i].length = PyString_Size(obj);
2183                         me->values[i].data = talloc_memdup(me, 
2184                                 (uint8_t *)PyString_AsString(obj), me->values[i].length+1);
2185                 }
2186         } else {
2187                 talloc_free(me);
2188                 me = NULL;
2189         }
2190
2191         return me;
2192 }
2193
2194
2195 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
2196                                         struct ldb_message_element *me)
2197 {
2198         Py_ssize_t i;
2199         PyObject *result;
2200
2201         /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
2202         result = PyList_New(me->num_values);
2203
2204         for (i = 0; i < me->num_values; i++) {
2205                 PyList_SetItem(result, i,
2206                         PyObject_FromLdbValue(&me->values[i]));
2207         }
2208
2209         return result;
2210 }
2211
2212 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
2213 {
2214         unsigned int i;
2215         if (!PyArg_ParseTuple(args, "I", &i))
2216                 return NULL;
2217         if (i >= pyldb_MessageElement_AsMessageElement(self)->num_values)
2218                 Py_RETURN_NONE;
2219
2220         return PyObject_FromLdbValue(&(pyldb_MessageElement_AsMessageElement(self)->values[i]));
2221 }
2222
2223 static PyObject *py_ldb_msg_element_flags(PyLdbMessageElementObject *self, PyObject *args)
2224 {
2225         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2226         return PyInt_FromLong(el->flags);
2227 }
2228
2229 static PyObject *py_ldb_msg_element_set_flags(PyLdbMessageElementObject *self, PyObject *args)
2230 {
2231         unsigned int flags;
2232         struct ldb_message_element *el;
2233         if (!PyArg_ParseTuple(args, "I", &flags))
2234                 return NULL;
2235
2236         el = pyldb_MessageElement_AsMessageElement(self);
2237         el->flags = flags;
2238         Py_RETURN_NONE;
2239 }
2240
2241 static PyMethodDef py_ldb_msg_element_methods[] = {
2242         { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
2243         { "set_flags", (PyCFunction)py_ldb_msg_element_set_flags, METH_VARARGS, NULL },
2244         { "flags", (PyCFunction)py_ldb_msg_element_flags, METH_NOARGS, NULL },
2245         { NULL },
2246 };
2247
2248 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
2249 {
2250         return pyldb_MessageElement_AsMessageElement(self)->num_values;
2251 }
2252
2253 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
2254 {
2255         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2256         if (idx < 0 || idx >= el->num_values) {
2257                 PyErr_SetString(PyExc_IndexError, "Out of range");
2258                 return NULL;
2259         }
2260         return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
2261 }
2262
2263 static PySequenceMethods py_ldb_msg_element_seq = {
2264         .sq_length = (lenfunc)py_ldb_msg_element_len,
2265         .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
2266 };
2267
2268 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
2269 {
2270         int ret = ldb_msg_element_compare(pyldb_MessageElement_AsMessageElement(self),
2271                                                                           pyldb_MessageElement_AsMessageElement(other));
2272         return SIGN(ret);
2273 }
2274
2275 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
2276 {
2277         PyObject *el = ldb_msg_element_to_set(NULL,
2278                                               pyldb_MessageElement_AsMessageElement(self));
2279         return PyObject_GetIter(el);
2280 }
2281
2282 static PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
2283 {
2284         PyLdbMessageElementObject *ret;
2285         ret = PyObject_New(PyLdbMessageElementObject, &PyLdbMessageElement);
2286         if (ret == NULL) {
2287                 PyErr_NoMemory();
2288                 return NULL;
2289         }
2290         ret->mem_ctx = talloc_new(NULL);
2291         if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
2292                 PyErr_NoMemory();
2293                 return NULL;
2294         }
2295         ret->el = el;
2296         return (PyObject *)ret;
2297 }
2298
2299 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2300 {
2301         PyObject *py_elements = NULL;
2302         struct ldb_message_element *el;
2303         unsigned int flags = 0;
2304         char *name = NULL;
2305         const char * const kwnames[] = { "elements", "flags", "name", NULL };
2306         PyLdbMessageElementObject *ret;
2307         TALLOC_CTX *mem_ctx;
2308
2309         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OIs",
2310                                          discard_const_p(char *, kwnames),
2311                                          &py_elements, &flags, &name))
2312                 return NULL;
2313
2314         mem_ctx = talloc_new(NULL);
2315         if (mem_ctx == NULL) {
2316                 PyErr_NoMemory();
2317                 return NULL;
2318         }
2319
2320         el = talloc_zero(mem_ctx, struct ldb_message_element);
2321         if (el == NULL) {
2322                 PyErr_NoMemory();
2323                 talloc_free(mem_ctx);
2324                 return NULL;
2325         }
2326
2327         if (py_elements != NULL) {
2328                 Py_ssize_t i;
2329                 if (PyString_Check(py_elements)) {
2330                         el->num_values = 1;
2331                         el->values = talloc_array(el, struct ldb_val, 1);
2332                         if (el->values == NULL) {
2333                                 talloc_free(mem_ctx);
2334                                 PyErr_NoMemory();
2335                                 return NULL;
2336                         }
2337                         el->values[0].length = PyString_Size(py_elements);
2338                         el->values[0].data = talloc_memdup(el->values, 
2339                                 (uint8_t *)PyString_AsString(py_elements), el->values[0].length+1);
2340                 } else if (PySequence_Check(py_elements)) {
2341                         el->num_values = PySequence_Size(py_elements);
2342                         el->values = talloc_array(el, struct ldb_val, el->num_values);
2343                         if (el->values == NULL) {
2344                                 talloc_free(mem_ctx);
2345                                 PyErr_NoMemory();
2346                                 return NULL;
2347                         }
2348                         for (i = 0; i < el->num_values; i++) {
2349                                 PyObject *item = PySequence_GetItem(py_elements, i);
2350                                 if (item == NULL) {
2351                                         talloc_free(mem_ctx);
2352                                         return NULL;
2353                                 }
2354                                 if (!PyString_Check(item)) {
2355                                         PyErr_Format(PyExc_TypeError, 
2356                                                      "Expected string as element %zd in list", i);
2357                                         talloc_free(mem_ctx);
2358                                         return NULL;
2359                                 }
2360                                 el->values[i].length = PyString_Size(item);
2361                                 el->values[i].data = talloc_memdup(el,
2362                                         (uint8_t *)PyString_AsString(item), el->values[i].length+1);
2363                         }
2364                 } else {
2365                         PyErr_SetString(PyExc_TypeError, 
2366                                         "Expected string or list");
2367                         talloc_free(mem_ctx);
2368                         return NULL;
2369                 }
2370         }
2371
2372         el->flags = flags;
2373         el->name = talloc_strdup(el, name);
2374
2375         ret = PyObject_New(PyLdbMessageElementObject, type);
2376         if (ret == NULL) {
2377                 talloc_free(mem_ctx);
2378                 return NULL;
2379         }
2380
2381         ret->mem_ctx = mem_ctx;
2382         ret->el = el;
2383         return (PyObject *)ret;
2384 }
2385
2386 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
2387 {
2388         char *element_str = NULL;
2389         Py_ssize_t i;
2390         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2391         PyObject *ret;
2392
2393         for (i = 0; i < el->num_values; i++) {
2394                 PyObject *o = py_ldb_msg_element_find(self, i);
2395                 if (element_str == NULL)
2396                         element_str = talloc_strdup(NULL, PyObject_REPR(o));
2397                 else
2398                         element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
2399         }
2400
2401         if (element_str != NULL) {
2402                 ret = PyString_FromFormat("MessageElement([%s])", element_str);
2403                 talloc_free(element_str);
2404         } else {
2405                 ret = PyString_FromString("MessageElement([])");
2406         }
2407
2408         return ret;
2409 }
2410
2411 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
2412 {
2413         struct ldb_message_element *el = pyldb_MessageElement_AsMessageElement(self);
2414
2415         if (el->num_values == 1)
2416                 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
2417         else
2418                 Py_RETURN_NONE;
2419 }
2420
2421 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
2422 {
2423         talloc_free(self->mem_ctx);
2424         PyObject_Del(self);
2425 }
2426
2427 static PyTypeObject PyLdbMessageElement = {
2428         .tp_name = "ldb.MessageElement",
2429         .tp_basicsize = sizeof(PyLdbMessageElementObject),
2430         .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
2431         .tp_repr = (reprfunc)py_ldb_msg_element_repr,
2432         .tp_str = (reprfunc)py_ldb_msg_element_str,
2433         .tp_methods = py_ldb_msg_element_methods,
2434         .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
2435         .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
2436         .tp_as_sequence = &py_ldb_msg_element_seq,
2437         .tp_new = py_ldb_msg_element_new,
2438         .tp_flags = Py_TPFLAGS_DEFAULT,
2439 };
2440
2441
2442 static PyObject *py_ldb_msg_from_dict(PyTypeObject *type, PyObject *args)
2443 {
2444         PyObject *py_ldb;
2445         PyObject *py_dict;
2446         PyObject *py_ret;
2447         struct ldb_message *msg;
2448         struct ldb_context *ldb_ctx;
2449         unsigned int mod_flags = LDB_FLAG_MOD_REPLACE;
2450
2451         if (!PyArg_ParseTuple(args, "O!O!|I",
2452                               &PyLdb, &py_ldb, &PyDict_Type, &py_dict,
2453                               &mod_flags)) {
2454                 return NULL;
2455         }
2456
2457         /* mask only flags we are going to use */
2458         mod_flags = LDB_FLAG_MOD_TYPE(mod_flags);
2459         if (!mod_flags) {
2460                 PyErr_SetString(PyExc_ValueError,
2461                                 "FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE"
2462                                 " expected as mod_flag value");
2463                 return NULL;
2464         }
2465
2466         ldb_ctx = pyldb_Ldb_AsLdbContext(py_ldb);
2467
2468         msg = PyDict_AsMessage(ldb_ctx, py_dict, ldb_ctx, mod_flags);
2469         if (!msg) {
2470                 return NULL;
2471         }
2472
2473         py_ret = PyLdbMessage_FromMessage(msg);
2474
2475         talloc_unlink(ldb_ctx, msg);
2476
2477         return py_ret;
2478 }
2479
2480 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
2481 {
2482         char *name;
2483         if (!PyArg_ParseTuple(args, "s", &name))
2484                 return NULL;
2485
2486         ldb_msg_remove_attr(self->msg, name);
2487
2488         Py_RETURN_NONE;
2489 }
2490
2491 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
2492 {
2493         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2494         Py_ssize_t i, j = 0;
2495         PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
2496         if (msg->dn != NULL) {
2497                 PyList_SetItem(obj, j, PyString_FromString("dn"));
2498                 j++;
2499         }
2500         for (i = 0; i < msg->num_elements; i++) {
2501                 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
2502                 j++;
2503         }
2504         return obj;
2505 }
2506
2507 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
2508 {
2509         struct ldb_message_element *el;
2510         char *name;
2511         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2512         if (!PyString_Check(py_name)) {
2513                 PyErr_SetNone(PyExc_TypeError);
2514                 return NULL;
2515         }
2516         name = PyString_AsString(py_name);
2517         if (!strcmp(name, "dn"))
2518                 return pyldb_Dn_FromDn(msg->dn);
2519         el = ldb_msg_find_element(msg, name);
2520         if (el == NULL) {
2521                 return NULL;
2522         }
2523         return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg->elements);
2524 }
2525
2526 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
2527 {
2528         PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
2529         if (ret == NULL) {
2530                 PyErr_SetString(PyExc_KeyError, "No such element");
2531                 return NULL;
2532         }
2533         return ret;
2534 }
2535
2536 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args)
2537 {
2538         PyObject *name, *ret, *retobj;
2539         retobj = NULL;
2540         if (!PyArg_ParseTuple(args, "O|O", &name, &retobj))
2541                 return NULL;
2542
2543         ret = py_ldb_msg_getitem_helper(self, name);
2544         if (ret == NULL) {
2545                 if (PyErr_Occurred())
2546                         return NULL;
2547                 if (retobj != NULL) {
2548                         return retobj;
2549                 } else {
2550                         Py_RETURN_NONE;
2551                 }
2552         }
2553         return ret;
2554 }
2555
2556 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
2557 {
2558         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2559         Py_ssize_t i, j = 0;
2560         PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
2561         if (msg->dn != NULL) {
2562                 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", pyldb_Dn_FromDn(msg->dn)));
2563                 j++;
2564         }
2565         for (i = 0; i < msg->num_elements; i++, j++) {
2566                 PyObject *py_el = PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements);
2567                 PyObject *value = Py_BuildValue("(sO)", msg->elements[i].name, py_el);
2568                 PyList_SetItem(l, j, value);
2569         }
2570         return l;
2571 }
2572
2573 static PyObject *py_ldb_msg_elements(PyLdbMessageObject *self)
2574 {
2575         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2576         Py_ssize_t i = 0;
2577         PyObject *l = PyList_New(msg->num_elements);
2578         for (i = 0; i < msg->num_elements; i++) {
2579                 PyList_SetItem(l, i, PyLdbMessageElement_FromMessageElement(&msg->elements[i], msg->elements));
2580         }
2581         return l;
2582 }
2583
2584 static PyObject *py_ldb_msg_add(PyLdbMessageObject *self, PyObject *args)
2585 {
2586         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2587         PyLdbMessageElementObject *py_element;
2588         int ret;
2589         struct ldb_message_element *el;
2590
2591         if (!PyArg_ParseTuple(args, "O!", &PyLdbMessageElement, &py_element))
2592                 return NULL;
2593
2594         el = talloc_reference(msg, py_element->el);
2595         if (el == NULL) {
2596                 PyErr_NoMemory();
2597                 return NULL;
2598         }
2599
2600         ret = ldb_msg_add(msg, el, el->flags);
2601         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
2602
2603         Py_RETURN_NONE;
2604 }
2605
2606 static PyMethodDef py_ldb_msg_methods[] = {
2607         { "from_dict", (PyCFunction)py_ldb_msg_from_dict, METH_CLASS | METH_VARARGS,
2608                 "Message.from_dict(ldb, dict, mod_flag=FLAG_MOD_REPLACE) -> ldb.Message\n"
2609                 "Class method to create ldb.Message object from Dictionary.\n"
2610                 "mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE."},
2611         { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, 
2612                 "S.keys() -> list\n\n"
2613                 "Return sequence of all attribute names." },
2614         { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, 
2615                 "S.remove(name)\n\n"
2616                 "Remove all entries for attributes with the specified name."},
2617         { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL },
2618         { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
2619         { "elements", (PyCFunction)py_ldb_msg_elements, METH_NOARGS, NULL },
2620         { "add", (PyCFunction)py_ldb_msg_add, METH_VARARGS,
2621                 "S.append(element)\n\n"
2622                 "Add an element to this message." },
2623         { NULL },
2624 };
2625
2626 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
2627 {
2628         PyObject *list, *iter;
2629
2630         list = py_ldb_msg_keys(self);
2631         iter = PyObject_GetIter(list);
2632         Py_DECREF(list);
2633         return iter;
2634 }
2635
2636 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
2637 {
2638         char *attr_name;
2639
2640         if (!PyString_Check(name)) {
2641                 PyErr_SetNone(PyExc_TypeError);
2642                 return -1;
2643         }
2644
2645         attr_name = PyString_AsString(name);
2646         if (value == NULL) {
2647                 /* delitem */
2648                 ldb_msg_remove_attr(self->msg, attr_name);
2649         } else {
2650                 struct ldb_message_element *el = PyObject_AsMessageElement(self->msg,
2651                                                                            value, 0, attr_name);
2652                 if (el == NULL)
2653                         return -1;
2654                 ldb_msg_remove_attr(pyldb_Message_AsMessage(self), attr_name);
2655                 ldb_msg_add(pyldb_Message_AsMessage(self), el, el->flags);
2656         }
2657         return 0;
2658 }
2659
2660 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
2661 {
2662         return pyldb_Message_AsMessage(self)->num_elements;
2663 }
2664
2665 static PyMappingMethods py_ldb_msg_mapping = {
2666         .mp_length = (lenfunc)py_ldb_msg_length,
2667         .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
2668         .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
2669 };
2670
2671 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2672 {
2673         const char * const kwnames[] = { "dn", NULL };
2674         struct ldb_message *ret;
2675         TALLOC_CTX *mem_ctx;
2676         PyObject *pydn = NULL;
2677         PyLdbMessageObject *py_ret;
2678
2679         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
2680                                          discard_const_p(char *, kwnames),
2681                                          &pydn))
2682                 return NULL;
2683
2684         mem_ctx = talloc_new(NULL);
2685         if (mem_ctx == NULL) {
2686                 PyErr_NoMemory();
2687                 return NULL;
2688         }
2689
2690         ret = ldb_msg_new(mem_ctx);
2691         if (ret == NULL) {
2692                 talloc_free(mem_ctx);
2693                 PyErr_NoMemory();
2694                 return NULL;
2695         }
2696
2697         if (pydn != NULL) {
2698                 struct ldb_dn *dn;
2699                 if (!pyldb_Object_AsDn(NULL, pydn, NULL, &dn)) {
2700                         talloc_free(mem_ctx);
2701                         return NULL;
2702                 }
2703                 ret->dn = talloc_reference(ret, dn);
2704         }
2705
2706         py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
2707         if (py_ret == NULL) {
2708                 PyErr_NoMemory();
2709                 talloc_free(mem_ctx);
2710                 return NULL;
2711         }
2712
2713         py_ret->mem_ctx = mem_ctx;
2714         py_ret->msg = ret;
2715         return (PyObject *)py_ret;
2716 }
2717
2718 static PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
2719 {
2720         PyLdbMessageObject *ret;
2721
2722         ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
2723         if (ret == NULL) {
2724                 PyErr_NoMemory();
2725                 return NULL;
2726         }
2727         ret->mem_ctx = talloc_new(NULL);
2728         ret->msg = talloc_reference(ret->mem_ctx, msg);
2729         return (PyObject *)ret;
2730 }
2731
2732 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
2733 {
2734         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2735         return pyldb_Dn_FromDn(msg->dn);
2736 }
2737
2738 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
2739 {
2740         struct ldb_message *msg = pyldb_Message_AsMessage(self);
2741         if (!pyldb_Dn_Check(value)) {
2742                 PyErr_SetNone(PyExc_TypeError);
2743                 return -1;
2744         }
2745
2746         msg->dn = talloc_reference(msg, pyldb_Dn_AsDn(value));
2747         return 0;
2748 }
2749
2750 static PyGetSetDef py_ldb_msg_getset[] = {
2751         { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
2752         { NULL }
2753 };
2754
2755 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
2756 {
2757         PyObject *dict = PyDict_New(), *ret;
2758         if (PyDict_Update(dict, (PyObject *)self) != 0)
2759                 return NULL;
2760         ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
2761         Py_DECREF(dict);
2762         return ret;
2763 }
2764
2765 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
2766 {
2767         talloc_free(self->mem_ctx);
2768         PyObject_Del(self);
2769 }
2770
2771 static int py_ldb_msg_compare(PyLdbMessageObject *py_msg1,
2772                               PyLdbMessageObject *py_msg2)
2773 {
2774         struct ldb_message *msg1 = pyldb_Message_AsMessage(py_msg1),
2775                            *msg2 = pyldb_Message_AsMessage(py_msg2);
2776         unsigned int i;
2777         int ret;
2778
2779         if ((msg1->dn != NULL) || (msg2->dn != NULL)) {
2780                 ret = ldb_dn_compare(msg1->dn, msg2->dn);
2781                 if (ret != 0) {
2782                         return SIGN(ret);
2783                 }
2784         }
2785
2786         ret = msg1->num_elements - msg2->num_elements;
2787         if (ret != 0) {
2788                 return SIGN(ret);
2789         }
2790
2791         for (i = 0; i < msg1->num_elements; i++) {
2792                 ret = ldb_msg_element_compare_name(&msg1->elements[i],
2793                                                    &msg2->elements[i]);
2794                 if (ret != 0) {
2795                         return SIGN(ret);
2796                 }
2797
2798                 ret = ldb_msg_element_compare(&msg1->elements[i],
2799                                               &msg2->elements[i]);
2800                 if (ret != 0) {
2801                         return SIGN(ret);
2802                 }
2803         }
2804
2805         return 0;
2806 }
2807
2808 static PyTypeObject PyLdbMessage = {
2809         .tp_name = "ldb.Message",
2810         .tp_methods = py_ldb_msg_methods,
2811         .tp_getset = py_ldb_msg_getset,
2812         .tp_as_mapping = &py_ldb_msg_mapping,
2813         .tp_basicsize = sizeof(PyLdbMessageObject),
2814         .tp_dealloc = (destructor)py_ldb_msg_dealloc,
2815         .tp_new = py_ldb_msg_new,
2816         .tp_repr = (reprfunc)py_ldb_msg_repr,
2817         .tp_flags = Py_TPFLAGS_DEFAULT,
2818         .tp_iter = (getiterfunc)py_ldb_msg_iter,
2819         .tp_compare = (cmpfunc)py_ldb_msg_compare,
2820 };
2821
2822 static PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
2823 {
2824         PyLdbTreeObject *ret;
2825
2826         ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
2827         if (ret == NULL) {
2828                 PyErr_NoMemory();
2829                 return NULL;
2830         }
2831
2832         ret->mem_ctx = talloc_new(NULL);
2833         ret->tree = talloc_reference(ret->mem_ctx, tree);
2834         return (PyObject *)ret;
2835 }
2836
2837 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
2838 {
2839         talloc_free(self->mem_ctx);
2840         PyObject_Del(self);
2841 }
2842
2843 static PyTypeObject PyLdbTree = {
2844         .tp_name = "ldb.Tree",
2845         .tp_basicsize = sizeof(PyLdbTreeObject),
2846         .tp_dealloc = (destructor)py_ldb_tree_dealloc,
2847         .tp_flags = Py_TPFLAGS_DEFAULT,
2848 };
2849
2850 /* Ldb_module */
2851 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
2852 {
2853         PyObject *py_ldb = (PyObject *)mod->private_data;
2854         PyObject *py_result, *py_base, *py_attrs, *py_tree;
2855
2856         py_base = pyldb_Dn_FromDn(req->op.search.base);
2857
2858         if (py_base == NULL)
2859                 return LDB_ERR_OPERATIONS_ERROR;
2860
2861         py_tree = PyLdbTree_FromTree(req->op.search.tree);
2862
2863         if (py_tree == NULL)
2864                 return LDB_ERR_OPERATIONS_ERROR;
2865
2866         if (req->op.search.attrs == NULL) {
2867                 py_attrs = Py_None;
2868         } else {
2869                 int i, len;
2870                 for (len = 0; req->op.search.attrs[len]; len++);
2871                 py_attrs = PyList_New(len);
2872                 for (i = 0; i < len; i++)
2873                         PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
2874         }
2875
2876         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
2877                                         discard_const_p(char, "OiOO"),
2878                                         py_base, req->op.search.scope, py_tree, py_attrs);
2879
2880         Py_DECREF(py_attrs);
2881         Py_DECREF(py_tree);
2882         Py_DECREF(py_base);
2883
2884         if (py_result == NULL) {
2885                 return LDB_ERR_PYTHON_EXCEPTION;
2886         }
2887
2888         req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
2889         if (req->op.search.res == NULL) {
2890                 return LDB_ERR_PYTHON_EXCEPTION;
2891         }
2892
2893         Py_DECREF(py_result);
2894
2895         return LDB_SUCCESS;
2896 }
2897
2898 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
2899 {
2900         PyObject *py_ldb = (PyObject *)mod->private_data;
2901         PyObject *py_result, *py_msg;
2902
2903         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
2904
2905         if (py_msg == NULL) {
2906                 return LDB_ERR_OPERATIONS_ERROR;
2907         }
2908
2909         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
2910                                         discard_const_p(char, "O"),
2911                                         py_msg);
2912
2913         Py_DECREF(py_msg);
2914
2915         if (py_result == NULL) {
2916                 return LDB_ERR_PYTHON_EXCEPTION;
2917         }
2918
2919         Py_DECREF(py_result);
2920
2921         return LDB_SUCCESS;
2922 }
2923
2924 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
2925 {
2926         PyObject *py_ldb = (PyObject *)mod->private_data;
2927         PyObject *py_result, *py_msg;
2928
2929         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
2930
2931         if (py_msg == NULL) {
2932                 return LDB_ERR_OPERATIONS_ERROR;
2933         }
2934
2935         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
2936                                         discard_const_p(char, "O"),
2937                                         py_msg);
2938
2939         Py_DECREF(py_msg);
2940
2941         if (py_result == NULL) {
2942                 return LDB_ERR_PYTHON_EXCEPTION;
2943         }
2944
2945         Py_DECREF(py_result);
2946
2947         return LDB_SUCCESS;
2948 }
2949
2950 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
2951 {
2952         PyObject *py_ldb = (PyObject *)mod->private_data;
2953         PyObject *py_result, *py_dn;
2954
2955         py_dn = pyldb_Dn_FromDn(req->op.del.dn);
2956
2957         if (py_dn == NULL)
2958                 return LDB_ERR_OPERATIONS_ERROR;
2959
2960         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
2961                                         discard_const_p(char, "O"),
2962                                         py_dn);
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_rename(struct ldb_module *mod, struct ldb_request *req)
2974 {
2975         PyObject *py_ldb = (PyObject *)mod->private_data;
2976         PyObject *py_result, *py_olddn, *py_newdn;
2977
2978         py_olddn = pyldb_Dn_FromDn(req->op.rename.olddn);
2979
2980         if (py_olddn == NULL)
2981                 return LDB_ERR_OPERATIONS_ERROR;
2982
2983         py_newdn = pyldb_Dn_FromDn(req->op.rename.newdn);
2984
2985         if (py_newdn == NULL)
2986                 return LDB_ERR_OPERATIONS_ERROR;
2987
2988         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
2989                                         discard_const_p(char, "OO"),
2990                                         py_olddn, py_newdn);
2991
2992         Py_DECREF(py_olddn);
2993         Py_DECREF(py_newdn);
2994
2995         if (py_result == NULL) {
2996                 return LDB_ERR_PYTHON_EXCEPTION;
2997         }
2998
2999         Py_DECREF(py_result);
3000
3001         return LDB_SUCCESS;
3002 }
3003
3004 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
3005 {
3006         PyObject *py_ldb = (PyObject *)mod->private_data;
3007         PyObject *py_result;
3008
3009         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
3010                                         discard_const_p(char, ""));
3011
3012         return LDB_ERR_OPERATIONS_ERROR;
3013 }
3014
3015 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
3016 {
3017         PyObject *py_ldb = (PyObject *)mod->private_data;
3018         PyObject *py_result;
3019
3020         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
3021                                         discard_const_p(char, ""));
3022
3023         return LDB_ERR_OPERATIONS_ERROR;
3024 }
3025
3026 static int py_module_start_transaction(struct ldb_module *mod)
3027 {
3028         PyObject *py_ldb = (PyObject *)mod->private_data;
3029         PyObject *py_result;
3030
3031         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
3032                                         discard_const_p(char, ""));
3033
3034         if (py_result == NULL) {
3035                 return LDB_ERR_PYTHON_EXCEPTION;
3036         }
3037
3038         Py_DECREF(py_result);
3039
3040         return LDB_SUCCESS;
3041 }
3042
3043 static int py_module_end_transaction(struct ldb_module *mod)
3044 {
3045         PyObject *py_ldb = (PyObject *)mod->private_data;
3046         PyObject *py_result;
3047
3048         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
3049                                         discard_const_p(char, ""));
3050
3051         if (py_result == NULL) {
3052                 return LDB_ERR_PYTHON_EXCEPTION;
3053         }
3054
3055         Py_DECREF(py_result);
3056
3057         return LDB_SUCCESS;
3058 }
3059
3060 static int py_module_del_transaction(struct ldb_module *mod)
3061 {
3062         PyObject *py_ldb = (PyObject *)mod->private_data;
3063         PyObject *py_result;
3064
3065         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
3066                                         discard_const_p(char, ""));
3067
3068         if (py_result == NULL) {
3069                 return LDB_ERR_PYTHON_EXCEPTION;
3070         }
3071
3072         Py_DECREF(py_result);
3073
3074         return LDB_SUCCESS;
3075 }
3076
3077 static int py_module_destructor(struct ldb_module *mod)
3078 {
3079         Py_DECREF((PyObject *)mod->private_data);
3080         return 0;
3081 }
3082
3083 static int py_module_init(struct ldb_module *mod)
3084 {
3085         PyObject *py_class = (PyObject *)mod->ops->private_data;
3086         PyObject *py_result, *py_next, *py_ldb;
3087
3088         py_ldb = PyLdb_FromLdbContext(mod->ldb);
3089
3090         if (py_ldb == NULL)
3091                 return LDB_ERR_OPERATIONS_ERROR;
3092
3093         py_next = PyLdbModule_FromModule(mod->next);
3094
3095         if (py_next == NULL)
3096                 return LDB_ERR_OPERATIONS_ERROR;
3097
3098         py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
3099                                           py_ldb, py_next);
3100
3101         if (py_result == NULL) {
3102                 return LDB_ERR_PYTHON_EXCEPTION;
3103         }
3104
3105         mod->private_data = py_result;
3106
3107         talloc_set_destructor(mod, py_module_destructor);
3108
3109         return ldb_next_init(mod);
3110 }
3111
3112 static PyObject *py_register_module(PyObject *module, PyObject *args)
3113 {
3114         int ret;
3115         struct ldb_module_ops *ops;
3116         PyObject *input;
3117
3118         if (!PyArg_ParseTuple(args, "O", &input))
3119                 return NULL;
3120
3121         ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
3122         if (ops == NULL) {
3123                 PyErr_NoMemory();
3124                 return NULL;
3125         }
3126
3127         ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
3128
3129         Py_INCREF(input);
3130         ops->private_data = input;
3131         ops->init_context = py_module_init;
3132         ops->search = py_module_search;
3133         ops->add = py_module_add;
3134         ops->modify = py_module_modify;
3135         ops->del = py_module_del;
3136         ops->rename = py_module_rename;
3137         ops->request = py_module_request;
3138         ops->extended = py_module_extended;
3139         ops->start_transaction = py_module_start_transaction;
3140         ops->end_transaction = py_module_end_transaction;
3141         ops->del_transaction = py_module_del_transaction;
3142
3143         ret = ldb_register_module(ops);
3144
3145         PyErr_LDB_ERROR_IS_ERR_RAISE(PyExc_LdbError, ret, NULL);
3146
3147         Py_RETURN_NONE;
3148 }
3149
3150 static PyObject *py_timestring(PyObject *module, PyObject *args)
3151 {
3152         /* most times "time_t" is a signed integer type with 32 or 64 bit:
3153          * http://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
3154         long int t_val;
3155         char *tresult;
3156         PyObject *ret;
3157         if (!PyArg_ParseTuple(args, "l", &t_val))
3158                 return NULL;
3159         tresult = ldb_timestring(NULL, (time_t) t_val);
3160         ret = PyString_FromString(tresult);
3161         talloc_free(tresult);
3162         return ret;
3163 }
3164
3165 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
3166 {
3167         char *str;
3168         if (!PyArg_ParseTuple(args, "s", &str))
3169                 return NULL;
3170
3171         return PyInt_FromLong(ldb_string_to_time(str));
3172 }
3173
3174 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
3175 {
3176         char *name;
3177         if (!PyArg_ParseTuple(args, "s", &name))
3178                 return NULL;
3179         return PyBool_FromLong(ldb_valid_attr_name(name));
3180 }
3181
3182 /*
3183   encode a string using RFC2254 rules
3184  */
3185 static PyObject *py_binary_encode(PyObject *self, PyObject *args)
3186 {
3187         char *str, *encoded;
3188         int size = 0;
3189         struct ldb_val val;
3190         PyObject *ret;
3191
3192         if (!PyArg_ParseTuple(args, "s#", &str, &size))
3193                 return NULL;
3194         val.data = (uint8_t *)str;
3195         val.length = size;
3196
3197         encoded = ldb_binary_encode(NULL, val);
3198         if (encoded == NULL) {
3199                 PyErr_SetString(PyExc_TypeError, "unable to encode binary string");
3200                 return NULL;
3201         }
3202         ret = PyString_FromString(encoded);
3203         talloc_free(encoded);
3204         return ret;
3205 }
3206
3207 /*
3208   decode a string using RFC2254 rules
3209  */
3210 static PyObject *py_binary_decode(PyObject *self, PyObject *args)
3211 {
3212         char *str;
3213         struct ldb_val val;
3214         PyObject *ret;
3215
3216         if (!PyArg_ParseTuple(args, "s", &str))
3217                 return NULL;
3218
3219         val = ldb_binary_decode(NULL, str);
3220         if (val.data == NULL) {
3221                 PyErr_SetString(PyExc_TypeError, "unable to decode binary string");
3222                 return NULL;
3223         }
3224         ret = Py_BuildValue("s#", val.data, val.length);
3225         talloc_free(val.data);
3226         return ret;
3227 }
3228
3229 static PyMethodDef py_ldb_global_methods[] = {
3230         { "register_module", py_register_module, METH_VARARGS, 
3231                 "S.register_module(module) -> None\n"
3232                 "Register a LDB module."},
3233         { "timestring", py_timestring, METH_VARARGS, 
3234                 "S.timestring(int) -> string\n"
3235                 "Generate a LDAP time string from a UNIX timestamp" },
3236         { "string_to_time", py_string_to_time, METH_VARARGS,
3237                 "S.string_to_time(string) -> int\n"
3238                 "Parse a LDAP time string into a UNIX timestamp." },
3239         { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
3240                 "S.valid_attr_name(name) -> bool\n"
3241                 "Check whether the supplied name is a valid attribute name." },
3242         { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
3243                 NULL },
3244         { "binary_encode", py_binary_encode, METH_VARARGS,
3245                 "S.binary_encode(string) -> string\n"
3246                 "Perform a RFC2254 binary encoding on a string" },
3247         { "binary_decode", py_binary_decode, METH_VARARGS,
3248                 "S.binary_decode(string) -> string\n"
3249                 "Perform a RFC2254 binary decode on a string" },
3250         { NULL }
3251 };
3252
3253 void initldb(void)
3254 {
3255         PyObject *m;
3256
3257         if (PyType_Ready(&PyLdbDn) < 0)
3258                 return;
3259
3260         if (PyType_Ready(&PyLdbMessage) < 0)
3261                 return;
3262
3263         if (PyType_Ready(&PyLdbMessageElement) < 0)
3264                 return;
3265
3266         if (PyType_Ready(&PyLdb) < 0)
3267                 return;
3268
3269         if (PyType_Ready(&PyLdbModule) < 0)
3270                 return;
3271
3272         if (PyType_Ready(&PyLdbTree) < 0)
3273                 return;
3274
3275         if (PyType_Ready(&PyLdbResult) < 0)
3276                 return;
3277
3278         if (PyType_Ready(&PyLdbControl) < 0)
3279                 return;
3280
3281         m = Py_InitModule3("ldb", py_ldb_global_methods, 
3282                 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
3283         if (m == NULL)
3284                 return;
3285
3286         PyModule_AddObject(m, "SEQ_HIGHEST_SEQ", PyInt_FromLong(LDB_SEQ_HIGHEST_SEQ));
3287         PyModule_AddObject(m, "SEQ_HIGHEST_TIMESTAMP", PyInt_FromLong(LDB_SEQ_HIGHEST_TIMESTAMP));
3288         PyModule_AddObject(m, "SEQ_NEXT", PyInt_FromLong(LDB_SEQ_NEXT));
3289         PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
3290         PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
3291         PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
3292         PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
3293
3294         PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
3295         PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
3296         PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
3297         PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
3298
3299         PyModule_AddObject(m, "FLAG_MOD_ADD", PyInt_FromLong(LDB_FLAG_MOD_ADD));
3300         PyModule_AddObject(m, "FLAG_MOD_REPLACE", PyInt_FromLong(LDB_FLAG_MOD_REPLACE));
3301         PyModule_AddObject(m, "FLAG_MOD_DELETE", PyInt_FromLong(LDB_FLAG_MOD_DELETE));
3302
3303         PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
3304         PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
3305         PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
3306         PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
3307         PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
3308         PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
3309         PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
3310         PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
3311         PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
3312         PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
3313         PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
3314         PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
3315         PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
3316         PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
3317         PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
3318         PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
3319         PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
3320         PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
3321         PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
3322         PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
3323         PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
3324         PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
3325         PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
3326         PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
3327         PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
3328         PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
3329         PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
3330         PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
3331         PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
3332         PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
3333         PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
3334         PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
3335         PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
3336         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
3337         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
3338         PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
3339         PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
3340         PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
3341         PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
3342
3343         PyModule_AddObject(m, "FLG_RDONLY", PyInt_FromLong(LDB_FLG_RDONLY));
3344         PyModule_AddObject(m, "FLG_NOSYNC", PyInt_FromLong(LDB_FLG_NOSYNC));
3345         PyModule_AddObject(m, "FLG_RECONNECT", PyInt_FromLong(LDB_FLG_RECONNECT));
3346         PyModule_AddObject(m, "FLG_NOMMAP", PyInt_FromLong(LDB_FLG_NOMMAP));
3347
3348         PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
3349
3350         PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
3351         PyModule_AddObject(m, "LdbError", PyExc_LdbError);
3352
3353         Py_INCREF(&PyLdb);
3354         Py_INCREF(&PyLdbDn);
3355         Py_INCREF(&PyLdbModule);
3356         Py_INCREF(&PyLdbMessage);
3357         Py_INCREF(&PyLdbMessageElement);
3358         Py_INCREF(&PyLdbTree);
3359         Py_INCREF(&PyLdbResult);
3360         Py_INCREF(&PyLdbControl);
3361
3362         PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
3363         PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
3364         PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
3365         PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
3366         PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
3367         PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
3368         PyModule_AddObject(m, "Control", (PyObject *)&PyLdbControl);
3369
3370         PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION));
3371
3372 #define ADD_LDB_STRING(val)  PyModule_AddObject(m, #val, PyString_FromString(LDB_## val))
3373
3374         ADD_LDB_STRING(SYNTAX_DN);
3375         ADD_LDB_STRING(SYNTAX_DN);
3376         ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
3377         ADD_LDB_STRING(SYNTAX_INTEGER);
3378         ADD_LDB_STRING(SYNTAX_BOOLEAN);
3379         ADD_LDB_STRING(SYNTAX_OCTET_STRING);
3380         ADD_LDB_STRING(SYNTAX_UTC_TIME);
3381         ADD_LDB_STRING(OID_COMPARATOR_AND);
3382         ADD_LDB_STRING(OID_COMPARATOR_OR);
3383 }