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