Merge branch 'master' of ssh://git.samba.org/data/git/samba into wspp-schema
[samba.git] / source4 / lib / ldb / pyldb.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Swig 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-2008 Jelmer Vernooij <jelmer@samba.org>
9
10          ** NOTE! The following LGPL license applies to the ldb
11          ** library. This does NOT imply that all of Samba is released
12          ** under the LGPL
13    
14    This library is free software; you can redistribute it and/or
15    modify it under the terms of the GNU Lesser General Public
16    License as published by the Free Software Foundation; either
17    version 3 of the License, or (at your option) any later version.
18
19    This library is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22    Lesser General Public License for more details.
23
24    You should have received a copy of the GNU Lesser General Public
25    License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 */
27
28 #include "replace.h"
29 #include "ldb_private.h"
30 #include <Python.h>
31 #include "pyldb.h"
32
33 /* There's no Py_ssize_t in 2.4, apparently */
34 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
35 typedef int Py_ssize_t;
36 typedef inquiry lenfunc;
37 typedef intargfunc ssizeargfunc;
38 #endif
39
40 #ifndef Py_RETURN_NONE
41 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
42 #endif
43
44 /* Picked out of thin air. To do this properly, we should probably have some part of the 
45  * errors in LDB be allocated to bindings ? */
46 #define LDB_ERR_PYTHON_EXCEPTION        142
47
48 static PyObject *PyExc_LdbError;
49
50 void PyErr_SetLdbError(int ret, struct ldb_context *ldb_ctx)
51 {
52         if (ret == LDB_ERR_PYTHON_EXCEPTION)
53                 return; /* Python exception should already be set, just keep that */
54         PyErr_SetObject(PyExc_LdbError, Py_BuildValue(discard_const_p(char, "(i,s)"),
55                         ret, ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
56 }
57
58 static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx, 
59                                                            struct ldb_message_element *el, 
60                                                            struct ldb_val *val)
61 {
62         const struct ldb_schema_attribute *a;
63         struct ldb_val new_val;
64         TALLOC_CTX *mem_ctx = talloc_new(NULL);
65         PyObject *ret;
66         
67         new_val = *val;
68         
69         if (ldb_ctx != NULL) {          
70                 a = ldb_schema_attribute_by_name(ldb_ctx, el->name);
71         
72                 if (a != NULL) {
73                         if (a->syntax->ldif_write_fn(ldb_ctx, mem_ctx, val, &new_val) != 0) {
74                                 talloc_free(mem_ctx);
75                                 return NULL;
76                         }
77                 }
78         } 
79         
80         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
81         
82         talloc_free(mem_ctx);
83         
84         return ret;
85 }
86
87 bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, 
88                    struct ldb_context *ldb_ctx, struct ldb_dn **dn)
89 {
90         struct ldb_dn *odn;
91
92         if (ldb_ctx != NULL && PyString_Check(object)) {
93                 odn = ldb_dn_new(mem_ctx, ldb_ctx, PyString_AsString(object));
94                 *dn = odn;
95                 return true;
96         }
97
98         if (PyLdbDn_Check(object)) {
99                 *dn = PyLdbDn_AsDn(object);
100                 return true;
101         }
102
103         PyErr_SetString(PyExc_TypeError, "Expected DN");
104         return false;
105 }
106
107 static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
108 {
109         PyObject *ret;
110         int i;
111         if (result == NULL) {
112                 Py_RETURN_NONE;
113         } 
114         ret = PyList_New(result->count);
115         for (i = 0; i < result->count; i++) {
116                 PyList_SetItem(ret, i, PyLdbMessage_FromMessage(result->msgs[i])
117                 );
118         }
119         return ret;
120 }
121
122 static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, PyObject *obj)
123 {
124         struct ldb_result *res;
125         int i;
126         
127         if (obj == Py_None)
128                 return NULL;
129
130         res = talloc_zero(mem_ctx, struct ldb_result);
131         res->count = PyList_Size(obj);
132         res->msgs = talloc_array(res, struct ldb_message *, res->count);
133         for (i = 0; i < res->count; i++) {
134                 PyObject *item = PyList_GetItem(obj, i);
135                 res->msgs[i] = PyLdbMessage_AsMessage(item);
136         }
137         return res;
138 }
139
140 static PyObject *py_ldb_dn_validate(PyLdbDnObject *self)
141 {
142         return PyBool_FromLong(ldb_dn_validate(self->dn));
143 }
144
145 static PyObject *py_ldb_dn_is_valid(PyLdbDnObject *self)
146 {
147         return PyBool_FromLong(ldb_dn_is_valid(self->dn));
148 }
149
150 static PyObject *py_ldb_dn_is_special(PyLdbDnObject *self)
151 {
152         return PyBool_FromLong(ldb_dn_is_special(self->dn));
153 }
154
155 static PyObject *py_ldb_dn_is_null(PyLdbDnObject *self)
156 {
157         return PyBool_FromLong(ldb_dn_is_null(self->dn));
158 }
159  
160 static PyObject *py_ldb_dn_get_casefold(PyLdbDnObject *self)
161 {
162         return PyString_FromString(ldb_dn_get_casefold(self->dn));
163 }
164
165 static PyObject *py_ldb_dn_get_linearized(PyLdbDnObject *self)
166 {
167         return PyString_FromString(ldb_dn_get_linearized(self->dn));
168 }
169
170 static PyObject *py_ldb_dn_canonical_str(PyLdbDnObject *self)
171 {
172         return PyString_FromString(ldb_dn_canonical_string(self->dn, self->dn));
173 }
174
175 static PyObject *py_ldb_dn_canonical_ex_str(PyLdbDnObject *self)
176 {
177         return PyString_FromString(ldb_dn_canonical_ex_string(self->dn, self->dn));
178 }
179
180 static PyObject *py_ldb_dn_repr(PyLdbDnObject *self)
181 {
182         return PyString_FromFormat("Dn(%s)", PyObject_REPR(PyString_FromString(ldb_dn_get_linearized(self->dn))));
183 }
184
185 static PyObject *py_ldb_dn_check_special(PyLdbDnObject *self, PyObject *args)
186 {
187         char *name;
188
189         if (!PyArg_ParseTuple(args, "s", &name))
190                 return NULL;
191
192         return ldb_dn_check_special(self->dn, name)?Py_True:Py_False;
193 }
194
195 static int py_ldb_dn_compare(PyLdbDnObject *dn1, PyLdbDnObject *dn2)
196 {
197         return ldb_dn_compare(dn1->dn, dn2->dn);
198 }
199
200 static PyObject *py_ldb_dn_get_parent(PyLdbDnObject *self)
201 {
202         struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self);
203         return PyLdbDn_FromDn(ldb_dn_get_parent(NULL, dn));
204 }
205
206 #define dn_ldb_ctx(dn) ((struct ldb_context *)dn)
207
208 static PyObject *py_ldb_dn_add_child(PyLdbDnObject *self, PyObject *args)
209 {
210         PyObject *py_other;
211         struct ldb_dn *dn, *other;
212         if (!PyArg_ParseTuple(args, "O", &py_other))
213                 return NULL;
214
215         dn = PyLdbDn_AsDn((PyObject *)self);
216
217         if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
218                 return NULL;
219
220         return ldb_dn_add_child(dn, other)?Py_True:Py_False;
221 }
222
223 static PyObject *py_ldb_dn_add_base(PyLdbDnObject *self, PyObject *args)
224 {
225         PyObject *py_other;
226         struct ldb_dn *other, *dn;
227         if (!PyArg_ParseTuple(args, "O", &py_other))
228                 return NULL;
229
230         dn = PyLdbDn_AsDn((PyObject *)self);
231
232         if (!PyObject_AsDn(NULL, py_other, dn_ldb_ctx(dn), &other))
233                 return NULL;
234
235         return ldb_dn_add_base(dn, other)?Py_True:Py_False;
236 }
237
238 static PyMethodDef py_ldb_dn_methods[] = {
239         { "validate", (PyCFunction)py_ldb_dn_validate, METH_NOARGS, 
240                 "S.validate() -> bool\n"
241                 "Validate DN is correct." },
242         { "is_valid", (PyCFunction)py_ldb_dn_is_valid, METH_NOARGS,
243                 "S.is_valid() -> bool\n" },
244         { "is_special", (PyCFunction)py_ldb_dn_is_special, METH_NOARGS,
245                 "S.is_special() -> bool\n"
246                 "Check whether this is a special LDB DN." },
247         { "is_null", (PyCFunction)py_ldb_dn_is_null, METH_NOARGS,
248                 "Check whether this is a null DN." },
249         { "get_casefold", (PyCFunction)py_ldb_dn_get_casefold, METH_NOARGS,
250                 NULL },
251         { "get_linearized", (PyCFunction)py_ldb_dn_get_linearized, METH_NOARGS,
252                 NULL },
253         { "canonical_str", (PyCFunction)py_ldb_dn_canonical_str, METH_NOARGS,
254                 "S.canonical_str() -> string\n"
255                 "Canonical version of this DN (like a posix path)." },
256         { "canonical_ex_str", (PyCFunction)py_ldb_dn_canonical_ex_str, METH_NOARGS,
257                 "S.canonical_ex_str() -> string\n"
258                 "Canonical version of this DN (like a posix path, with terminating newline)." },
259         { "check_special", (PyCFunction)py_ldb_dn_is_special, METH_VARARGS, 
260                 NULL },
261         { "parent", (PyCFunction)py_ldb_dn_get_parent, METH_NOARGS,
262                 "S.parent() -> dn\n"
263                 "Get the parent for this DN." },
264         { "add_child", (PyCFunction)py_ldb_dn_add_child, METH_VARARGS, 
265                 "S.add_child(dn) -> None\n"
266                 "Add a child DN to this DN." },
267         { "add_base", (PyCFunction)py_ldb_dn_add_base, METH_VARARGS,
268                 "S.add_base(dn) -> None\n"
269                 "Add a base DN to this DN." },
270         { "check_special", (PyCFunction)py_ldb_dn_check_special, METH_VARARGS,
271                 NULL },
272         { NULL }
273 };
274
275 static Py_ssize_t py_ldb_dn_len(PyLdbDnObject *self)
276 {
277         return ldb_dn_get_comp_num(PyLdbDn_AsDn((PyObject *)self));
278 }
279
280 static PyObject *py_ldb_dn_concat(PyLdbDnObject *self, PyObject *py_other)
281 {
282         struct ldb_dn *dn = PyLdbDn_AsDn((PyObject *)self), 
283                                   *other;
284         struct ldb_dn *ret = ldb_dn_copy(NULL, dn);
285         if (!PyObject_AsDn(NULL, py_other, NULL, &other))
286                 return NULL;
287         ldb_dn_add_child(ret, other);
288         return PyLdbDn_FromDn(ret);
289 }
290
291 static PySequenceMethods py_ldb_dn_seq = {
292         .sq_length = (lenfunc)py_ldb_dn_len,
293         .sq_concat = (binaryfunc)py_ldb_dn_concat,
294 };
295
296 static PyObject *py_ldb_dn_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
297 {
298         struct ldb_dn *ret;
299         char *str;
300         PyObject *py_ldb;
301         struct ldb_context *ldb_ctx;
302         PyLdbDnObject *py_ret;
303         const char * const kwnames[] = { "ldb", "dn", NULL };
304
305         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os",
306                                          discard_const_p(char *, kwnames),
307                                          &py_ldb, &str))
308                 return NULL;
309
310         ldb_ctx = PyLdb_AsLdbContext(py_ldb);
311         
312         ret = ldb_dn_new(ldb_ctx, ldb_ctx, str);
313         /* ldb_dn_new() doesn't accept NULL as memory context, so 
314            we do it this way... */
315         talloc_steal(NULL, ret);
316
317         if (ret == NULL || !ldb_dn_validate(ret)) {
318                 PyErr_SetString(PyExc_ValueError, "unable to parse dn string");
319                 return NULL;
320         }
321
322         py_ret = (PyLdbDnObject *)type->tp_alloc(type, 0);
323         if (ret == NULL) {
324                 PyErr_NoMemory();
325                 return NULL;
326         }
327         py_ret->dn = ret;
328         return (PyObject *)py_ret;
329 }
330
331 PyObject *PyLdbDn_FromDn(struct ldb_dn *dn)
332 {
333         PyLdbDnObject *py_ret;
334         py_ret = (PyLdbDnObject *)PyLdbDn.tp_alloc(&PyLdbDn, 0);
335         if (py_ret == NULL) {
336                 PyErr_NoMemory();
337                 return NULL;
338         }
339         py_ret->mem_ctx = talloc_new(NULL);
340         py_ret->dn = talloc_reference(py_ret->mem_ctx, dn);
341         return (PyObject *)py_ret;
342 }
343
344 static void py_ldb_dn_dealloc(PyLdbDnObject *self)
345 {
346         talloc_free(self->mem_ctx);
347         self->ob_type->tp_free(self);
348 }
349
350 PyTypeObject PyLdbDn = {
351         .tp_name = "Dn",
352         .tp_methods = py_ldb_dn_methods,
353         .tp_str = (reprfunc)py_ldb_dn_get_linearized,
354         .tp_repr = (reprfunc)py_ldb_dn_repr,
355         .tp_compare = (cmpfunc)py_ldb_dn_compare,
356         .tp_as_sequence = &py_ldb_dn_seq,
357         .tp_doc = "A LDB distinguished name.",
358         .tp_new = py_ldb_dn_new,
359         .tp_dealloc = (destructor)py_ldb_dn_dealloc,
360         .tp_basicsize = sizeof(PyLdbObject),
361         .tp_flags = Py_TPFLAGS_DEFAULT,
362 };
363
364 /* Debug */
365 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3, 0);
366 static void py_ldb_debug(void *context, enum ldb_debug_level level, const char *fmt, va_list ap)
367 {
368         PyObject *fn = (PyObject *)context;
369         PyObject_CallFunction(fn, discard_const_p(char, "(i,O)"), level, PyString_FromFormatV(fmt, ap));
370 }
371
372 static PyObject *py_ldb_set_debug(PyLdbObject *self, PyObject *args)
373 {
374         PyObject *cb;
375         
376         if (!PyArg_ParseTuple(args, "O", &cb))
377                 return NULL;
378
379         Py_INCREF(cb);
380         /* FIXME: Where do we DECREF cb ? */
381         PyErr_LDB_ERROR_IS_ERR_RAISE(ldb_set_debug(self->ldb_ctx, py_ldb_debug, cb), PyLdb_AsLdbContext(self));
382         
383         Py_RETURN_NONE;
384 }
385
386 static PyObject *py_ldb_set_create_perms(PyTypeObject *self, PyObject *args)
387 {
388         unsigned int perms;
389         if (!PyArg_ParseTuple(args, "I", &perms))
390                 return NULL;
391
392         ldb_set_create_perms(PyLdb_AsLdbContext(self), perms);
393
394         Py_RETURN_NONE;
395 }
396
397 static PyObject *py_ldb_set_modules_dir(PyTypeObject *self, PyObject *args)
398 {
399         char *modules_dir;
400         if (!PyArg_ParseTuple(args, "s", &modules_dir))
401                 return NULL;
402
403         ldb_set_modules_dir(PyLdb_AsLdbContext(self), modules_dir);
404
405         Py_RETURN_NONE;
406 }
407
408 static PyObject *py_ldb_transaction_start(PyLdbObject *self)
409 {
410         PyErr_LDB_ERROR_IS_ERR_RAISE(ldb_transaction_start(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
411         Py_RETURN_NONE;
412 }
413
414 static PyObject *py_ldb_transaction_commit(PyLdbObject *self)
415 {
416         PyErr_LDB_ERROR_IS_ERR_RAISE(ldb_transaction_commit(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
417         Py_RETURN_NONE;
418 }
419
420 static PyObject *py_ldb_transaction_cancel(PyLdbObject *self)
421 {
422         PyErr_LDB_ERROR_IS_ERR_RAISE(ldb_transaction_cancel(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
423         Py_RETURN_NONE;
424 }
425
426 static PyObject *py_ldb_setup_wellknown_attributes(PyLdbObject *self)
427 {
428         PyErr_LDB_ERROR_IS_ERR_RAISE(ldb_setup_wellknown_attributes(PyLdb_AsLdbContext(self)), PyLdb_AsLdbContext(self));
429         Py_RETURN_NONE;
430 }
431
432 static PyObject *py_ldb_repr(PyLdbObject *self)
433 {
434         return PyString_FromFormat("<ldb connection>");
435 }
436
437 static PyObject *py_ldb_get_root_basedn(PyLdbObject *self)
438 {
439         struct ldb_dn *dn = ldb_get_root_basedn(PyLdb_AsLdbContext(self));
440         if (dn == NULL)
441                 Py_RETURN_NONE;
442         return PyLdbDn_FromDn(dn);
443 }
444
445
446 static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
447 {
448         struct ldb_dn *dn = ldb_get_schema_basedn(PyLdb_AsLdbContext(self));
449         if (dn == NULL)
450                 Py_RETURN_NONE;
451         return PyLdbDn_FromDn(dn);
452 }
453
454
455 static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
456 {
457         struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self));
458         if (dn == NULL)
459                 Py_RETURN_NONE;
460         return PyLdbDn_FromDn(dn);
461 }
462
463
464 static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
465 {
466         struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self));
467         if (dn == NULL)
468                 Py_RETURN_NONE;
469         return PyLdbDn_FromDn(dn);
470 }
471
472 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, 
473                                                                                 const char *paramname)
474 {
475         const char **ret;
476         int i;
477         if (!PyList_Check(list)) {
478                 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
479                 return NULL;
480         }
481         ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
482         for (i = 0; i < PyList_Size(list); i++) {
483                 PyObject *item = PyList_GetItem(list, i);
484                 if (!PyString_Check(item)) {
485                         PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
486                         return NULL;
487                 }
488                 ret[i] = PyString_AsString(item);
489         }
490         ret[i] = NULL;
491         return ret;
492 }
493
494 static int py_ldb_init(PyLdbObject *self, PyObject *args, PyObject *kwargs)
495 {
496         const char * const kwnames[] = { "url", "flags", "options", NULL };
497         char *url = NULL;
498         PyObject *py_options = Py_None;
499         const char **options;
500         int flags = 0;
501         int ret;
502         struct ldb_context *ldb;
503
504         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ziO:Ldb.__init__",
505                                          discard_const_p(char *, kwnames),
506                                          &url, &flags, &py_options))
507                 return -1;
508
509         ldb = PyLdb_AsLdbContext(self);
510
511         if (py_options == Py_None) {
512                 options = NULL;
513         } else {
514                 options = PyList_AsStringList(ldb, py_options, "options");
515                 if (options == NULL)
516                         return -1;
517         }
518         
519         if (url != NULL) {
520                 ret = ldb_connect(ldb, url, flags, options);
521                 if (ret != LDB_SUCCESS) {
522                         PyErr_SetLdbError(ret, ldb);
523                         return -1;
524                 }
525         }
526
527         talloc_free(options);
528         return 0;
529 }
530
531 static PyObject *py_ldb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
532 {
533         PyLdbObject *ret;
534         struct ldb_context *ldb;
535         ldb = ldb_init(NULL, NULL);
536         if (ldb == NULL) {
537                 PyErr_NoMemory();
538                 return NULL;
539         }
540
541         ret = (PyLdbObject *)type->tp_alloc(type, 0);
542         if (ret == NULL) {
543                 PyErr_NoMemory();
544                 return NULL;
545         }
546         ret->ldb_ctx = ldb;
547         return (PyObject *)ret;
548 }
549
550 static PyObject *py_ldb_connect(PyLdbObject *self, PyObject *args, PyObject *kwargs)
551 {
552         char *url;
553         int flags = 0;
554         PyObject *py_options = Py_None;
555         int ret;
556         const char **options;
557         const char * const kwnames[] = { "url", "flags", "options", NULL };
558
559         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iO",
560                                          discard_const_p(char *, kwnames),
561                                          &url, &flags, &py_options))
562                 return NULL;
563
564         if (py_options == Py_None) {
565                 options = NULL;
566         } else {
567                 options = PyList_AsStringList(NULL, py_options, "options");
568                 if (options == NULL)
569                         return NULL;
570         }
571         
572         ret = ldb_connect(PyLdb_AsLdbContext(self), url, flags, options);
573         talloc_free(options);
574
575         PyErr_LDB_ERROR_IS_ERR_RAISE(ret, PyLdb_AsLdbContext(self));
576
577         Py_RETURN_NONE;
578 }
579
580 static PyObject *py_ldb_modify(PyLdbObject *self, PyObject *args)
581 {
582         PyObject *py_msg;
583         int ret;
584         if (!PyArg_ParseTuple(args, "O", &py_msg))
585                 return NULL;
586
587         if (!PyLdbMessage_Check(py_msg)) {
588                 PyErr_SetString(PyExc_TypeError, "Expected Ldb Message");
589                 return NULL;
590         }
591
592         ret = ldb_modify(PyLdb_AsLdbContext(self), PyLdbMessage_AsMessage(py_msg));
593         PyErr_LDB_ERROR_IS_ERR_RAISE(ret, PyLdb_AsLdbContext(self));
594
595         Py_RETURN_NONE;
596 }
597
598 static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
599 {
600         PyObject *py_msg;
601         int ret;
602         Py_ssize_t dict_pos, msg_pos;
603         struct ldb_message_element *msgel;
604         struct ldb_message *msg;
605         PyObject *key, *value;
606
607         if (!PyArg_ParseTuple(args, "O", &py_msg))
608                 return NULL;
609
610         if (PyDict_Check(py_msg)) {
611                 PyObject *dn_value = PyDict_GetItemString(py_msg, "dn");
612                 msg = ldb_msg_new(NULL);
613                 msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg));
614                 msg_pos = dict_pos = 0;
615                 if (dn_value) {
616                         if (!PyObject_AsDn(msg, dn_value, PyLdb_AsLdbContext(self), &msg->dn)) {
617                                 PyErr_SetString(PyExc_TypeError, "unable to import dn object");
618                                 return NULL;
619                         }
620                         if (msg->dn == NULL) {
621                                 PyErr_SetString(PyExc_TypeError, "dn set but not found");
622                                 return NULL;
623                         }
624                 }
625
626                 while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
627                         char *key_str = PyString_AsString(key);
628                         if (strcmp(key_str, "dn") != 0) {
629                                 msgel = PyObject_AsMessageElement(msg->elements, value, 0, key_str);
630                                 if (msgel == NULL) {
631                                         PyErr_SetString(PyExc_TypeError, "unable to import element");
632                                         return NULL;
633                                 }
634                                 memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
635                                 msg_pos++;
636                         }
637                 }
638
639                 if (msg->dn == NULL) {
640                         PyErr_SetString(PyExc_TypeError, "no dn set");
641                         return NULL;
642                 }
643
644                 msg->num_elements = msg_pos;
645         } else {
646                 msg = PyLdbMessage_AsMessage(py_msg);
647         }
648         
649         ret = ldb_add(PyLdb_AsLdbContext(self), msg);
650         PyErr_LDB_ERROR_IS_ERR_RAISE(ret, PyLdb_AsLdbContext(self));
651
652         Py_RETURN_NONE;
653 }
654
655
656
657 static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args)
658 {
659         PyObject *py_dn;
660         struct ldb_dn *dn;
661         int ret;
662         struct ldb_context *ldb;
663         if (!PyArg_ParseTuple(args, "O", &py_dn))
664                 return NULL;
665
666         ldb = PyLdb_AsLdbContext(self);
667
668         if (!PyObject_AsDn(NULL, py_dn, ldb, &dn))
669                 return NULL;
670
671         ret = ldb_delete(ldb, dn);
672         PyErr_LDB_ERROR_IS_ERR_RAISE(ret, ldb);
673
674         Py_RETURN_NONE;
675 }
676
677 static PyObject *py_ldb_rename(PyLdbObject *self, PyObject *args)
678 {
679         PyObject *py_dn1, *py_dn2;
680         struct ldb_dn *dn1, *dn2;
681         int ret;
682         struct ldb_context *ldb;
683         if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
684                 return NULL;
685
686         ldb = PyLdb_AsLdbContext(self);
687         if (!PyObject_AsDn(NULL, py_dn1, ldb, &dn1))
688                 return NULL;
689
690         if (!PyObject_AsDn(NULL, py_dn2, ldb, &dn2))
691                 return NULL;
692
693         ret = ldb_rename(ldb, dn1, dn2);
694         PyErr_LDB_ERROR_IS_ERR_RAISE(ret, ldb);
695
696         Py_RETURN_NONE;
697 }
698
699 static PyObject *py_ldb_schema_attribute_remove(PyLdbObject *self, PyObject *args)
700 {
701         char *name;
702         if (!PyArg_ParseTuple(args, "s", &name))
703                 return NULL;
704
705         ldb_schema_attribute_remove(PyLdb_AsLdbContext(self), name);
706
707         Py_RETURN_NONE;
708 }
709
710 static PyObject *py_ldb_schema_attribute_add(PyLdbObject *self, PyObject *args)
711 {
712         char *attribute, *syntax;
713         unsigned int flags;
714         int ret;
715         if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
716                 return NULL;
717
718         ret = ldb_schema_attribute_add(PyLdb_AsLdbContext(self), attribute, flags, syntax);
719
720         PyErr_LDB_ERROR_IS_ERR_RAISE(ret, PyLdb_AsLdbContext(self));
721
722         Py_RETURN_NONE;
723 }
724
725 static PyObject *ldb_ldif_to_pyobject(struct ldb_ldif *ldif)
726 {
727         if (ldif == NULL) {
728                 Py_RETURN_NONE;
729         } else {
730         /* We don't want this attached to the 'ldb' any more */
731                 talloc_steal(NULL, ldif);
732                 return Py_BuildValue(discard_const_p(char, "(iO)"),
733                                      ldif->changetype,
734                                      PyLdbMessage_FromMessage(ldif->msg));
735         }
736 }
737
738
739 static PyObject *py_ldb_parse_ldif(PyLdbObject *self, PyObject *args)
740 {
741         PyObject *list;
742         struct ldb_ldif *ldif;
743         const char *s;
744
745         if (!PyArg_ParseTuple(args, "s", &s))
746                 return NULL;
747
748         list = PyList_New(0);
749         while ((ldif = ldb_ldif_read_string(self->ldb_ctx, &s)) != NULL) {
750                 PyList_Append(list, ldb_ldif_to_pyobject(ldif));
751         }
752         return PyObject_GetIter(list);
753 }
754
755 static PyObject *py_ldb_schema_format_value(PyLdbObject *self, PyObject *args)
756 {
757         const struct ldb_schema_attribute *a;
758         struct ldb_val old_val;
759         struct ldb_val new_val;
760         TALLOC_CTX *mem_ctx;
761         PyObject *ret;
762         char *element_name;
763         PyObject *val;
764
765         if (!PyArg_ParseTuple(args, "sO", &element_name, &val))
766                 return NULL;
767         
768         mem_ctx = talloc_new(NULL);
769         
770         old_val.data = (uint8_t *)PyString_AsString(val);
771         old_val.length = PyString_Size(val);
772                 
773         a = ldb_schema_attribute_by_name(PyLdb_AsLdbContext(self), element_name);
774
775         if (a == NULL) {
776                 Py_RETURN_NONE;
777         }
778         
779         if (a->syntax->ldif_write_fn(PyLdb_AsLdbContext(self), mem_ctx, &old_val, &new_val) != 0) {
780                 talloc_free(mem_ctx);
781                 Py_RETURN_NONE;
782         }
783
784         ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
785
786         talloc_free(mem_ctx);
787
788         return ret;
789 }
790
791 static PyObject *py_ldb_search(PyLdbObject *self, PyObject *args, PyObject *kwargs)
792 {
793         PyObject *py_base = Py_None;
794         enum ldb_scope scope = LDB_SCOPE_DEFAULT;
795         char *expr = NULL;
796         PyObject *py_attrs = Py_None;
797         PyObject *py_controls = Py_None;
798         const char * const kwnames[] = { "base", "scope", "expression", "attrs", "controls", NULL };
799         int ret;
800         struct ldb_result *res;
801         struct ldb_request *req;
802         const char **attrs;
803         struct ldb_context *ldb_ctx;
804         struct ldb_control **parsed_controls;
805         struct ldb_dn *base;
806
807         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OizOO",
808                                          discard_const_p(char *, kwnames),
809                                          &py_base, &scope, &expr, &py_attrs, &py_controls))
810                 return NULL;
811
812         ldb_ctx = PyLdb_AsLdbContext(self);
813
814         if (py_attrs == Py_None) {
815                 attrs = NULL;
816         } else {
817                 attrs = PyList_AsStringList(ldb_ctx, py_attrs, "attrs");
818                 if (attrs == NULL)
819                         return NULL;
820         }
821
822         if (py_base == Py_None) {
823                 base = ldb_get_default_basedn(ldb_ctx);
824         } else {
825                 if (!PyObject_AsDn(ldb_ctx, py_base, ldb_ctx, &base))
826                         return NULL;
827         }
828
829         if (py_controls == Py_None) {
830                 parsed_controls = NULL;
831         } else {
832                 const char **controls = PyList_AsStringList(ldb_ctx, py_controls, "controls");
833                 parsed_controls = ldb_parse_control_strings(ldb_ctx, ldb_ctx, controls);
834                 talloc_free(controls);
835         }
836
837         res = talloc_zero(ldb_ctx, struct ldb_result);
838         if (res == NULL) {
839                 PyErr_NoMemory();
840                 return NULL;
841         }
842
843         ret = ldb_build_search_req(&req, ldb_ctx, ldb_ctx,
844                                    base,
845                                    scope,
846                                    expr,
847                                    attrs,
848                                    parsed_controls,
849                                    res,
850                                    ldb_search_default_callback,
851                                    NULL);
852
853         if (ret != LDB_SUCCESS) {
854                 talloc_free(res);
855                 PyErr_LDB_ERROR_IS_ERR_RAISE(ret, ldb_ctx);
856                 return NULL;
857         }
858
859         ret = ldb_request(ldb_ctx, req);
860                 
861         if (ret == LDB_SUCCESS) {
862                 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
863         }
864
865         talloc_free(req);
866
867         if (ret != LDB_SUCCESS) {
868                 talloc_free(res);
869                 PyErr_LDB_ERROR_IS_ERR_RAISE(ret, ldb_ctx);
870                 return NULL;
871         }
872
873         return PyLdbResult_FromResult(res);
874 }
875
876 static PyObject *py_ldb_get_opaque(PyLdbObject *self, PyObject *args)
877 {
878         char *name;
879         void *data;
880
881         if (!PyArg_ParseTuple(args, "s", &name))
882                 return NULL;
883
884         data = ldb_get_opaque(PyLdb_AsLdbContext(self), name);
885
886         if (data == NULL)
887                 Py_RETURN_NONE;
888
889         /* FIXME: More interpretation */
890
891         return Py_True;
892 }
893
894 static PyObject *py_ldb_set_opaque(PyLdbObject *self, PyObject *args)
895 {
896         char *name;
897         PyObject *data;
898
899         if (!PyArg_ParseTuple(args, "sO", &name, &data))
900                 return NULL;
901
902         /* FIXME: More interpretation */
903
904         ldb_set_opaque(PyLdb_AsLdbContext(self), name, data);
905
906         Py_RETURN_NONE;
907 }
908
909 static PyObject *py_ldb_modules(PyLdbObject *self)
910 {
911         struct ldb_context *ldb = PyLdb_AsLdbContext(self);
912         PyObject *ret = PyList_New(0);
913         struct ldb_module *mod;
914
915         for (mod = ldb->modules; mod; mod = mod->next) {
916                 PyList_Append(ret, PyLdbModule_FromModule(mod));
917         }
918
919         return ret;
920 }
921
922 static PyMethodDef py_ldb_methods[] = {
923         { "set_debug", (PyCFunction)py_ldb_set_debug, METH_VARARGS, 
924                 "S.set_debug(callback) -> None\n"
925                 "Set callback for LDB debug messages.\n"
926                 "The callback should accept a debug level and debug text." },
927         { "set_create_perms", (PyCFunction)py_ldb_set_create_perms, METH_VARARGS, 
928                 "S.set_create_perms(mode) -> None\n"
929                 "Set mode to use when creating new LDB files." },
930         { "set_modules_dir", (PyCFunction)py_ldb_set_modules_dir, METH_VARARGS,
931                 "S.set_modules_dir(path) -> None\n"
932                 "Set path LDB should search for modules" },
933         { "transaction_start", (PyCFunction)py_ldb_transaction_start, METH_NOARGS, 
934                 "S.transaction_start() -> None\n"
935                 "Start a new transaction." },
936         { "transaction_commit", (PyCFunction)py_ldb_transaction_commit, METH_NOARGS, 
937                 "S.transaction_commit() -> None\n"
938                 "commit a new transaction." },
939         { "transaction_cancel", (PyCFunction)py_ldb_transaction_cancel, METH_NOARGS, 
940                 "S.transaction_cancel() -> None\n"
941                 "cancel a new transaction." },
942         { "setup_wellknown_attributes", (PyCFunction)py_ldb_setup_wellknown_attributes, METH_NOARGS, 
943                 NULL },
944         { "get_root_basedn", (PyCFunction)py_ldb_get_root_basedn, METH_NOARGS,
945                 NULL },
946         { "get_schema_basedn", (PyCFunction)py_ldb_get_schema_basedn, METH_NOARGS,
947                 NULL },
948         { "get_default_basedn", (PyCFunction)py_ldb_get_default_basedn, METH_NOARGS,
949                 NULL },
950         { "get_config_basedn", (PyCFunction)py_ldb_get_config_basedn, METH_NOARGS,
951                 NULL },
952         { "connect", (PyCFunction)py_ldb_connect, METH_VARARGS|METH_KEYWORDS, 
953                 "S.connect(url, flags=0, options=None) -> None\n"
954                 "Connect to a LDB URL." },
955         { "modify", (PyCFunction)py_ldb_modify, METH_VARARGS, 
956                 "S.modify(message) -> None\n"
957                 "Modify an entry." },
958         { "add", (PyCFunction)py_ldb_add, METH_VARARGS, 
959                 "S.add(message) -> None\n"
960                 "Add an entry." },
961         { "delete", (PyCFunction)py_ldb_delete, METH_VARARGS,
962                 "S.delete(dn) -> None\n"
963                 "Remove an entry." },
964         { "rename", (PyCFunction)py_ldb_rename, METH_VARARGS,
965                 "S.rename(old_dn, new_dn) -> None\n"
966                 "Rename an entry." },
967         { "search", (PyCFunction)py_ldb_search, METH_VARARGS|METH_KEYWORDS,
968                 "S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> msgs\n"
969                 "Search in a database.\n"
970                 "\n"
971                 ":param base: Optional base DN to search\n"
972                 ":param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE)\n"
973                 ":param expression: Optional search expression\n"
974                 ":param attrs: Attributes to return (defaults to all)\n"
975                 ":param controls: Optional list of controls\n"
976                 ":return: Iterator over Message objects\n"
977         },
978         { "schema_attribute_remove", (PyCFunction)py_ldb_schema_attribute_remove, METH_VARARGS,
979                 NULL },
980         { "schema_attribute_add", (PyCFunction)py_ldb_schema_attribute_add, METH_VARARGS,
981                 NULL },
982         { "schema_format_value", (PyCFunction)py_ldb_schema_format_value, METH_VARARGS,
983                 NULL },
984         { "parse_ldif", (PyCFunction)py_ldb_parse_ldif, METH_VARARGS,
985                 "S.parse_ldif(ldif) -> iter(messages)\n"
986                 "Parse a string formatted using LDIF." },
987         { "get_opaque", (PyCFunction)py_ldb_get_opaque, METH_VARARGS,
988                 "S.get_opaque(name) -> value\n"
989                 "Get an opaque value set on this LDB connection. \n"
990                 ":note: The returned value may not be useful in Python."
991         },
992         { "set_opaque", (PyCFunction)py_ldb_set_opaque, METH_VARARGS,
993                 "S.set_opaque(name, value) -> None\n"
994                 "Set an opaque value on this LDB connection. \n"
995                 ":note: Passing incorrect values may cause crashes." },
996         { "modules", (PyCFunction)py_ldb_modules, METH_NOARGS,
997                 "S.modules() -> list\n"
998                 "Return the list of modules on this LDB connection " },
999         { NULL },
1000 };
1001
1002 PyObject *PyLdbModule_FromModule(struct ldb_module *mod)
1003 {
1004         PyLdbModuleObject *ret;
1005
1006         ret = (PyLdbModuleObject *)PyLdbModule.tp_alloc(&PyLdbModule, 0);
1007         if (ret == NULL) {
1008                 PyErr_NoMemory();
1009                 return NULL;
1010         }
1011         ret->mem_ctx = talloc_new(NULL);
1012         ret->mod = talloc_reference(ret->mem_ctx, mod);
1013         return (PyObject *)ret;
1014 }
1015
1016 static PyObject *py_ldb_get_firstmodule(PyLdbObject *self, void *closure)
1017 {
1018         return PyLdbModule_FromModule(PyLdb_AsLdbContext(self)->modules);
1019 }
1020
1021 static PyGetSetDef py_ldb_getset[] = {
1022         { discard_const_p(char, "firstmodule"), (getter)py_ldb_get_firstmodule, NULL, NULL },
1023         { NULL }
1024 };
1025
1026 static int py_ldb_contains(PyLdbObject *self, PyObject *obj)
1027 {
1028         struct ldb_context *ldb_ctx = PyLdb_AsLdbContext(self);
1029         struct ldb_dn *dn;
1030         struct ldb_result *result;
1031         int ret;
1032         int count;
1033
1034         if (!PyObject_AsDn(ldb_ctx, obj, ldb_ctx, &dn))
1035                 return -1;
1036
1037         ret = ldb_search(ldb_ctx, ldb_ctx, &result, dn, LDB_SCOPE_BASE, NULL, NULL);
1038         if (ret != LDB_SUCCESS) {
1039                 PyErr_SetLdbError(ret, ldb_ctx);
1040                 return -1;
1041         }
1042
1043         count = result->count;
1044
1045         talloc_free(result);
1046
1047         return count;
1048 }
1049
1050 static PySequenceMethods py_ldb_seq = {
1051         .sq_contains = (objobjproc)py_ldb_contains,
1052 };
1053
1054 PyObject *PyLdb_FromLdbContext(struct ldb_context *ldb_ctx)
1055 {
1056         PyLdbObject *ret;
1057
1058         ret = (PyLdbObject *)PyLdb.tp_alloc(&PyLdb, 0);
1059         if (ret == NULL) {
1060                 PyErr_NoMemory();
1061                 return NULL;
1062         }
1063         ret->mem_ctx = talloc_new(NULL);
1064         ret->ldb_ctx = talloc_reference(ret->mem_ctx, ldb_ctx);
1065         return (PyObject *)ret;
1066 }
1067
1068 static void py_ldb_dealloc(PyLdbObject *self)
1069 {
1070         talloc_free(self->mem_ctx);
1071         self->ob_type->tp_free(self);
1072 }
1073
1074 PyTypeObject PyLdb = {
1075         .tp_name = "Ldb",
1076         .tp_methods = py_ldb_methods,
1077         .tp_repr = (reprfunc)py_ldb_repr,
1078         .tp_new = py_ldb_new,
1079         .tp_init = (initproc)py_ldb_init,
1080         .tp_dealloc = (destructor)py_ldb_dealloc,
1081         .tp_getset = py_ldb_getset,
1082         .tp_getattro = PyObject_GenericGetAttr,
1083         .tp_basicsize = sizeof(PyLdbObject),
1084         .tp_doc = "Connection to a LDB database.",
1085         .tp_as_sequence = &py_ldb_seq,
1086         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1087 };
1088
1089 static PyObject *py_ldb_module_repr(PyLdbModuleObject *self)
1090 {
1091         return PyString_FromFormat("<ldb module '%s'>", PyLdbModule_AsModule(self)->ops->name);
1092 }
1093
1094 static PyObject *py_ldb_module_str(PyLdbModuleObject *self)
1095 {
1096         return PyString_FromString(PyLdbModule_AsModule(self)->ops->name);
1097 }
1098
1099 static PyObject *py_ldb_module_start_transaction(PyLdbModuleObject *self)
1100 {
1101         PyLdbModule_AsModule(self)->ops->start_transaction(PyLdbModule_AsModule(self));
1102         Py_RETURN_NONE;
1103 }
1104
1105 static PyObject *py_ldb_module_end_transaction(PyLdbModuleObject *self)
1106 {
1107         PyLdbModule_AsModule(self)->ops->end_transaction(PyLdbModule_AsModule(self));
1108         Py_RETURN_NONE;
1109 }
1110
1111 static PyObject *py_ldb_module_del_transaction(PyLdbModuleObject *self)
1112 {
1113         PyLdbModule_AsModule(self)->ops->del_transaction(PyLdbModule_AsModule(self));
1114         Py_RETURN_NONE;
1115 }
1116
1117 static PyObject *py_ldb_module_search(PyLdbModuleObject *self, PyObject *args, PyObject *kwargs)
1118 {
1119         PyObject *py_base, *py_tree, *py_attrs;
1120         int ret, scope;
1121         struct ldb_request *req;
1122         const char * const kwnames[] = { "base", "scope", "tree", "attrs", NULL };
1123         struct ldb_module *mod;
1124
1125         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OiOO",
1126                                          discard_const_p(char *, kwnames),
1127                                          &py_base, &scope, &py_tree, &py_attrs))
1128                 return NULL;
1129
1130         mod = self->mod;
1131
1132         ret = ldb_build_search_req(&req, mod->ldb, NULL, PyLdbDn_AsDn(py_base), 
1133                              scope, NULL /* expr */, py_attrs == Py_None?NULL:PyList_AsStringList(req, py_attrs, "attrs"),
1134                              NULL /* controls */, NULL, NULL, NULL);
1135         PyErr_LDB_ERROR_IS_ERR_RAISE(ret, mod->ldb);
1136
1137         ret = mod->ops->search(mod, req);
1138         talloc_free(req);
1139
1140         PyErr_LDB_ERROR_IS_ERR_RAISE(ret, mod->ldb);
1141
1142         return PyLdbResult_FromResult(req->op.search.res);
1143 }
1144
1145
1146 static PyObject *py_ldb_module_add(PyLdbModuleObject *self, PyObject *args)
1147 {
1148         struct ldb_request *req;
1149         PyObject *py_message;
1150         int ret;
1151         struct ldb_module *mod;
1152
1153         if (!PyArg_ParseTuple(args, "O", &py_message))
1154                 return NULL;
1155
1156         req = talloc_zero(NULL, struct ldb_request);
1157         req->operation = LDB_ADD;
1158         req->op.add.message = PyLdbMessage_AsMessage(py_message);
1159
1160         mod = PyLdbModule_AsModule(self);
1161         ret = mod->ops->add(mod, req);
1162
1163         PyErr_LDB_ERROR_IS_ERR_RAISE(ret, mod->ldb);
1164
1165         Py_RETURN_NONE;
1166 }
1167
1168 static PyObject *py_ldb_module_modify(PyLdbModuleObject *self, PyObject *args) 
1169 {
1170         int ret;
1171         struct ldb_request *req;
1172         PyObject *py_message;
1173         struct ldb_module *mod;
1174
1175         if (!PyArg_ParseTuple(args, "O", &py_message))
1176                 return NULL;
1177         
1178         req = talloc_zero(NULL, struct ldb_request);
1179         req->operation = LDB_MODIFY;
1180         req->op.mod.message = PyLdbMessage_AsMessage(py_message);
1181         
1182         mod = PyLdbModule_AsModule(self);
1183         ret = mod->ops->modify(mod, req);
1184
1185         PyErr_LDB_ERROR_IS_ERR_RAISE(ret, mod->ldb);
1186
1187         Py_RETURN_NONE;
1188 }
1189
1190 static PyObject *py_ldb_module_delete(PyLdbModuleObject *self, PyObject *args) 
1191 {
1192         int ret;
1193         struct ldb_request *req;
1194         PyObject *py_dn;
1195
1196         if (!PyArg_ParseTuple(args, "O", &py_dn))
1197                 return NULL;
1198         
1199         req = talloc_zero(NULL, struct ldb_request);
1200         req->operation = LDB_DELETE;
1201         req->op.del.dn = PyLdbDn_AsDn(py_dn);
1202         
1203         ret = PyLdbModule_AsModule(self)->ops->del(PyLdbModule_AsModule(self), req);
1204
1205         PyErr_LDB_ERROR_IS_ERR_RAISE(ret, NULL);
1206
1207         Py_RETURN_NONE;
1208 }
1209
1210 static PyObject *py_ldb_module_rename(PyLdbModuleObject *self, PyObject *args)
1211 {
1212         int ret;
1213         struct ldb_request *req;
1214         PyObject *py_dn1, *py_dn2;
1215
1216         if (!PyArg_ParseTuple(args, "OO", &py_dn1, &py_dn2))
1217                 return NULL;
1218         
1219         req = talloc_zero(NULL, struct ldb_request);
1220
1221         req->operation = LDB_RENAME;
1222         req->op.rename.olddn = PyLdbDn_AsDn(py_dn1);
1223         req->op.rename.newdn = PyLdbDn_AsDn(py_dn2);
1224         
1225         ret = PyLdbModule_AsModule(self)->ops->rename(PyLdbModule_AsModule(self), req);
1226
1227         PyErr_LDB_ERROR_IS_ERR_RAISE(ret, NULL);
1228
1229         Py_RETURN_NONE;
1230 }
1231
1232 static PyMethodDef py_ldb_module_methods[] = {
1233         { "search", (PyCFunction)py_ldb_module_search, METH_VARARGS|METH_KEYWORDS, NULL },
1234         { "add", (PyCFunction)py_ldb_module_add, METH_VARARGS, NULL },
1235         { "modify", (PyCFunction)py_ldb_module_modify, METH_VARARGS, NULL },
1236         { "rename", (PyCFunction)py_ldb_module_rename, METH_VARARGS, NULL },
1237         { "delete", (PyCFunction)py_ldb_module_delete, METH_VARARGS, NULL },
1238         { "start_transaction", (PyCFunction)py_ldb_module_start_transaction, METH_NOARGS, NULL },
1239         { "end_transaction", (PyCFunction)py_ldb_module_end_transaction, METH_NOARGS, NULL },
1240         { "del_transaction", (PyCFunction)py_ldb_module_del_transaction, METH_NOARGS, NULL },
1241         { NULL },
1242 };
1243
1244 static void py_ldb_module_dealloc(PyLdbModuleObject *self)
1245 {
1246         talloc_free(self->mem_ctx);
1247         self->ob_type->tp_free(self);
1248 }
1249
1250 PyTypeObject PyLdbModule = {
1251         .tp_name = "LdbModule",
1252         .tp_methods = py_ldb_module_methods,
1253         .tp_repr = (reprfunc)py_ldb_module_repr,
1254         .tp_str = (reprfunc)py_ldb_module_str,
1255         .tp_basicsize = sizeof(PyLdbModuleObject),
1256         .tp_dealloc = (destructor)py_ldb_module_dealloc,
1257         .tp_flags = Py_TPFLAGS_DEFAULT,
1258 };
1259
1260 struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
1261                                                                                            PyObject *set_obj, int flags,
1262                                                                                            const char *attr_name)
1263 {
1264         struct ldb_message_element *me;
1265
1266         if (PyLdbMessageElement_Check(set_obj))
1267                 return PyLdbMessageElement_AsMessageElement(set_obj);
1268
1269         me = talloc(mem_ctx, struct ldb_message_element);
1270
1271         me->name = attr_name;
1272         me->flags = flags;
1273         if (PyString_Check(set_obj)) {
1274                 me->num_values = 1;
1275                 me->values = talloc_array(me, struct ldb_val, me->num_values);
1276                 me->values[0].length = PyString_Size(set_obj);
1277                 me->values[0].data = (uint8_t *)talloc_strndup(me->values,
1278                                         PyString_AsString(set_obj),
1279                                         me->values[0].length);
1280         } else if (PySequence_Check(set_obj)) {
1281                 int i;
1282                 me->num_values = PySequence_Size(set_obj);
1283                 me->values = talloc_array(me, struct ldb_val, me->num_values);
1284                 for (i = 0; i < me->num_values; i++) {
1285                         PyObject *obj = PySequence_GetItem(set_obj, i);
1286
1287                         me->values[i].length = PyString_Size(obj);
1288                         me->values[i].data = (uint8_t *)PyString_AsString(obj);
1289                 }
1290         } else {
1291                 talloc_free(me);
1292                 me = NULL;
1293         }
1294
1295         return me;
1296 }
1297
1298
1299 static PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx, 
1300                                                                  struct ldb_message_element *me)
1301 {
1302         int i;
1303         PyObject *result;
1304
1305         /* Python << 2.5 doesn't have PySet_New and PySet_Add. */
1306         result = PyList_New(me->num_values);
1307
1308         for (i = 0; i < me->num_values; i++) {
1309                 PyList_SetItem(result, i,
1310                         PyObject_FromLdbValue(ldb_ctx, me, &me->values[i]));
1311         }
1312
1313         return result;
1314 }
1315
1316 static PyObject *py_ldb_msg_element_get(PyLdbMessageElementObject *self, PyObject *args)
1317 {
1318         int i;
1319         if (!PyArg_ParseTuple(args, "i", &i))
1320                 return NULL;
1321         if (i < 0 || i >= PyLdbMessageElement_AsMessageElement(self)->num_values)
1322                 Py_RETURN_NONE;
1323
1324         return PyObject_FromLdbValue(NULL, PyLdbMessageElement_AsMessageElement(self), 
1325                                                                  &(PyLdbMessageElement_AsMessageElement(self)->values[i]));
1326 }
1327
1328 static PyMethodDef py_ldb_msg_element_methods[] = {
1329         { "get", (PyCFunction)py_ldb_msg_element_get, METH_VARARGS, NULL },
1330         { NULL },
1331 };
1332
1333 static Py_ssize_t py_ldb_msg_element_len(PyLdbMessageElementObject *self)
1334 {
1335         return PyLdbMessageElement_AsMessageElement(self)->num_values;
1336 }
1337
1338 static PyObject *py_ldb_msg_element_find(PyLdbMessageElementObject *self, Py_ssize_t idx)
1339 {
1340         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1341         if (idx < 0 || idx >= el->num_values) {
1342                 PyErr_SetString(PyExc_IndexError, "Out of range");
1343                 return NULL;
1344         }
1345         return PyString_FromStringAndSize((char *)el->values[idx].data, el->values[idx].length);
1346 }
1347
1348 static PySequenceMethods py_ldb_msg_element_seq = {
1349         .sq_length = (lenfunc)py_ldb_msg_element_len,
1350         .sq_item = (ssizeargfunc)py_ldb_msg_element_find,
1351 };
1352
1353 static int py_ldb_msg_element_cmp(PyLdbMessageElementObject *self, PyLdbMessageElementObject *other)
1354 {
1355         return ldb_msg_element_compare(PyLdbMessageElement_AsMessageElement(self), 
1356                                                                    PyLdbMessageElement_AsMessageElement(other));
1357 }
1358
1359 static PyObject *py_ldb_msg_element_iter(PyLdbMessageElementObject *self)
1360 {
1361         return PyObject_GetIter(ldb_msg_element_to_set(NULL, PyLdbMessageElement_AsMessageElement(self)));
1362 }
1363
1364 PyObject *PyLdbMessageElement_FromMessageElement(struct ldb_message_element *el, TALLOC_CTX *mem_ctx)
1365 {
1366         PyLdbMessageElementObject *ret;
1367         ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
1368         if (ret == NULL) {
1369                 PyErr_NoMemory();
1370                 return NULL;
1371         }
1372         ret->mem_ctx = talloc_new(NULL);
1373         if (talloc_reference(ret->mem_ctx, mem_ctx) == NULL) {
1374                 PyErr_NoMemory();
1375                 return NULL;
1376         }
1377         ret->el = el;
1378         return (PyObject *)ret;
1379 }
1380
1381 static PyObject *py_ldb_msg_element_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1382 {
1383         PyObject *py_elements = NULL;
1384         struct ldb_message_element *el;
1385         int flags = 0;
1386         char *name = NULL;
1387         const char * const kwnames[] = { "elements", "flags", "name", NULL };
1388         PyLdbMessageElementObject *ret;
1389
1390         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Ois",
1391                                          discard_const_p(char *, kwnames),
1392                                          &py_elements, &flags, &name))
1393                 return NULL;
1394
1395         el = talloc_zero(NULL, struct ldb_message_element);
1396
1397         if (py_elements != NULL) {
1398                 int i;
1399                 if (PyString_Check(py_elements)) {
1400                         el->num_values = 1;
1401                         el->values = talloc_array(el, struct ldb_val, 1);
1402                         el->values[0].data = (uint8_t *)PyString_AsString(py_elements);
1403                         el->values[0].length = PyString_Size(py_elements);
1404                 } else if (PySequence_Check(py_elements)) {
1405                         el->num_values = PySequence_Size(py_elements);
1406                         el->values = talloc_array(el, struct ldb_val, el->num_values);
1407                         for (i = 0; i < el->num_values; i++) {
1408                                 PyObject *item = PySequence_GetItem(py_elements, i);
1409                                 el->values[i].data = (uint8_t *)PyString_AsString(item);
1410                                 el->values[i].length = PyString_Size(item);
1411                         }
1412                 } else {
1413                         PyErr_SetString(PyExc_TypeError, 
1414                                         "Expected string or list");
1415                         talloc_free(el);
1416                         return NULL;
1417                 }
1418         }
1419
1420         el->flags = flags;
1421         el->name = talloc_strdup(el, name);
1422
1423         ret = (PyLdbMessageElementObject *)PyLdbMessageElement.tp_alloc(&PyLdbMessageElement, 0);
1424         if (ret == NULL) {
1425                 PyErr_NoMemory();
1426                 talloc_free(el);
1427                 return NULL;
1428         }
1429
1430         ret->mem_ctx = talloc_new(NULL);
1431         ret->el = talloc_reference(ret->mem_ctx, el);
1432         return (PyObject *)ret;
1433 }
1434
1435 static PyObject *py_ldb_msg_element_repr(PyLdbMessageElementObject *self)
1436 {
1437         char *element_str = NULL;
1438         int i;
1439         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1440         PyObject *ret;
1441
1442         for (i = 0; i < el->num_values; i++) {
1443                 PyObject *o = py_ldb_msg_element_find(self, i);
1444                 if (element_str == NULL)
1445                         element_str = talloc_strdup(NULL, PyObject_REPR(o));
1446                 else
1447                         element_str = talloc_asprintf_append(element_str, ",%s", PyObject_REPR(o));
1448         }
1449
1450         ret = PyString_FromFormat("MessageElement([%s])", element_str);
1451
1452         talloc_free(element_str);
1453
1454         return ret;
1455 }
1456
1457 static PyObject *py_ldb_msg_element_str(PyLdbMessageElementObject *self)
1458 {
1459         struct ldb_message_element *el = PyLdbMessageElement_AsMessageElement(self);
1460
1461         if (el->num_values == 1)
1462                 return PyString_FromStringAndSize((char *)el->values[0].data, el->values[0].length);
1463         else 
1464                 Py_RETURN_NONE;
1465 }
1466
1467 static void py_ldb_msg_element_dealloc(PyLdbMessageElementObject *self)
1468 {
1469         talloc_free(self->mem_ctx);
1470         self->ob_type->tp_free(self);
1471 }
1472
1473 PyTypeObject PyLdbMessageElement = {
1474         .tp_name = "MessageElement",
1475         .tp_basicsize = sizeof(PyLdbMessageElementObject),
1476         .tp_dealloc = (destructor)py_ldb_msg_element_dealloc,
1477         .tp_repr = (reprfunc)py_ldb_msg_element_repr,
1478         .tp_str = (reprfunc)py_ldb_msg_element_str,
1479         .tp_methods = py_ldb_msg_element_methods,
1480         .tp_compare = (cmpfunc)py_ldb_msg_element_cmp,
1481         .tp_iter = (getiterfunc)py_ldb_msg_element_iter,
1482         .tp_as_sequence = &py_ldb_msg_element_seq,
1483         .tp_new = py_ldb_msg_element_new,
1484         .tp_flags = Py_TPFLAGS_DEFAULT,
1485 };
1486
1487 static PyObject *py_ldb_msg_remove_attr(PyLdbMessageObject *self, PyObject *args)
1488 {
1489         char *name;
1490         if (!PyArg_ParseTuple(args, "s", &name))
1491                 return NULL;
1492
1493         ldb_msg_remove_attr(self->msg, name);
1494
1495         Py_RETURN_NONE;
1496 }
1497
1498 static PyObject *py_ldb_msg_keys(PyLdbMessageObject *self)
1499 {
1500         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1501         int i, j = 0;
1502         PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
1503         if (msg->dn != NULL) {
1504                 PyList_SetItem(obj, j, PyString_FromString("dn"));
1505                 j++;
1506         }
1507         for (i = 0; i < msg->num_elements; i++) {
1508                 PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
1509                 j++;
1510         }
1511         return obj;
1512 }
1513
1514 static PyObject *py_ldb_msg_getitem_helper(PyLdbMessageObject *self, PyObject *py_name)
1515 {
1516         struct ldb_message_element *el;
1517         char *name = PyString_AsString(py_name);
1518         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1519         if (!strcmp(name, "dn"))
1520                 return PyLdbDn_FromDn(msg->dn);
1521         el = ldb_msg_find_element(msg, name);
1522         if (el == NULL) {
1523                 return NULL;
1524         }
1525         return (PyObject *)PyLdbMessageElement_FromMessageElement(el, msg);
1526 }
1527
1528 static PyObject *py_ldb_msg_getitem(PyLdbMessageObject *self, PyObject *py_name)
1529 {
1530         PyObject *ret = py_ldb_msg_getitem_helper(self, py_name);
1531         if (ret == NULL) {
1532                 PyErr_SetString(PyExc_KeyError, "No such element");
1533                 return NULL;
1534         }
1535         return ret;
1536 }
1537
1538 static PyObject *py_ldb_msg_get(PyLdbMessageObject *self, PyObject *args)
1539 {
1540         PyObject *name, *ret;
1541         if (!PyArg_ParseTuple(args, "O", &name))
1542                 return NULL;
1543
1544         ret = py_ldb_msg_getitem_helper(self, name);
1545         if (ret == NULL)
1546                 Py_RETURN_NONE;
1547         return ret;
1548 }
1549
1550 static PyObject *py_ldb_msg_items(PyLdbMessageObject *self)
1551 {
1552         struct ldb_message *msg = PyLdbMessage_AsMessage(self);
1553         int i, j;
1554         PyObject *l = PyList_New(msg->num_elements + (msg->dn == NULL?0:1));
1555         j = 0;
1556         if (msg->dn != NULL) {
1557                 PyList_SetItem(l, 0, Py_BuildValue("(sO)", "dn", PyLdbDn_FromDn(msg->dn)));
1558                 j++;
1559         }
1560         for (i = 0; i < msg->num_elements; i++, j++) {
1561                 PyList_SetItem(l, j, Py_BuildValue("(sO)", msg->elements[i].name, PyLdbMessageElement_FromMessageElement(&msg->elements[i], self->msg)));
1562         }
1563         return l;
1564 }
1565
1566 static PyMethodDef py_ldb_msg_methods[] = { 
1567         { "keys", (PyCFunction)py_ldb_msg_keys, METH_NOARGS, NULL },
1568         { "remove", (PyCFunction)py_ldb_msg_remove_attr, METH_VARARGS, NULL },
1569         { "get", (PyCFunction)py_ldb_msg_get, METH_VARARGS, NULL },
1570         { "items", (PyCFunction)py_ldb_msg_items, METH_NOARGS, NULL },
1571         { NULL },
1572 };
1573
1574 static PyObject *py_ldb_msg_iter(PyLdbMessageObject *self)
1575 {
1576         PyObject *list, *iter;
1577
1578         list = py_ldb_msg_keys(self);
1579         iter = PyObject_GetIter(list);
1580         Py_DECREF(list);
1581         return iter;
1582 }
1583
1584 static int py_ldb_msg_setitem(PyLdbMessageObject *self, PyObject *name, PyObject *value)
1585 {
1586         char *attr_name = PyString_AsString(name);
1587         if (value == NULL) {
1588                 ldb_msg_remove_attr(self->msg, attr_name);
1589         } else {
1590                 struct ldb_message_element *el = PyObject_AsMessageElement(NULL,
1591                                                                                         value, 0, attr_name);
1592                 if (el == NULL)
1593                         return -1;
1594                 talloc_steal(self->msg, el);
1595                 ldb_msg_remove_attr(PyLdbMessage_AsMessage(self), attr_name);
1596                 ldb_msg_add(PyLdbMessage_AsMessage(self), el, el->flags);
1597         }
1598         return 0;
1599 }
1600
1601 static Py_ssize_t py_ldb_msg_length(PyLdbMessageObject *self)
1602 {
1603         return PyLdbMessage_AsMessage(self)->num_elements;
1604 }
1605
1606 static PyMappingMethods py_ldb_msg_mapping = {
1607         .mp_length = (lenfunc)py_ldb_msg_length,
1608         .mp_subscript = (binaryfunc)py_ldb_msg_getitem,
1609         .mp_ass_subscript = (objobjargproc)py_ldb_msg_setitem,
1610 };
1611
1612 static PyObject *py_ldb_msg_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1613 {
1614         const char * const kwnames[] = { "dn", NULL };
1615         struct ldb_message *ret;
1616         PyObject *pydn = NULL;
1617         PyLdbMessageObject *py_ret;
1618
1619         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O",
1620                                          discard_const_p(char *, kwnames),
1621                                          &pydn))
1622                 return NULL;
1623
1624         ret = ldb_msg_new(NULL);
1625         if (ret == NULL) {
1626                 PyErr_NoMemory();
1627                 return NULL;
1628         }
1629
1630         if (pydn != NULL)
1631                 if (!PyObject_AsDn(NULL, pydn, NULL, &ret->dn))
1632                         return NULL;
1633
1634         py_ret = (PyLdbMessageObject *)type->tp_alloc(type, 0);
1635         if (py_ret == NULL) {
1636                 PyErr_NoMemory();
1637                 return NULL;
1638         }
1639
1640         py_ret->mem_ctx = talloc_new(NULL);
1641         py_ret->msg = talloc_reference(py_ret->mem_ctx, ret);
1642         return (PyObject *)py_ret;
1643 }
1644
1645 PyObject *PyLdbMessage_FromMessage(struct ldb_message *msg)
1646 {
1647         PyLdbMessageObject *ret;
1648
1649         ret = (PyLdbMessageObject *)PyLdbMessage.tp_alloc(&PyLdbMessage, 0);
1650         if (ret == NULL) {
1651                 PyErr_NoMemory();
1652                 return NULL;
1653         }
1654         ret->mem_ctx = talloc_new(NULL);
1655         ret->msg = talloc_reference(ret->mem_ctx, msg);
1656         return (PyObject *)ret;
1657 }
1658
1659 static PyObject *py_ldb_msg_get_dn(PyLdbMessageObject *self, void *closure)
1660 {
1661         return PyLdbDn_FromDn(PyLdbMessage_AsMessage(self)->dn);
1662 }
1663
1664 static int py_ldb_msg_set_dn(PyLdbMessageObject *self, PyObject *value, void *closure)
1665 {
1666         PyLdbMessage_AsMessage(self)->dn = PyLdbDn_AsDn(value);
1667         return 0;
1668 }
1669
1670 static PyGetSetDef py_ldb_msg_getset[] = {
1671         { discard_const_p(char, "dn"), (getter)py_ldb_msg_get_dn, (setter)py_ldb_msg_set_dn, NULL },
1672         { NULL }
1673 };
1674
1675 static PyObject *py_ldb_msg_repr(PyLdbMessageObject *self)
1676 {
1677         PyObject *dict = PyDict_New(), *ret;
1678         if (PyDict_Update(dict, (PyObject *)self) != 0)
1679                 return NULL;
1680         ret = PyString_FromFormat("Message(%s)", PyObject_REPR(dict));
1681         Py_DECREF(dict);
1682         return ret;
1683 }
1684
1685 static void py_ldb_msg_dealloc(PyLdbMessageObject *self)
1686 {
1687         talloc_free(self->mem_ctx);
1688         self->ob_type->tp_free(self);
1689 }
1690
1691 PyTypeObject PyLdbMessage = {
1692         .tp_name = "Message",
1693         .tp_methods = py_ldb_msg_methods,
1694         .tp_getset = py_ldb_msg_getset,
1695         .tp_as_mapping = &py_ldb_msg_mapping,
1696         .tp_basicsize = sizeof(PyLdbMessageObject),
1697         .tp_dealloc = (destructor)py_ldb_msg_dealloc,
1698         .tp_new = py_ldb_msg_new,
1699         .tp_repr = (reprfunc)py_ldb_msg_repr,
1700         .tp_flags = Py_TPFLAGS_DEFAULT,
1701         .tp_iter = (getiterfunc)py_ldb_msg_iter,
1702 };
1703
1704 PyObject *PyLdbTree_FromTree(struct ldb_parse_tree *tree)
1705 {
1706         PyLdbTreeObject *ret;
1707
1708         ret = (PyLdbTreeObject *)PyLdbTree.tp_alloc(&PyLdbTree, 0);
1709         if (ret == NULL) {
1710                 PyErr_NoMemory();
1711                 return NULL;
1712         }
1713         
1714         ret->mem_ctx = talloc_new(NULL);
1715         ret->tree = talloc_reference(ret->mem_ctx, tree);
1716         return (PyObject *)ret;
1717 }
1718
1719 static void py_ldb_tree_dealloc(PyLdbTreeObject *self)
1720 {
1721         talloc_free(self->mem_ctx);
1722         self->ob_type->tp_free(self);
1723 }
1724
1725 PyTypeObject PyLdbTree = {
1726         .tp_name = "Tree",
1727         .tp_basicsize = sizeof(PyLdbTreeObject),
1728         .tp_dealloc = (destructor)py_ldb_tree_dealloc,
1729         .tp_flags = Py_TPFLAGS_DEFAULT,
1730 };
1731
1732 /* Ldb_module */
1733 static int py_module_search(struct ldb_module *mod, struct ldb_request *req)
1734 {
1735         PyObject *py_ldb = (PyObject *)mod->private_data;
1736         PyObject *py_result, *py_base, *py_attrs, *py_tree;
1737
1738         py_base = PyLdbDn_FromDn(req->op.search.base);
1739
1740         if (py_base == NULL)
1741                 return LDB_ERR_OPERATIONS_ERROR;
1742
1743         py_tree = PyLdbTree_FromTree(req->op.search.tree);
1744
1745         if (py_tree == NULL)
1746                 return LDB_ERR_OPERATIONS_ERROR;
1747
1748         if (req->op.search.attrs == NULL) {
1749                 py_attrs = Py_None;
1750         } else {
1751                 int i, len;
1752                 for (len = 0; req->op.search.attrs[len]; len++);
1753                 py_attrs = PyList_New(len);
1754                 for (i = 0; i < len; i++)
1755                         PyList_SetItem(py_attrs, i, PyString_FromString(req->op.search.attrs[i]));
1756         }
1757
1758         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "search"),
1759                                         discard_const_p(char, "OiOO"),
1760                                         py_base, req->op.search.scope, py_tree, py_attrs);
1761
1762         Py_DECREF(py_attrs);
1763         Py_DECREF(py_tree);
1764         Py_DECREF(py_base);
1765
1766         if (py_result == NULL) {
1767                 return LDB_ERR_PYTHON_EXCEPTION;
1768         }
1769
1770         req->op.search.res = PyLdbResult_AsResult(NULL, py_result);
1771         if (req->op.search.res == NULL) {
1772                 return LDB_ERR_PYTHON_EXCEPTION;
1773         }
1774
1775         Py_DECREF(py_result);
1776
1777         return LDB_SUCCESS;
1778 }
1779
1780 static int py_module_add(struct ldb_module *mod, struct ldb_request *req)
1781 {
1782         PyObject *py_ldb = (PyObject *)mod->private_data;
1783         PyObject *py_result, *py_msg;
1784
1785         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.add.message));
1786
1787         if (py_msg == NULL) {
1788                 return LDB_ERR_OPERATIONS_ERROR;
1789         }
1790
1791         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "add"),
1792                                         discard_const_p(char, "O"),
1793                                         py_msg);
1794
1795         Py_DECREF(py_msg);
1796
1797         if (py_result == NULL) {
1798                 return LDB_ERR_PYTHON_EXCEPTION;
1799         }
1800
1801         Py_DECREF(py_result);
1802
1803         return LDB_SUCCESS;
1804 }
1805
1806 static int py_module_modify(struct ldb_module *mod, struct ldb_request *req)
1807 {
1808         PyObject *py_ldb = (PyObject *)mod->private_data;
1809         PyObject *py_result, *py_msg;
1810
1811         py_msg = PyLdbMessage_FromMessage(discard_const_p(struct ldb_message, req->op.mod.message));
1812
1813         if (py_msg == NULL) {
1814                 return LDB_ERR_OPERATIONS_ERROR;
1815         }
1816
1817         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "modify"),
1818                                         discard_const_p(char, "O"),
1819                                         py_msg);
1820
1821         Py_DECREF(py_msg);
1822
1823         if (py_result == NULL) {
1824                 return LDB_ERR_PYTHON_EXCEPTION;
1825         }
1826
1827         Py_DECREF(py_result);
1828
1829         return LDB_SUCCESS;
1830 }
1831
1832 static int py_module_del(struct ldb_module *mod, struct ldb_request *req)
1833 {
1834         PyObject *py_ldb = (PyObject *)mod->private_data;
1835         PyObject *py_result, *py_dn;
1836
1837         py_dn = PyLdbDn_FromDn(req->op.del.dn);
1838
1839         if (py_dn == NULL)
1840                 return LDB_ERR_OPERATIONS_ERROR;
1841
1842         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "delete"),
1843                                         discard_const_p(char, "O"),
1844                                         py_dn);
1845
1846         if (py_result == NULL) {
1847                 return LDB_ERR_PYTHON_EXCEPTION;
1848         }
1849
1850         Py_DECREF(py_result);
1851
1852         return LDB_SUCCESS;
1853 }
1854
1855 static int py_module_rename(struct ldb_module *mod, struct ldb_request *req)
1856 {
1857         PyObject *py_ldb = (PyObject *)mod->private_data;
1858         PyObject *py_result, *py_olddn, *py_newdn;
1859
1860         py_olddn = PyLdbDn_FromDn(req->op.rename.olddn);
1861
1862         if (py_olddn == NULL)
1863                 return LDB_ERR_OPERATIONS_ERROR;
1864
1865         py_newdn = PyLdbDn_FromDn(req->op.rename.newdn);
1866
1867         if (py_newdn == NULL)
1868                 return LDB_ERR_OPERATIONS_ERROR;
1869
1870         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "rename"),
1871                                         discard_const_p(char, "OO"),
1872                                         py_olddn, py_newdn);
1873
1874         Py_DECREF(py_olddn);
1875         Py_DECREF(py_newdn);
1876
1877         if (py_result == NULL) {
1878                 return LDB_ERR_PYTHON_EXCEPTION;
1879         }
1880
1881         Py_DECREF(py_result);
1882
1883         return LDB_SUCCESS;
1884 }
1885
1886 static int py_module_request(struct ldb_module *mod, struct ldb_request *req)
1887 {
1888         PyObject *py_ldb = (PyObject *)mod->private_data;
1889         PyObject *py_result;
1890
1891         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "request"),
1892                                         discard_const_p(char, ""));
1893
1894         return LDB_ERR_OPERATIONS_ERROR;
1895 }
1896
1897 static int py_module_extended(struct ldb_module *mod, struct ldb_request *req)
1898 {
1899         PyObject *py_ldb = (PyObject *)mod->private_data;
1900         PyObject *py_result;
1901
1902         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "extended"),
1903                                         discard_const_p(char, ""));
1904
1905         return LDB_ERR_OPERATIONS_ERROR;
1906 }
1907
1908 static int py_module_start_transaction(struct ldb_module *mod)
1909 {
1910         PyObject *py_ldb = (PyObject *)mod->private_data;
1911         PyObject *py_result;
1912
1913         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "start_transaction"),
1914                                         discard_const_p(char, ""));
1915
1916         if (py_result == NULL) {
1917                 return LDB_ERR_PYTHON_EXCEPTION;
1918         }
1919
1920         Py_DECREF(py_result);
1921
1922         return LDB_SUCCESS;
1923 }
1924
1925 static int py_module_end_transaction(struct ldb_module *mod)
1926 {
1927         PyObject *py_ldb = (PyObject *)mod->private_data;
1928         PyObject *py_result;
1929
1930         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "end_transaction"),
1931                                         discard_const_p(char, ""));
1932
1933         if (py_result == NULL) {
1934                 return LDB_ERR_PYTHON_EXCEPTION;
1935         }
1936
1937         Py_DECREF(py_result);
1938
1939         return LDB_SUCCESS;
1940 }
1941
1942 static int py_module_del_transaction(struct ldb_module *mod)
1943 {
1944         PyObject *py_ldb = (PyObject *)mod->private_data;
1945         PyObject *py_result;
1946
1947         py_result = PyObject_CallMethod(py_ldb, discard_const_p(char, "del_transaction"),
1948                                         discard_const_p(char, ""));
1949
1950         if (py_result == NULL) {
1951                 return LDB_ERR_PYTHON_EXCEPTION;
1952         }
1953
1954         Py_DECREF(py_result);
1955
1956         return LDB_SUCCESS;
1957 }
1958
1959 static int py_module_destructor(struct ldb_module *mod)
1960 {
1961         Py_DECREF((PyObject *)mod->private_data);
1962         return 0;
1963 }
1964
1965 static int py_module_init(struct ldb_module *mod)
1966 {
1967         PyObject *py_class = (PyObject *)mod->ops->private_data;
1968         PyObject *py_result, *py_next, *py_ldb;
1969
1970         py_ldb = PyLdb_FromLdbContext(mod->ldb);
1971
1972         if (py_ldb == NULL)
1973                 return LDB_ERR_OPERATIONS_ERROR;
1974
1975         py_next = PyLdbModule_FromModule(mod->next);
1976
1977         if (py_next == NULL)
1978                 return LDB_ERR_OPERATIONS_ERROR;
1979
1980         py_result = PyObject_CallFunction(py_class, discard_const_p(char, "OO"),
1981                                           py_ldb, py_next);
1982
1983         if (py_result == NULL) {
1984                 return LDB_ERR_PYTHON_EXCEPTION;
1985         }
1986
1987         mod->private_data = py_result;
1988
1989         talloc_set_destructor(mod, py_module_destructor);
1990
1991         return ldb_next_init(mod);
1992 }
1993
1994 static PyObject *py_register_module(PyObject *module, PyObject *args)
1995 {
1996         int ret;
1997         struct ldb_module_ops *ops;
1998         PyObject *input;
1999
2000         if (!PyArg_ParseTuple(args, "O", &input))
2001                 return NULL;
2002
2003         ops = talloc_zero(talloc_autofree_context(), struct ldb_module_ops);
2004         if (ops == NULL) {
2005                 PyErr_NoMemory();
2006                 return NULL;
2007         }
2008
2009         ops->name = talloc_strdup(ops, PyString_AsString(PyObject_GetAttrString(input, discard_const_p(char, "name"))));
2010
2011         Py_INCREF(input);
2012         ops->private_data = input;
2013         ops->init_context = py_module_init;
2014         ops->search = py_module_search;
2015         ops->add = py_module_add;
2016         ops->modify = py_module_modify;
2017         ops->del = py_module_del;
2018         ops->rename = py_module_rename;
2019         ops->request = py_module_request;
2020         ops->extended = py_module_extended;
2021         ops->start_transaction = py_module_start_transaction;
2022         ops->end_transaction = py_module_end_transaction;
2023         ops->del_transaction = py_module_del_transaction;
2024
2025         ret = ldb_register_module(ops);
2026
2027         PyErr_LDB_ERROR_IS_ERR_RAISE(ret, NULL);
2028
2029         Py_RETURN_NONE;
2030 }
2031
2032 static PyObject *py_timestring(PyObject *module, PyObject *args)
2033 {
2034         time_t t;
2035         char *tresult;
2036         PyObject *ret;
2037         if (!PyArg_ParseTuple(args, "L", &t))
2038                 return NULL;
2039         tresult = ldb_timestring(NULL, t);
2040         ret = PyString_FromString(tresult);
2041         talloc_free(tresult);
2042         return ret;
2043 }
2044
2045 static PyObject *py_string_to_time(PyObject *module, PyObject *args)
2046 {
2047         char *str;
2048         if (!PyArg_ParseTuple(args, "s", &str))
2049                 return NULL;
2050
2051         return PyInt_FromLong(ldb_string_to_time(str));
2052 }
2053
2054 static PyObject *py_valid_attr_name(PyObject *self, PyObject *args)
2055 {
2056         char *name;
2057         if (!PyArg_ParseTuple(args, "s", &name))
2058                 return NULL;
2059         return PyBool_FromLong(ldb_valid_attr_name(name));
2060 }
2061
2062 static PyMethodDef py_ldb_global_methods[] = {
2063         { "register_module", py_register_module, METH_VARARGS, 
2064                 "S.register_module(module) -> None\n"
2065                 "Register a LDB module."},
2066         { "timestring", py_timestring, METH_VARARGS, 
2067                 "S.timestring(int) -> string\n"
2068                 "Generate a LDAP time string from a UNIX timestamp" },
2069         { "string_to_time", py_string_to_time, METH_VARARGS,
2070                 "S.string_to_time(string) -> int\n"
2071                 "Parse a LDAP time string into a UNIX timestamp." },
2072         { "valid_attr_name", py_valid_attr_name, METH_VARARGS,
2073                 "S.valid_attr_name(name) -> bool\n"
2074                 "Check whether the supplied name is a valid attribute name." },
2075         { "open", (PyCFunction)py_ldb_new, METH_VARARGS|METH_KEYWORDS,
2076                 NULL },
2077         { NULL }
2078 };
2079
2080 void initldb(void)
2081 {
2082         PyObject *m;
2083
2084         if (PyType_Ready(&PyLdbDn) < 0)
2085                 return;
2086
2087         if (PyType_Ready(&PyLdbMessage) < 0)
2088                 return;
2089
2090         if (PyType_Ready(&PyLdbMessageElement) < 0)
2091                 return;
2092
2093         if (PyType_Ready(&PyLdb) < 0)
2094                 return;
2095
2096         if (PyType_Ready(&PyLdbModule) < 0)
2097                 return;
2098
2099         if (PyType_Ready(&PyLdbTree) < 0)
2100                 return;
2101
2102         m = Py_InitModule3("ldb", py_ldb_global_methods, 
2103                 "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server.");
2104         if (m == NULL)
2105                 return;
2106
2107         PyModule_AddObject(m, "SCOPE_DEFAULT", PyInt_FromLong(LDB_SCOPE_DEFAULT));
2108         PyModule_AddObject(m, "SCOPE_BASE", PyInt_FromLong(LDB_SCOPE_BASE));
2109         PyModule_AddObject(m, "SCOPE_ONELEVEL", PyInt_FromLong(LDB_SCOPE_ONELEVEL));
2110         PyModule_AddObject(m, "SCOPE_SUBTREE", PyInt_FromLong(LDB_SCOPE_SUBTREE));
2111
2112         PyModule_AddObject(m, "CHANGETYPE_NONE", PyInt_FromLong(LDB_CHANGETYPE_NONE));
2113         PyModule_AddObject(m, "CHANGETYPE_ADD", PyInt_FromLong(LDB_CHANGETYPE_ADD));
2114         PyModule_AddObject(m, "CHANGETYPE_DELETE", PyInt_FromLong(LDB_CHANGETYPE_DELETE));
2115         PyModule_AddObject(m, "CHANGETYPE_MODIFY", PyInt_FromLong(LDB_CHANGETYPE_MODIFY));
2116
2117         PyModule_AddObject(m, "SUCCESS", PyInt_FromLong(LDB_SUCCESS));
2118         PyModule_AddObject(m, "ERR_OPERATIONS_ERROR", PyInt_FromLong(LDB_ERR_OPERATIONS_ERROR));
2119         PyModule_AddObject(m, "ERR_PROTOCOL_ERROR", PyInt_FromLong(LDB_ERR_PROTOCOL_ERROR));
2120         PyModule_AddObject(m, "ERR_TIME_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_TIME_LIMIT_EXCEEDED));
2121         PyModule_AddObject(m, "ERR_SIZE_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_SIZE_LIMIT_EXCEEDED));
2122         PyModule_AddObject(m, "ERR_COMPARE_FALSE", PyInt_FromLong(LDB_ERR_COMPARE_FALSE));
2123         PyModule_AddObject(m, "ERR_COMPARE_TRUE", PyInt_FromLong(LDB_ERR_COMPARE_TRUE));
2124         PyModule_AddObject(m, "ERR_AUTH_METHOD_NOT_SUPPORTED", PyInt_FromLong(LDB_ERR_AUTH_METHOD_NOT_SUPPORTED));
2125         PyModule_AddObject(m, "ERR_STRONG_AUTH_REQUIRED", PyInt_FromLong(LDB_ERR_STRONG_AUTH_REQUIRED));
2126         PyModule_AddObject(m, "ERR_REFERRAL", PyInt_FromLong(LDB_ERR_REFERRAL));
2127         PyModule_AddObject(m, "ERR_ADMIN_LIMIT_EXCEEDED", PyInt_FromLong(LDB_ERR_ADMIN_LIMIT_EXCEEDED));
2128         PyModule_AddObject(m, "ERR_UNSUPPORTED_CRITICAL_EXTENSION", PyInt_FromLong(LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION));
2129         PyModule_AddObject(m, "ERR_CONFIDENTIALITY_REQUIRED", PyInt_FromLong(LDB_ERR_CONFIDENTIALITY_REQUIRED));
2130         PyModule_AddObject(m, "ERR_SASL_BIND_IN_PROGRESS", PyInt_FromLong(LDB_ERR_SASL_BIND_IN_PROGRESS));
2131         PyModule_AddObject(m, "ERR_NO_SUCH_ATTRIBUTE", PyInt_FromLong(LDB_ERR_NO_SUCH_ATTRIBUTE));
2132         PyModule_AddObject(m, "ERR_UNDEFINED_ATTRIBUTE_TYPE", PyInt_FromLong(LDB_ERR_UNDEFINED_ATTRIBUTE_TYPE));
2133         PyModule_AddObject(m, "ERR_INAPPROPRIATE_MATCHING", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_MATCHING));
2134         PyModule_AddObject(m, "ERR_CONSTRAINT_VIOLATION", PyInt_FromLong(LDB_ERR_CONSTRAINT_VIOLATION));
2135         PyModule_AddObject(m, "ERR_ATTRIBUTE_OR_VALUE_EXISTS", PyInt_FromLong(LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS));
2136         PyModule_AddObject(m, "ERR_INVALID_ATTRIBUTE_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_ATTRIBUTE_SYNTAX));
2137         PyModule_AddObject(m, "ERR_NO_SUCH_OBJECT", PyInt_FromLong(LDB_ERR_NO_SUCH_OBJECT));
2138         PyModule_AddObject(m, "ERR_ALIAS_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_PROBLEM));
2139         PyModule_AddObject(m, "ERR_INVALID_DN_SYNTAX", PyInt_FromLong(LDB_ERR_INVALID_DN_SYNTAX));
2140         PyModule_AddObject(m, "ERR_ALIAS_DEREFERINCING_PROBLEM", PyInt_FromLong(LDB_ERR_ALIAS_DEREFERENCING_PROBLEM));
2141         PyModule_AddObject(m, "ERR_INAPPROPRIATE_AUTHENTICATION", PyInt_FromLong(LDB_ERR_INAPPROPRIATE_AUTHENTICATION));
2142         PyModule_AddObject(m, "ERR_INVALID_CREDENTIALS", PyInt_FromLong(LDB_ERR_INVALID_CREDENTIALS));
2143         PyModule_AddObject(m, "ERR_INSUFFICIENT_ACCESS_RIGHTS", PyInt_FromLong(LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS));
2144         PyModule_AddObject(m, "ERR_BUSY", PyInt_FromLong(LDB_ERR_BUSY));
2145         PyModule_AddObject(m, "ERR_UNAVAILABLE", PyInt_FromLong(LDB_ERR_UNAVAILABLE));
2146         PyModule_AddObject(m, "ERR_UNWILLING_TO_PERFORM", PyInt_FromLong(LDB_ERR_UNWILLING_TO_PERFORM));
2147         PyModule_AddObject(m, "ERR_LOOP_DETECT", PyInt_FromLong(LDB_ERR_LOOP_DETECT));
2148         PyModule_AddObject(m, "ERR_NAMING_VIOLATION", PyInt_FromLong(LDB_ERR_NAMING_VIOLATION));
2149         PyModule_AddObject(m, "ERR_OBJECT_CLASS_VIOLATION", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_VIOLATION));
2150         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_NON_LEAF", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_NON_LEAF));
2151         PyModule_AddObject(m, "ERR_NOT_ALLOWED_ON_RDN", PyInt_FromLong(LDB_ERR_NOT_ALLOWED_ON_RDN));
2152         PyModule_AddObject(m, "ERR_ENTRY_ALREADY_EXISTS", PyInt_FromLong(LDB_ERR_ENTRY_ALREADY_EXISTS));
2153         PyModule_AddObject(m, "ERR_OBJECT_CLASS_MODS_PROHIBITED", PyInt_FromLong(LDB_ERR_OBJECT_CLASS_MODS_PROHIBITED));
2154         PyModule_AddObject(m, "ERR_AFFECTS_MULTIPLE_DSAS", PyInt_FromLong(LDB_ERR_AFFECTS_MULTIPLE_DSAS));
2155
2156         PyModule_AddObject(m, "ERR_OTHER", PyInt_FromLong(LDB_ERR_OTHER));
2157
2158         PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText"));
2159
2160         PyExc_LdbError = PyErr_NewException(discard_const_p(char, "_ldb.LdbError"), NULL, NULL);
2161         PyModule_AddObject(m, "LdbError", PyExc_LdbError);
2162
2163         Py_INCREF(&PyLdb);
2164         Py_INCREF(&PyLdbDn);
2165         Py_INCREF(&PyLdbModule);
2166         Py_INCREF(&PyLdbMessage);
2167         Py_INCREF(&PyLdbMessageElement);
2168         Py_INCREF(&PyLdbTree);
2169
2170         PyModule_AddObject(m, "Ldb", (PyObject *)&PyLdb);
2171         PyModule_AddObject(m, "Dn", (PyObject *)&PyLdbDn);
2172         PyModule_AddObject(m, "Message", (PyObject *)&PyLdbMessage);
2173         PyModule_AddObject(m, "MessageElement", (PyObject *)&PyLdbMessageElement);
2174         PyModule_AddObject(m, "Module", (PyObject *)&PyLdbModule);
2175         PyModule_AddObject(m, "Tree", (PyObject *)&PyLdbTree);
2176 }